【问题标题】:Expanding and collapsing table row (tr) using jquery使用jquery展开和折叠表格行(tr)
【发布时间】:2014-11-24 07:29:33
【问题描述】:

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

<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

我该怎么做..?

【问题讨论】:

  • 只是检查您是否考虑过更简单(而且有点愚蠢)的解决方案。是否可以选择将它们作为两个单独的网格处理?两人独立工作?这样,您的切换功能将减少为隐藏和显示类型的操作。活动网格将始终保持可见,您可以分别隐藏和显示非活动网格。您只需要确保应用样式,以便两个网格的列宽保持相同。如果这个解决方案过于简单,我们深表歉意。

标签: html jquery html-table click slidetoggle


【解决方案1】:

这里是切换“非活动”表行的代码。依赖 "closest()" 比依赖 "parent()" 或 "parents()" 更好,因为它更快,而且在这种情况下使用它更有意义。

$(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;
  });

});
<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>

【讨论】:

  • 是否有机会默认隐藏非活动项目并切换它们?
  • 给你 :) 我编辑了上面的代码。如果您认为此答案解决了您的问题,请将其标记为有效。
  • 非常感谢,但根据我的问题图表,InActive 项目被分隔为一个块。我还尝试将 InActive 项目分组为单独的块并切换它们。
  • 最好使用服务器端脚本语言(PHP、ASP.NET 等)来实现。您将对数组进行正确排序,然后循环遍历数组。我用新问题的解决方案编辑了 JavaScript 代码,但最好使用服务器端语言。
【解决方案2】:

首先,Jquery 无法正确处理表格元素的高度动画,因此我们将在 &lt;td&gt; 中注入 &lt;div&gt; 以进行动画处理,如 answer 中所述。

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

  • 我们将使用has() 方法找到不活动的行,使用wrapAll() 将它们包装在&lt;tfoot&gt; 中并将其插入到&lt;tbody&gt; 之前, 我们使用insertBefore()

    我正在使用insertBefore(),因为由于answer 中提到的优势,这是更好的做法。我们也可以使用insertAfter(),因为在&lt;tbody&gt; 之后包含&lt;tfoot&gt; 在语义上是可以的,

  • 然后我们将find&lt;td&gt; 放在其中,并使用wrapInner() 方法将其内容包装在隐藏的&lt;div&gt; 中。

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

  • 然后,我们添加了用于切换 beforefirst 非活动行的选项。

  • on 点击切换选项,我们使用closest() 访问它的父&lt;tr&gt;,然后使用nextAll() 来定位以下所有&lt;tr&gt; - 它们是非活动的。然后我们找到注入其中的&lt;div,并调用slideToggle() 来获得切换功能。

    根据当前标记,我们也可以使用parent() 来访问父级&lt;tr&gt;。我正在使用最接近的,因此如果您将事件处理程序绑定到 &lt;td&gt; 内的元素 - 例如按钮,它将起作用。

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

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

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

除了这些,

  • 我已将标题列包裹在 &lt;thead&gt; 中,这样更 语义上合适。
  • 我为&lt;td&gt; 设置了一个最小宽度,以避免在切换所有Inactive 项目的可见性时由于State 列的宽度变化而出现“混蛋”
  • 为了演示,我删除了空的 &lt;td&gt; 并添加了一些 CSS

我们最终得到以下 语义上很酷的结构,它是可折叠

 <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>

$('.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);
});
*{
  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;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="alertsList">
    <table width="100%">
        <thead>
          <tr>
                <th>Id</th>
                <th>From</th>
                <th>Action</th>
                <th>State</th>
                <th>time</th>
            </tr>
        </thead>
        <tbody>
            <tr class="alertRow">
                <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>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>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>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>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>

【讨论】:

  • Wissam 解决方案是我正在寻找的,但是您的代码很棒,而且您解释的方式非常有用。我不知道如何为您的答案添加奖励积分,但必须在 Wissam 中添加打勾以提供我需要的解决方案。
  • @Chandana 您可以在每个答案旁边的选票下方看到加分编号,单击它会给该答案加分... :) 顺便说一句,如果您不手动操作,赏金到期时,接受的答案将获得奖励积分..
  • ++ 特殊答案!
【解决方案3】:

您的选择器有几个问题:

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

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

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

【讨论】:

  • 切换有点困难,因为项目在点击时被隐藏。您能否帮我提供一些提示,如何制作活动和非活动 2 块并切换非活动项目。
【解决方案4】:

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

Here 是一个使用按钮切换所有“InActive”行的示例。

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);
});

【讨论】:

    【解决方案5】:

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

    如果不可能,那么您可能可以使用下面的代码对它们进行排序(仅供参考,这仅适用于那些已经存在于 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);
    });
    

    希望这会有所帮助:)

    【讨论】:

      【解决方案6】:

      作为T J said in his answer,对表格行的高度进行动画处理很复杂(请参阅this answerthis answer 了解有关它的技巧,其中涉及将每个单元格的内容包装在&lt;div&gt; 中)。

      您可以完全跳过动画,并简单地隐藏或显示不活动的行:

      $('#btnToggle').click(function() {
          $('td.InActive').closest('tr').toggle();
      });
      

      如果您想要一些视觉糖果向用户发出隐藏信号,我建议使用.fadeToggle(),它会立即起作用:

      $('#btnToggle').click(function() {
          $('td.InActive').closest('tr').fadeToggle(1000);
      });
      

      fiddle


      作为额外说明:如果您可以修改生成表的代码(例如:PHP 或 ruby​​(或 wathever)代码),请尝试将 active / inactive 类放在 &lt;tr&gt; 节点)而不是内部单元格(&lt;td&gt; 节点):

      <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>
      

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

      //css
      tr.inactive {font-style: italic; background-color: #eee}
      
      //js
      $('tr.inactive').fadeToggle(1000);
      

      【讨论】:

        【解决方案7】:

        我使用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 元素来显示/隐藏非活动行。

        【讨论】:

          猜你喜欢
          • 2011-09-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-31
          • 1970-01-01
          • 2011-09-18
          • 1970-01-01
          • 2020-02-22
          • 1970-01-01
          相关资源
          最近更新 更多