使用jQuery/JavaScript操作HTML表(用于列重新排序,可见性)?

leo*_*ora 8 html javascript jquery html-table multi-select

我有一个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>
Run Code Online (Sandbox Code Playgroud)

我现在想要使用这个jQuery multiselect插件来允许用户选择他们想要的列的顺序以及显示/隐藏某些列所以我创建了一个如下所示的多选:

<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>
Run Code Online (Sandbox Code Playgroud)

允许用户选择订购,然后我暂时将这些数据存储在本地存储中.所以我存储的是一个字符串数组,表示"列的可见顺序",用于设置多选选择器.这工作正常,我能够持久化此数组或"有序列名称".

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

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

更新:

@Rick Hitchcock在下面的回答让我有90%的路在那里但是有一个未解决的问题让我觉得有点复杂了我的问题.在某些情况下,我在主表中有一个嵌套表.我已更新问题以包括这种情况. 我不希望列选择器代码影响嵌套表,所以我正在寻找一种方法让代码影响主表.

Ric*_*ock 6

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

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

['Col 2', 'Col 3', 'Col 1']
Run Code Online (Sandbox Code Playgroud)

… 或这个:

['Col 1', 'Col 3']
Run Code Online (Sandbox Code Playgroud)

...这将命令主表的列匹配,它将隐藏未使用的列:

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();
  });
});
Run Code Online (Sandbox Code Playgroud)

小提琴

单击按钮可对表重新排序.


这个怎么运作

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

var tr= $('#mainTable > tbody > tr, #mainTable > thead > tr');
Run Code Online (Sandbox Code Playgroud)

即使您排除tbody,也会为您添加.出于这个原因,这总是一个空集合: $('#mainTable > tr').


这只隐藏了tr集合的直接子节点(来自上一行):

$('> th, > td', tr).hide();
Run Code Online (Sandbox Code Playgroud)

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

它相当于:

$(tr).children('th, td').hide();
Run Code Online (Sandbox Code Playgroud)

当你可以使用CSS选择器完成相同的事情时,jQuery childrenfind方法通常是不必要的(并且代价高昂) - 特别是考虑到可选context参数的优点:

$( selector [, context ] )
Run Code Online (Sandbox Code Playgroud)

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

$.each(arr, function(_, val) {
  ...
});
Run Code Online (Sandbox Code Playgroud)


这得到了index()中的th元素(即是一个直接子tr集),其中,其text()匹配的数组值:

var col=  $('> th', tr)
              .filter(function() {
                return $(this).text()===val;
              })
              .index();
Run Code Online (Sandbox Code Playgroud)

这是我们想要展示的专栏.


最后,这会向tr集合中的每个成员追加具有该列号的所有子成员,并显示它们:

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

jQuery的append()方法(比如JavaScript的appendChild()方法)将元素移动到DOM或DOM中的其他位置.

知道了这一点,我们经常可以避免使用诸如此类的方法detach().