【问题标题】:Manipulate an HTML table (for column reordering, visibility) using jQuery/JavaScript?使用 jQuery/JavaScript 操作 HTML 表(用于列重新排序、可见性)?
【发布时间】:2015-05-21 14:07:37
【问题描述】:

我有一个 ASP.NET MVC 站点,并且在视图中有一个 HTML 表。根据示例 html 代码,我有时会在单元格内嵌套表格,但在您完成问题之前可以忽略它。

<table id="mainTable">
      <thead>
      <tr>
        <th>Col 1</th>
        <th>Col 2</th>
        <th>Col 3</th>
      </tr>
      </thead>
      <tbody>
      <tr>
          <td>data</td>
          <td>data</td>
          <td>data</td>
      </tr>
      <tr>
          <td>data</td>
          <td>
               <table class="nestedTable">
                   <tr><th>Col 1</th><th>Col 3</th></tr>
                   <tr>
                       <td>nested data</td><td>nested data 1</td>
                    </tr>
               </table>
          </td>
          <td>data</td>
      </tr>
    </tbody>
</table>

我现在想使用这个jQuery multiselect plugin 来允许用户选择他们想要的列的顺序以及显示/隐藏某些列所以我正在创建一个看起来像这样的多选:

<select id="cols" class="multiselect" multiple="multiple" name="cols[]">
    <option value="Col1">Col1</option>
    <option value="Col2">Col2</option>
    <option value="Col3">Col3</option>
</select>

允许用户选择订单,然后我暂时将这些数据存储在本地存储中。所以我要存储的只是一个字符串数组,它们代表“列的可见顺序”,用于设置多选选择器。这很好用,我可以保留这个数组或“有序列名”。

我的问题是获取此字符串数组并更新 HTML 表以反映此列排序和列可见性的最佳方法是什么?

我知道有更大的 html 表格网格框架具有此功能,但在这种情况下,我需要坚持使用手工编码的 html 表格。

更新:

@Rick Hitchcock 下面的回答让我完成了 90% 的工作,但我意识到有一个未解决的问题使我的问题有点复杂。在某些情况下,我在主表中有一个嵌套表。我已经更新了问题以包括这种情况。 我不希望列选择器代码影响嵌套表,所以我正在寻找一种方法让代码影响主表。

【问题讨论】:

标签: javascript jquery html html-table multi-select


【解决方案1】:

[根据更新的问题删除原始答案]

给定一个这样的数组 (arr):

['Col 2', 'Col 3', 'Col 1']

……或者这个:

['Col 1', 'Col 3']

...这将对主表的列进行排序以匹配,并将隐藏未使用的列:

var tr= $('#mainTable > tbody > tr, #mainTable > thead > tr');

$('> th, > td', tr).hide();

$.each(arr, function(_, val) {
  var col=  $('> th', tr)
              .filter(function() {
                return $(this).text()===val;
              })
              .index();

  $(tr).append(function() {
    return $('> td, > th', this).eq(col).show();
  });
});

Fiddle

单击一个按钮以重新排列表格。


工作原理

这会将后续选择器限制在主表的行中:

var tr= $('#mainTable > tbody > tr, #mainTable > thead > tr');

即使您排除了tbodyit will be added for you。因此,这始终是一个空集合:$('#mainTable &gt; tr')


这仅隐藏了 tr 集合的直接子代(来自上一行):
$('> th, > td', tr).hide();

作为副作用,所有后代也将被隐藏。

相当于:

$(tr).children('th, td').hide();

jQuery 的 childrenfind 方法通常是不必要的(而且成本很高),当您可以使用 CSS 选择器完成相同的事情时——尤其是考虑到可选的 context 参数的优势:

$( selector [, context ] )

这会查看数组的每个元素:

$.each(arr, function(_, val) {
  ...
});


这将获取 th 元素(即 tr 集合的直接子元素)的 index(),其中其 text() 与数组值匹配:
var col=  $('> th', tr)
              .filter(function() {
                return $(this).text()===val;
              })
              .index();

这就是我们要显示的列。


最后,这会将具有该列号的所有子元素附加到 tr 集合的每个成员,并显示它们:

$(tr).append(function() {
  return $('> td, > th', this).eq(col).show();
});

jQuery 的 append() 方法(类似于 JavaScript 的 appendChild() 方法)移动一个元素 - 进入 DOM 或 DOM 中的其他位置。

知道了这一点,我们通常可以避免使用detach()等方法。


【讨论】:

  • 这很好用,除了一个问题。在一个列中,我有一个嵌套表,上面的代码似乎弄乱了那个嵌套表。有没有办法避免上述影响我主表中的嵌套表?
  • 感谢您的更新,但我的示例似乎不适用于您的代码。我认为这是因为我的 TH 周围有一个 thead 部分(看着你的小提琴,看起来你没有那个)所以当这条线运行时:$('> th,> td',tr)。 hide(),我的 TH 标题行没有隐藏,因为它们不在 tbody 内 .. 有什么建议吗?
  • 您的示例 HTML 没有 thead 部分,但我已经更新了我的第二个小提琴以考虑到这一点。这样做:var tr= $('#mainTable &gt; tbody &gt; tr, #mainTable &gt; thead &gt; tr');
  • 谢谢瑞克。 .我已经更新了这个问题,因为我意识到我把这个问题排除在外了.. 我会给你最新的更新一个镜头
猜你喜欢
  • 2017-04-16
  • 1970-01-01
  • 2010-11-05
  • 2010-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-22
相关资源
最近更新 更多