使用jQuery / JavaScript操作HTML表(用于列重新排序,可见性)? [英] Manipulate an HTML table (for column reordering, visibility) using jQuery/JavaScript?

查看:103
本文介绍了使用jQuery / JavaScript操作HTML表(用于列重新排序,可见性)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 < table id =mainTable> 
< thead>
< tr>
Col 1< / th>
Col 2< / th>
Col 3< / th>
< / tr>
< / thead>
< tbody>
< tr>
< td>资料< / td>
< td>资料< / td>
< td>资料< / td>
< / tr>
< tr>
< td>资料< / td>
< td>
< table class =nestedTable>
< tr> Col 1< th> Col 3< / th>< / tr>
< tr>
< td>嵌套数据< / td>< td>嵌套数据1< / td>
< / tr>
< / table>
< / td>
< td>资料< / td>
< / tr>
< / tbody>
< / table>

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

 < select id =colsclass =multiselectmultiple =multiplename =cols []> 
< option value =Col1> Col1< / option>
< option value =Col2> Col2< / option>
< option value =Col3> Col3< / option>
< / select>

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

我的问题是什么是最好的方式来采取这个字符串数组和更新HTML表反映了这个列的排序和列可见性?



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



更新:



@Rick Hitchcock的答案让我有90%是我意识到的一个开放性问题使我的问题变得复杂一点。在某些情况下,我在主表中有一个嵌套表。我已经更新了这个问题以包含这种情况。 我不希望列选择器代码影响嵌套表,所以我正在寻找一种方法让代码影响主表。

解决方案

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



给定一个数组( 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(){
返回$(this).text()=== val;
})
.index();
$ b $(tr).append(function() {
return $('> td,> th',this).eq(col).show();
});
});

小提琴



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



工作原理



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

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

即使您排除 tbody 它会为你添加。因此,这总是一个空集合: $('#mainTable> tr')



这只隐藏 tr 集合(来自上一行)的直接子元素:

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

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



这相当于:

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

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

  $(selector [,context])






数组:

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



获得 index() th 元素(它是 tr 集合的直接子元素)的code>,其中 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()方法 appendChild()方法)移动元素–要么进入DOM,要么进入DOM中的其他地方。

知道了这一点,我们通常可以避免使用诸如 detach()





I have an ASP.NET MVC site and I have a HTML table in a view. As per the example html code I sometimes have nested tables inside of cells but that can be ignored until you get to the end of the question.

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

I now want to to use this jQuery multiselect plugin to allow the user to select the ordering of columns they want as well as show / hide certain columns So I am creating a multiselect that looks like this:

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

to allow the user to pick the ordering and then I am going to store this data in local storage for the time being. So all I am storing is an array of strings that represent the "visible order of columns" which is used to setup the multiselect picker. This works fine and I am able to persist this array or "ordered column names".

My question is what is the best way to take this string array and update the HTML table to reflect this column ordering and column visibility?

I know there are larger html table grid frameworks that have this feature but in this case I need to stick with a hand coded html table.

Update:

@Rick Hitchcock's answer below got me 90% of the way there but there is one open issue that I realize complicates my question a bit. In certain cases, I have a nested table inside the main table. I have updated the question to include this situation. I do NOT want the column chooser code to affect the nested table so I am looking for a way to just have the code affect the main table.

解决方案

[original answer removed based on updated question]

Given an array (arr) like this:

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

… or this:

['Col 1', 'Col 3']

… this will order the main table's columns to match, and it will hide unused columns:

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

Click a button to reorder the table.


How it works

This will limit subsequent selectors to the main table's rows:

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

Even if you exclude tbody, it will be added for you. For this reason, this is always an empty collection: $('#mainTable > tr').


This hides only direct children of the tr collection (from the previous line):

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

As a side effect, all descendants will also be hidden.

It's the equivalent of:

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

jQuery's children and find methods are often unnecessary (and costly), when you can accomplish the same thing using CSS selectors – especially given the advantages of the optional context parameter:

$( selector [, context ] )


This looks at each element of the array:

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


This gets the index() of the th element (that is a direct child of the tr collection), in which its text() matches the array value:

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

That is the column we want to show.


Finally, this appends to each member of the tr collection all of its children having that column number, and it shows them:

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

jQuery's append() method (like JavaScript's appendChild() method) move an element – either into the DOM or somewhere else within the DOM.

Knowing this, we can often avoid using methods such as detach().


这篇关于使用jQuery / JavaScript操作HTML表(用于列重新排序,可见性)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆