jQuery expand/collapse hierarchical table row

前端 未结 3 792
不知归路
不知归路 2021-02-09 23:14

I am looking for an efficient way to expand/collapse hierarchical table rows using jQuery. The problem is, that the expand and collapse functionality differs.

  • Init
3条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-09 23:39

    I think you're gonna need a little some more code so you can handle clicks on all the rows in both closed and open states.

    I added a class switch to indicate when a row is open, and treat clicks differently based on it's state. Both collapse and expand have while loops that walk through rows, starting with the one immediately after the clicked row, and they stop when they get to rows of the same level. This logic should work for any level, not just 0. Also, the while loop could probably be cleaner using nextUntil logic with a fancy selector - I wasn't familiar with that jQuery method until seeing Jules answer - very slick!

    ALso, for keeping this example code simpler, I treated your level class naming system as HTML data attributes, so a given row looks like this: . You could replace calls to .data with code to parse your class names.

    var $rows = $('#mytable tr');
    
    $rows.live('click', function() {
    $(this).toggleClass('open');
    
    if ($this.hasClass('open')){
        collapse($(this));
    } else {
        expand($this);
    }
    }
    
    function collapse ($row) {
        $row.removeClass('open');
    var rowIndex = $rows.index($row);
    var siblingOrAncestorRowFound = false;
    
    while (!siblingOrAncestorRowFound){
        var $nextRow = $rows.eq(rowIndex + 1);
        if ($nextRow.level  > $row.level){
            $nextRow.hide().removeClass('open');
            rowIndex++;
        } else {
            siblingOrAncestorRowFound = true;
        }
    }
    }
    
    function expand ($row) {
        $row.addClass('open')
    var rowIndex = $rows.index($row);
    var siblingOrAncestorRowFound = false;
    
    while (!siblingOrAncestorRowFound){
        var $nextRow = $rows.eq(rowIndex + 1);
        if ($nextRow.level  > $row.level){
    
            // only show rows exactly one level below
            if ($nextRow.level == $row.level + 1){
                $nextRow.show();
            }
    
            rowIndex++;
        } else {
            siblingOrAncestorRowFound = true;
        }
    }
    }
    

    (This isn't tested - sorry gotta hit the sack!)

提交回复
热议问题