JavaScript / JQuery交换HTML表的水平和垂直顺序

时间:2014-09-05 08:27:23

标签: javascript jquery html

我有一个复杂的HTML表格,其水平和垂直标题看起来像这样。

Example of complex table

HTML代码很简单:

<table>
    <tr>
      <th>(empty)</th>
      <th>Heading 1</th>
      <th>Heading 2</th>
    </tr>
 <tr>
  <th>Heading A</th>
     <td>content for 1 and A</td>
     <td>content for 2 and A</td>
 </tr>
 <tr>
  <th>Heading B</th>
     <td>content for 1 and B</td>
     <td>content for 2 and B</td>
 </tr>
 <tr>
  <th>Heading C</th>
     <td>content for 1 and C</td>
     <td>content for 2 and C</td>
 </tr>
</table>

现在,我想让我的网站用户可以交换表格的内容。即:改变水平和垂直顺序,以便之后垂直标题是水平的,水平标题是垂直的,相应的是表格单元格。听起来很复杂,但你会看到图片来获得它:

complex table after swapping

HTML现在是:

<table>
    <tr>
      <th>(empty)</th>
      <th>Heading A</th>
      <th>Heading B</th>
      <th>Heading C</th>
    </tr>
 <tr>
  <th>Heading 1</th>
     <td>content for 1 and A</td>
     <td>content for 1 and B</td>
     <td>content for 1 and C</td>
 </tr>
 <tr>
  <th>Heading 2</th>
     <td>content for 2 and A</td>
     <td>content for 2 and B</td>
     <td>content for 2 and C</td>
 </tr>
</table>

从技术上讲,evey表格单元格(thtd)必须交换其索引:列索引应该成为行索引,列索引应该成为rown索引。但是我如何使用JavaScript和/或JQuery做到这一点?

我已经找到了如何获取行和列索引:

//column
$(this).parent().children().index(this);

//row
$(this).parent().parent().children().index(this.parentNode);

但似乎没有JQuery函数用于设置表格单元格位置&#34;,只有.inserAfter而老实说,我不知道如何处理它。

6 个答案:

答案 0 :(得分:3)

像这样更改你的HTML

<table>
<tbody>
    <tr>
      <td>(empty)</td>
      <td>Heading 1</td>
      <td>Heading 2</td>
    </tr>
 <tr>
  <td>Heading A</td>
     <td>content for 1 and A</td>
     <td>content for 2 and A</td>
 </tr>
 <tr>
  <td>Heading B</td>
     <td>content for 1 and B</td>
     <td>content for 2 and B</td>
 </tr>
 <tr>
  <td>Heading C</td>
     <td>content for 1 and C</td>
     <td>content for 2 and C</td>
 </tr>
 </tbody>
</table>

并调用此函数

function Swap(){
    var t= document.getElementsByTagName('tbody')[0],
    r= t.getElementsByTagName('tr'),
    cols= r.length, rows= r[0].getElementsByTagName('td').length,
    cell, next, tem, i= 0, tbod= document.createElement('tbody');

    while(i<rows){
        cell= 0;
        tem= document.createElement('tr');
        while(cell<cols){
            next= r[cell++].getElementsByTagName('td')[0];
            tem.appendChild(next);
        }
        tbod.appendChild(tem);
        ++i;
    }
    t.parentNode.replaceChild(tbod, t);
}

测试here

答案 1 :(得分:2)

function invertTable(table){

  var $table = $(table);

  var invertedTable = [];

  for(var i=0 ; i < $table.find('tr:first th').length ; i++){

    invertedTable.push([]);

  }

  $table.find('th,td').each(function(){
    invertedTable[$(this).index()].push($(this).text());    
  })

  var $newTable = $('<table></table>');

  for(var i=0 ; i < invertedTable.length ; i++){

    var $newTr = $('<tr></tr>');

    for(var j = 0 ; j < invertedTable[i].length ; j++){

        if(j == 0 || i == 0){
            $newTr.append('<th>'+invertedTable[i][j]+'</th>');
        }
        else{
            $newTr.append('<td>'+invertedTable[i][j]+'</td>');
        }

    }

    $newTable.append($newTr);
  }

  $table.after($newTable)
  $table.remove();
} 

http://jsfiddle.net/xybmoadx/1/

答案 2 :(得分:0)

也许你应该建立两个表并且每次都隐藏起来。

html:

<table>
    <tr>
      <th>(empty)</th>
      <th>Heading 1</th>
      <th>Heading 2</th>
    </tr>
 <tr>
  <th>Heading A</th>
     <td>content for 1 and A</td>
     <td>content for 2 and A</td>
 </tr>
 <tr>
  <th>Heading B</th>
     <td>content for 1 and B</td>
     <td>content for 2 and B</td>
 </tr>
 <tr>
  <th>Heading C</th>
     <td>content for 1 and C</td>
     <td>content for 2 and C</td>
 </tr>
</table>

<table style="display:none;">
    <tr>
      <th>(empty)</th>
      <th>Heading A</th>
      <th>Heading B</th>
      <th>Heading C</th>
    </tr>
 <tr>
  <th>Heading 1</th>
     <td>content for 1 and A</td>
     <td>content for 1 and B</td>
     <td>content for 1 and C</td>
 </tr>
 <tr>
  <th>Heading 2</th>
     <td>content for 2 and A</td>
     <td>content for 2 and B</td>
     <td>content for 2 and C</td>
 </tr>
</table>

注意第二张桌子上的style: "display:none;"

现在,您需要做的就是在您遇到问题时使用Google桌面。假设你想要点击表格点击:

$('table').on('click', function() {
  $('table').toggle();
});

此解决方案可以确保您的表格是静态的。这是一个快速简单的工作环境。 希望有所帮助

PS:你可以测试它here

答案 3 :(得分:0)

function transpose(arr){
    return Object.keys(arr[0]).map(function (c) { return arr.map(function (r) { return r[c]; }); });
}
function transposeTable(table){
    var rows = [];
    var tableString = '';
    table.find('tr').each(function(i,row){
        var rowArray = [];
        row = $(row);
        row.find('th,td').each(function(i,cell){
            cell = $(cell);
            rowArray.push({
                value : cell.text(),
                type : cell.is('th') ? 'th':'td'
            })
        })
        rows.push(rowArray);
    });
    rows = transpose(rows);
    rows.forEach(function(row){
        tableString += '<tr>';
        row.forEach(function(cell){
           tableString += '<' + cell.type + '>';
           tableString += cell.value;
           tableString += '</' + cell.type + '>';  
        })
        tableString += '</tr>';
    });
    return tableString;
}

JSfiddle

不干净但有效。

答案 4 :(得分:0)

看看我为你创造的这个jsfiddle:

http://jsfiddle.net/carloscalla/yuhx2tgk/3/

它将表格单元格的值存储在数组中,并从中构建表格。然后在单击按钮时交换顺序。

HTML:

<div id="table-wrapper"></div>
<button id="toggler">Toggler</button>

JS:

var max_rows = 4;
var a = new Array();
for (i = 0; i < max_rows; i++)
    a[i] = new Array();

a[0][0] = "(empty)";
a[0][1] = "Heading 1";
a[0][2] = "Heading 2";

a[1][0] = "Heading A";
a[1][1] = "content 1 A";
a[1][2] = "content 2 A";

a[2][0] = "Heading B";
a[2][1] = "content 1 B";
a[2][2] = "content 2 B";

a[3][0] = "Heading C";
a[3][1] = "content 1 C";
a[3][2] = "content 2 C";

var direction = 0;
// 0 for horizontal
// 1 for vertical

function changeDirection(){
    if (direction == 1) direction = 0;
    else if (direction == 0) direction = 1;
    resetTable();
}
function resetTable(){
    var $table_body = $('<table><tbody></tbody></table>');

    if (direction == 0){
        for (x = 0; x < a.length; x++){
            $table_body.append('<tr></tr>');
            $last_row = $table_body.find('tr').last();
            for (v = 0; v < a[x].length; v++){
                $last_row.append('<td>' + a[x][v] + '</td>');
            }
        }
    }
    else{
        for (x = 0; x < a[0].length; x++){
            $table_body.append('<tr></tr>');
            $last_row = $table_body.find('tr').last();
            for (v = 0; v < a.length; v++){
                $last_row.append('<td>' + a[v][x] + '</td>');
            }
        }        
    }

    $('#table-wrapper').html($table_body);
}
$('#toggler').on('click', changeDirection);

结果如下:

原始表:

enter image description here

更新的表格:

enter image description here

答案 5 :(得分:0)

从javascript动态生成数组。这将是制作它的最简单方法......以及维护它。

假设一个多维数组[x] [y]代表你所需要的一切。 [0] [0]显然是空的......

在HTML中定义一个表元素给它一个ID,比如'table'...在JavaScript中然后......

定义它应该很容易......

var t = new Array();
t[0] = new Array();
t[0][0] = 'Heading 1';
t[0][1] = 'Heading 2';

依旧......

在jQuery的Document Ready事件中,您可以初始化它......

$(document).ready(function() {
    for (var i = 0; i < t.length; i++) {
        $('#table').append('<tr id=tr' + 0 + '></tr>');
        for (var j = 0; j < t[i].length; j++) {
            if (i == 0)
                $('#tr' + i).append('<th>' + t[i][j] + '</th>');
            else
                $('#tr' + i).append('<td>' + t[i][j] + '</td>');
        }
    }

    var t_trans = t[0].map(function(col, i) {
        return t.map(function(row) {
            return row[i];
        });
    });
});

我使用了这个答案中的代码来转置创建的数组并将其存储在另一个变量中。 Transposing a 2D-array in JavaScript

现在,点击HTML中的“Transpose Button”所需要做的就是删除“table”中的现有标记,然后使用转置数组重新创建它。所以在onclick事件中,

$('#table').empty();
for (var i = 0; i < t_trans.length; i++) {
    $('#table').append('<tr id=tr' + 0 + '></tr>');
    for (var j = 0; j < t_trans[i].length; j++) {
        if (i == 0)
            $('#tr' + i).append('<th>' + t_trans[i][j] + '</th>');
        else
            $('#tr' + i).append('<td>' + t_trans[i][j] + '</td>');
    }
}

这应该这样做......天啊,你甚至可以创建一个复合函数,以数组作为参数来为你完成这项工作,例如function populate(arr){}和嵌套循环......

function populate(arr){
    for (var i = 0; i < arr.length; i++) {
        $('#table').append('<tr id=tr' + 0 + '></tr>');
        for (var j = 0; j < arr[i].length; j++) {
            if (i == 0)
                $('#tr' + i).append('<th>' + arr[i][j] + '</th>');
            else
                $('#tr' + i).append('<td>' + arr[i][j] + '</td>');
        }
    }
}

并在点击按钮后清空populate(t)并准备好populate(t_trans)