2014-11-22 99 views
1

我有一个表结构,所以一些分层数据: (实施例1)展开和在HTML表格的第3级层级行收起

A 
    A.1 
    A.1.1 
    A.1.2 
    A.2 
    A.2.1 
    A.2.2 
B 
    B.1 
    B.1.1 
    B.1.2 
    B.2 
    B.2.1 
    B.2.2 

我想能够扩大和内各塌陷水平,所以举例来说,如果我点击A.2,这是孩子应该崩溃(例如2)

A 
    A.1 
    A.1.1 
    A.1.2 
    A.2 
B 
    B.1 
    B.1.1 
    B.1.2 
    B.2 
    B.2.1 
    B.2.2 

如果我点击一个,所有的孩子都应该崩溃(例如3)

A 
B 
    B.1 
    B.1.1 
    B.1.2 
    B.2 
    B.2.1 
    B.2.2 

,如果我展开再次,A.2仍应保持折叠(隐藏子女)(例如4)

A 
    A.1 
    A.1.1 
    A.1.2 
    A.2 
B 
    B.1 
    B.1.1 
    B.1.2 
    B.2 
    B.2.1 
    B.2.2 

我从http://jsfiddle.net/y4Mdy/1124/试图代码样本 - 但不处理的三级层次结构。 $(this).nextUntil似乎很好地工作,但是当下一个tr是父行时,它将被折叠直到下一个子行。另外,如果我垮了2级,然后折叠父,第二层次是隐藏的,但第三级显示:

A 
    A.1.1 
    A.1.2  
B 
    B.1 
    B.1.1 
    B.1.2 
    B.2 
    B.2.1 
    B.2.2 

我也曾尝试http://jsfiddle.net/icc97/XNkbE/ - 不过分级别不回去折叠状态时,点击父级(类似于我上面的示例4)

任何人都可以帮忙吗?

在此先感谢。

回答

0

该解决方案应处理任何级别的数量。

我原来的jsfiddle是here。我会比这个答案更经常更新它。

$("tbody > tr:not([data-level='3'])").addClass("expandable sign folded"); 
 
$("tbody > tr:not([data-level='1'])").hide(); 
 
$("tbody > tr") 
 
    .css("padding-left", function (index) { 
 
    return 10 * parseInt($(this).data("level"), 10) + "px"; 
 
}); 
 

 
function range(lowEnd, highEnd) { 
 
    // assert lowEnd >= 0 and highEnd < 100 
 
    var validation = (lowEnd <= highEnd) && (lowEnd >= 0) && (highEnd < 100); 
 
    if (!(validation)) { 
 
     console.assert(validation, 
 
         'Function "range" received unlikely values: ' + 
 
         lowEnd + ' and ' + highEnd + "..."); 
 
    } else { 
 
     var arr = []; 
 
     while (lowEnd <= highEnd) { 
 
      arr.push(lowEnd++); 
 
     } 
 
     return arr; 
 
    } 
 
} 
 

 
function name_range(fun, lowEnd, highEnd) { 
 
    var arr = range(lowEnd, highEnd); 
 
    jQuery.each(arr, function (index, value) { 
 
     arr[index] = fun(value); 
 
    }); 
 
    return arr; 
 
} 
 

 
function create_selector(level) { 
 
    return "[data-level='" + level + "']"; 
 
} 
 

 
$("tr.expandable").click(function() { 
 
    var this_level = parseInt($(this).data("level"), 10); 
 
    var this_level_selector = create_selector(this_level); 
 
    var next_level_selector = create_selector(this_level + 1); 
 
    var next_or_lower = name_range(create_selector, 
 
    this_level + 1, 10); // TODO: find last level 
 
    var this_or_higher = name_range(create_selector, 0, this_level); 
 
    var node = $(this).prevUntil(this_or_higher.join(",")); 
 
    // different behaviour according to state (expanded/folded): 
 
    if ($(this).hasClass("expanded")) { 
 
     $(this).removeClass("expanded").addClass('folded'); 
 
     $(node).not("expanded").removeClass("expanded").addClass('folded'); 
 
     $(node).filter(next_or_lower.join(",")).hide(); 
 
    } else { 
 
     $(this).addClass("expanded").removeClass('folded'); 
 
     $(node).filter(next_level_selector).show(); 
 
    } 
 
});
table, tr, td, th { 
 
    border: 1px solid black; 
 
    border-collapse:collapse; 
 
    border-color: gray; 
 
} 
 
tr:not([data-level='3']) { 
 
    cursor:pointer; 
 
    font-weight: bold; 
 
} 
 
tr.expanded .sign:after { 
 
    content:"-"; 
 
} 
 
tr.folded .sign:after { 
 
    content:"+"; 
 
} 
 
td:first-child { 
 
    padding: inherit; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> 
 
<table border="0"> 
 
    <thead> 
 
     <tr> 
 
      <th colspan="4">Header</th> 
 
     </tr> 
 
    </thead> 
 
    <tbody> 
 
     <tr data-level='3'> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='3'> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='2'> 
 
      <td>sub stores<span class="sign"></span> 
 

 
      </td> 
 
      <td>total</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='1'> 
 
      <td>Trade<span class="sign"></span> 
 

 
      </td> 
 
      <td>total</td> 
 
      <td>total</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='3'> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='2'> 
 
      <td>sub stores<span class="sign"></span> 
 

 
      </td> 
 
      <td>total</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='3'> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='2'> 
 
      <td>sub stores<span class="sign"></span> 
 

 
      </td> 
 
      <td>total</td> 
 
      <td>data</td> 
 
      <td>data</td> 
 
     </tr> 
 
     <tr data-level='1'> 
 
      <td>Stores<span class="sign"></span> 
 

 
      </td> 
 
      <td>total</td> 
 
      <td>total</td> 
 
      <td>data</td> 
 
     </tr> 
 
    </tbody> 
 
</table>

0

既然你只处理嵌套table S,你可以用这一个:

CSS:

tbody.collapsed { 
    display: none; 
} 

JS:

$('thead').click(function(){ 

     $(this).siblings('tbody').toggleClass('collapsed'); 

    }); 

我使用theadtbody来利用语义。