使用jquery扩展和折叠表行(tr)

时间:2014-09-29 19:54:41

标签: jquery html-table click slidetoggle

enter image description here

我有一张包含有效和无效项目的表格。此表是从数据库动态填充的。我正在尝试为我的表中的非活动项添加切换并显示所有活动项。我的意思是我想要显示所有活动项目并在我的表格中仅滑动切换非活动项目。

<div class="alertsList">
    <table width="100%">
        <tbody>
            <tr>
                <th></th>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
                <tr class="alertRow">
                    <td></td>
                    <td>1025973</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
        </tbody>
    </table>
</div>

$('.alertRow.InActive').Parent.click(function () {

    $(this).nextUntil('tr.td.InActive').slideToggle(1000);
});

My Fiddle code

我该怎么做..?

7 个答案:

答案 0 :(得分:6)

这里是用于切换表格行的代码,这些表格是&#34;非活动&#34;。最好依靠&#34;最近()&#34;比父母()&#34;或者&#34; parent()&#34;,因为它更快,在这种情况下使用它更有意义。

&#13;
&#13;
$(document).ready(function() {

  // Save all the inactive rows
  var inactive_rows = '';
  $('.InActive').closest("tr").each(function() {
    inactive_rows += '<tr class="alertRow">';
    inactive_rows += $(this).html();
    inactive_rows += '</tr>';
  });
  console.log(inactive_rows);
  // Save all the active rows
  var active_rows = "";
  $('.Active').closest("tr").each(function() {
    active_rows += '<tr class="alertRow">';
    active_rows += $(this).html();
    active_rows += '</tr>';
  });
  // Empty the table
  $('.alertsList').html("");
  // Load the new table
  var table_html = '<table width="100%"><thead><th></th><th>Id</th><th>From</th><th>Action</th><th>State</th><th>time</th></thead><tbody>';
  table_html += active_rows;
  table_html += inactive_rows;
  table_html += '</tbody></table><a href="" class="toggleInactiveRows">Toggle Inactive Rows</a>';
  $('.alertsList').append(table_html);

  // Hide the inactive rows when the page loads
  $('.InActive').closest("tr").hide();

  // Toggle the inactive rows
  $('.toggleInactiveRows').click(function() {
    $('.InActive').closest("tr").slideToggle();
    return false;
  });

});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alertsList">
  <table width="100%">
    <thead>
      <th></th>
      <th>Id</th>
      <th>From</th>
      <th>Action</th>
      <th>State</th>
      <th>time</th>
    </thead>
    <tbody>
      <tr class="alertRow">
        <td></td>
        <td>1025973</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="Active">Active</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="Active">Active</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="InActive">InActive</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="InActive">InActive</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
      <tr class="alertRow">
        <td></td>
        <td>1025974</td>
        <td>SYSTEM</td>
        <td>false</td>
        <td class="Active">Active</td>
        <td>2014-09-23T00:59:26.92</td>
      </tr>
    </tbody>
  </table>
  <a href="" class="toggleInactiveRows">Toggle Inactive Rows</a>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:5)

首先,Jquery没有正确处理表格元素的高度动画,因此我们会在<div>内注入<td>个要动画,如answer中所述。

其次,由于您想要将非活动项目作为一个组进行切换,我们应该将它们组合在一起。

  • 我们会使用has()方法查找非活动行,使用wrapAll()将其打包在<tfoot>中并将其插入<tbody>之前, 我们使用insertBefore()

    我使用insertBefore()因为这是answer中提到的优势所以这是更好的做法。我们也可以使用insertAfter(),因为在<tfoot>

  • 之后包含<tbody>在语义上是可以的。
  • 然后我们find<td>个内容,并使用wrapInner()方法将其内容封装在隐藏的<div>中。

    您可以通过在服务器端相应地填充表来避免此步骤

  • 然后我们添加了切换before first非活动行的选项。

  • on点击切换选项,我们使用closest()访问其父级<tr>,然后使用nextAll()来定位以下所有内容{ {1}} - 不活跃。然后,我们会找到我们注入其中的<tr>,并为切换功能调用slideToggle()

    我们也可以使用parent()根据当前标记访问父<div。如果您将事件处理程序绑定到<tr>内的元素(例如,按钮),我使用最接近的以便它可以工作。功能

    我们也可以使用siblings()来访问以下<td>,因为我们将活动和非活动行分隔到不同的容器中。

    请注意,我们需要delegate the event handler使用on() 我们动态地注入了切换选项。

  • 最后我们使用CSS伪元素::before来显示 基于类的相应图标,当用户切换时 使用toggleClass()

  • 点击切换选项

除此之外,

  • 我已将<tr>内的标题栏包裹起来了 语义上合适。
  • 我为<thead>设置了最小宽度,以避免&#34; jerk&#34;由于在切换所有<td>项目的可见性时State列的宽度发生变化
  • 我已删除空Inactive并为演示添加了一些CSS

我们最终得到以下语义酷结构可折叠

<td>

&#13;
&#13;
 <table>
   <thead>
     <tr>
          <th> title</th>
     </tr>
   </thead>
   <tfoot>
    <tr>
      <td>Toggle Switch</td>
    </tr>
    <tr>
      <td><div> Collapsible content</div></td>
     </tr>
   </tfoot>
   <tbody>
     <tr>
          <td>body content</td>
     </tr>
   </tbody>
</table>
&#13;
$('.alertRow').has(".InActive")
// group them together in a tfoot and insert it before tbody
         .insertBefore(".alertsList table tbody").wrapAll("<tfoot></tfoot>")
// inject the hidden divs inside the columns for animating
         .find("td").wrapInner("<div style='display:none'/>").end()
// insert the toggle option before the first inactive row
         .first().before("<tr><td class='toggle' colspan='5'> Inactive Items</td></tr>");

$(".alertsList table").on("click", ".toggle", function () {
   // following class keeps track of the cuurrent state
   $(this).toggleClass("expanded")
   // find all the injected divs and toggle them
      .closest("tr").nextAll("tr").find('td  div').slideToggle(700);
});
&#13;
*{
  margin:0;
  padding:0;
}
th,td{
  min-width:80px;
  text-align:center;
}
.toggle{
  background:dodgerblue;
}
.toggle::before{
    content:"+"
}
.toggle.expanded::before{
    content:"-"
}
tfoot tr{
  background:#eee;
}
&#13;
&#13;
&#13;

答案 2 :(得分:4)

您的选择器出现了几个问题:

$('.alertRow .InActive').parent().click(function () {
    $(this).slideToggle(1000);
});

这应该按照您的预期方式工作。

不幸的是,就slideToggle的动画而言,表格往往具有受限制的风格。在这种情况下,由于tr元素的行高,slideToggle不会生成动画。您可以在CSS中手动设置tr line-heightheight属性,但这可能会在将来导致其他格式化问题。这是一个例子fiddle

答案 3 :(得分:4)

如上一篇文章所述,您需要设置line-height标记的heighttr样式属性才能使动画效果生效。

Here是一个切换所有&#39; InActive&#39;使用按钮的行。

CSS:

tr {
    height: 15px;
    line-height: 0px;
}

HTML:

<div class="alertsList">
<table width="100%">
    <tbody>
        <th></th>
        <th>Id</th>
        <th>From</th>
        <th>Action</th>
        <th>State</th>
        <th>time</th>
        <tr class="alertRow">
            <td></td>
            <td>1025973</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="Active">Active</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="Active">Active</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="InActive">InActive</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="InActive">InActive</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
        <tr class="alertRow">
            <td></td>
            <td>1025974</td>
            <td>SYSTEM</td>
            <td>false</td>
            <td class="Active">Active</td>
            <td>2014-09-23T00:59:26.92</td>
        </tr>
    </tbody>
</table>
<input id="btnShowHide" type="button" value="Show/hide" />

JS:

 $('#btnShowHide').click(function () {
    $('.InActive').parent('tr').slideToggle(1000);
});

答案 4 :(得分:3)

对此的一个简单解决方案是,以一种方式绑定数据,使活动的数据首先出现,然后是非活动的数据(使用相同的排序)。

如果不可能,那么你可以使用下面的代码对它们进行排序(仅供参考,这只适用于那些已经存在于DOM中且应该只运行一次的元素)

// a simple compare function, used by the sort below
var compare_rows = function(a, b) {
    var a_val = $(a).find('td.Active').text().toLowerCase();
    var b_val = $(b).find('td.InActive').text().toLowerCase();
    if (a_val > b_val) { return 1; }
    if (a_val < b_val) { return -1; }
    return 0;
};
// the actual sort
$('#tableID tr').sort(compare_rows).appendTo('#tableID');

然后添加用于折叠和扩展隐藏的图标

$("<tr class='toggle'><td colspan='5'>Show Hidden Icons</td></tr>").insertBefore($($(".alertsList table tr td.InActive")[0]).parent())

最后,添加点击,即使添加的动态图标如下,

$(".toggle").click(function(){
    $(this).nextAll().slideToggle(1000);
});

希望这会有所帮助:)

答案 5 :(得分:3)

作为T J said in his answer,为表格行的高度设置动画很复杂(请参阅this answerthis answer了解其周围的黑客,其中涉及将每个单元格的内容包装在{{1 }})。

您可以完全跳过动画,只需隐藏或显示不活动的行:

<div>

如果您想要一些视觉糖果来向用户发出隐藏信号,我建议您使用$('#btnToggle').click(function() { $('td.InActive').closest('tr').toggle(); }); 即可立即使用:

.fadeToggle()

fiddle


作为额外注释:如果您可以修改生成表的代码(例如:PHP或ruby(或wathever)代码),请尝试将$('#btnToggle').click(function() { $('td.InActive').closest('tr').fadeToggle(1000); }); 类放在active / inactive节点)而不是内部单元格(<tr>节点):

<td>

这将使您的css和js中的规则更容易:

<div class="alertsList">
    <table width="100%">
        <tbody>
            <tr>
                <th></th>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
            </tr>
            <tr class="alertRow active">
                ...
            </tr>
            <tr class="alertRow active">
                ...
            </tr>
            <tr class="alertRow inactive">
                ...
            </tr>
            <tr class="alertRow inactive">
                ...
            </tr>
            <tr class="alertRow active">
                ...
            </tr>
        </tbody>
    </table>
</div>

答案 6 :(得分:3)

我使用fadeToggle创建了这个:

$("table tr td.InActive").each(function(){
    $(this).parent().children(":not(:first-child)").hide();
});

$('a').click(function () {
    $(this).text() == "+" ? $(this).text("-") : $(this).text("+");
    $(this).parents("tr").children(":not(:first-child)").fadeToggle();
});
a{
    text-decoration: none;
}
a:hover{
    text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alertsList">
    <table width="100%">
        <tbody>
            <tr>
                <th></th>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
                <tr class="alertRow">
                    <td></td>
                    <td>1025973</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td><a href="#">+</a></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td><a href="#">+</a></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="InActive">InActive</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
                <tr class="alertRow">
                    <td></td>
                    <td>1025974</td>
                    <td>SYSTEM</td>
                    <td>false</td>
                    <td class="Active">Active</td>
                    <td>2014-09-23T00:59:26.92</td>
                </tr>
        </tbody>
    </table>
</div>

你可以看到我添加了一个+/- a元素来显示/隐藏非活动行。