如何根据javascript中的值来排序表行

时间:2015-01-28 07:15:58

标签: javascript html

我在桌子上工作,我的目标是根据列的总和有序地显示行。我的意思是,应该首先显示最高价值的行,然后再显示第二个最高值,然后继续..已经尝试过但无法实现。请给我一个想法,这对我来说已经足够了。我无法根据其总和值来了解如何重新洗牌。对此有何想法?

<div id="na_1" style="border: 1px solid gray;width: 450px;padding:10px;">
<form>
<input type="radio" value="All" onclick="Turnthis();"/>All
<input type="radio" value="Top15" onclick="TurnOutthis();"/>Top5
</form>
<table id="bt_01" border="1" width="100%">
<thead>
<tr><td>head1</td><td>head2</td><td>head3</td><td>head4</td><td>head5</td><td>head6</td><td>head7</td></tr>
</thead>
<tbody>
<tr><td>Subject1</td><td>501</td><td>501</td><td>501</td><td>550</td><td>560</td><td>570</td></tr>
<tr><td>Subject2</td><td>620</td><td>640</td><td>605</td><td>650</td><td>600</td><td>604</td></tr>
<tr><td>Subject3</td><td>730</td><td>730</td><td>740</td><td>750</td><td>760</td><td>790</td></tr>
<tr><td>Subject4</td><td>700</td><td>701</td><td>700</td><td>702</td><td>700</td><td>703</td></tr>
<tr><td>Subject5</td><td>220</td><td>201</td><td>202</td><td>222</td><td>210</td><td>203</td></tr>
<tr><td>Subject6</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
<tr><td>Subject7</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
<tr><td>Subject8</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
<tr><td>Total</td><td>202</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
</tbody>  
</table>

</div>

按下“Top5”按钮后,表格应显示如下[样本]

    <div id="na_1" style="border: 1px solid gray;width: 450px;padding:10px;">
    <form>
    <input type="radio" value="All" onclick="Turnthis();"/>All
    <input type="radio" value="Top15" onclick="TurnOutthis();"/>Top5
    </form>
    <table id="bt_01" border="1" width="100%">
    <thead>
    <tr><td>head1</td><td>head2</td><td>head3</td><td>head4</td><td>head5</td><td>head6</td><td>head7</td></tr>
    </thead>
    <tbody>
<tr><td>Subject3</td><td>730</td><td>730</td><td>740</td><td>750</td><td>760</td><td>790</td></tr>
    <tr><td>Subject4</td><td>700</td><td>701</td><td>700</td><td>702</td><td>700</td><td>703</td></tr>
<tr><td>Subject2</td><td>620</td><td>640</td><td>605</td><td>650</td><td>600</td><td>604</td></tr>
    <tr><td>Subject1</td><td>501</td><td>501</td><td>501</td><td>550</td><td>560</td><td>570</td></tr>
<tr><td>Subject5</td><td>220</td><td>201</td><td>202</td><td>222</td><td>210</td><td>203</td></tr>
 </tbody>  
    </table></div>

希望这是有道理的。对于您的类型信息,我除了代码只在javascript而不是jquery。

3 个答案:

答案 0 :(得分:1)

诀窍是获取所需的行并将它们放入数组中,然后对数组进行排序并按正确的顺序将行放入表中。以下将根据单元格值对行进行排序,因此如果第一个单元格值相等,则使用第二个单元格,依此类推。排序可能不稳定,因为它只使用内置的 Array.prototype.sort 。如果你想保持稳定,那很简单(但通常不需要)。

首先,获取相关的tBody元素和行:

var tBody = document.getElementById('bt_01').tBodies[0];
var rows = tBody.rows;

rows 是一个实时集合,因此您希望构建一个数组(也有助于排序)。以下在现代浏览器中工作正常:

var rowArr = Array.prototype.slice.call(rows);

但是在IE 8及更低版本中不起作用,你需要使用for循环(只需要一行代码):

var rowArr = [];
for (var i=0, iLen=rows.length; i<iLen; i++) rowArr[i] = rows[i];

要将最后一行保留为最后一行,只需保留一个参考:

var lastRow = rowArr[rowArr.length - 1];

现在根据第二个单元格的单元格值进行排序:

rowArr.sort(function(a, b) {
  var aVal, bVal;
  for (var i = 1, iLen = a.cells.length; i<iLen; i++) {
    aVal = a.cells[i].textContent || a.cells[i].innerText;
    bVal = b.cells[i].textContent || b.cells[i].innerText;
    if (aVal != bVal) return aVal - bVal;
  }
  return 0;
});

现在将行按顺序排列:

for (var j=0, jLen=rowArr.length; j<jLen; j++) {
  tBody.appendChild(rowArr[j]);
}

最后,将底行放回到底部:

tBody.appendChild(lastRow);

你完成了。并且它比提供的jQuery替代方案更短(并且可能更快)。 ; - )

最好将页脚行放在单独的tFoot部分中,因为您已经完成了标题。

修改

如果要根据每行中值的总和进行排序,排序部分将变为:

rowArr.sort(function(a, b) {
  var aSum = 0, bSum = 0;
  for (var i = 1, iLen = a.cells.length; i<iLen; i++) {
    aSum += parseFloat(a.cells[i].textContent || a.cells[i].innerText);
    bSum += parseFloat(b.cells[i].textContent || b.cells[i].innerText);
  }
  return aSum - bSum;
});

答案 1 :(得分:0)

此代码在Chrome 30上运行和测试

非jQuery版本(更新的问题):

<html>
<body>
  <div id="na_1" style="border: 1px solid gray;width: 450px;padding:10px;">
    <table id="bt_01" border="1" width="100%">
      <thead>
        <tr><td>head1</td><td>head2</td><td>head3</td><td>head4</td><td>head5</td><td>head6</td><td>head7</td></tr>
      </thead>
      <tbody>
        <tr><td>Subject1</td><td>501</td><td>501</td><td>501</td><td>550</td><td>560</td><td>570</td></tr>
        <tr><td>Subject2</td><td>620</td><td>640</td><td>605</td><td>650</td><td>600</td><td>604</td></tr>
        <tr><td>Subject3</td><td>730</td><td>730</td><td>740</td><td>750</td><td>760</td><td>790</td></tr>
        <tr><td>Subject4</td><td>700</td><td>701</td><td>700</td><td>702</td><td>700</td><td>703</td></tr>
        <tr><td>Subject5</td><td>220</td><td>201</td><td>202</td><td>222</td><td>210</td><td>203</td></tr>
        <tr><td>Subject6</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
        <tr><td>Subject7</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
        <tr><td>Subject8</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
      </tbody>
      <tfoot>
        <tr><td>Total</td><td>202</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
      </tfoot>
    </table>
  </div>
  <input type='button' onclick='sort()' value='sort by sum' />
  <script>
    function sort() {
      var t = document.getElementById('bt_01').children[1]; // tbody
      var arr = [];
        // find all tr
      var trs = t.children;
      for(;trs.length;) {
        var tr = trs[0];
        // find all td and calculate the sum
        var sum = 0;
        var tds = tr.children;
        for(var y in tds) {
          var td = tds[y];
          var v = +td.textContent;
          if (!isNaN(v)) sum += v;
        };
        // move them to arr
        tr = tr.parentNode.removeChild(tr)
        arr.push({sum: sum,tr: tr});
      };
      // sort it
      arr.sort(function(a, b) {
        if (a.sum < b.sum) return 1;
        if (a.sum > b.sum) return -1;
        return 0;
      });
      // attach back the tr in order
      for (var z in arr) t.appendChild(arr[z].tr)
    }
  </script>
</body>    
</html>

jQuery版本:

<html>
<body>
  <script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
  <div id="na_1" style="border: 1px solid gray;width: 450px;padding:10px;">
    <table id="bt_01" border="1" width="100%">
      <thead>
        <tr><td>head1</td><td>head2</td><td>head3</td><td>head4</td><td>head5</td><td>head6</td><td>head7</td></tr>
      </thead>
      <tbody>
        <tr><td>Subject1</td><td>501</td><td>501</td><td>501</td><td>550</td><td>560</td><td>570</td></tr>
        <tr><td>Subject2</td><td>620</td><td>640</td><td>605</td><td>650</td><td>600</td><td>604</td></tr>
        <tr><td>Subject3</td><td>730</td><td>730</td><td>740</td><td>750</td><td>760</td><td>790</td></tr>
        <tr><td>Subject4</td><td>700</td><td>701</td><td>700</td><td>702</td><td>700</td><td>703</td></tr>
        <tr><td>Subject5</td><td>220</td><td>201</td><td>202</td><td>222</td><td>210</td><td>203</td></tr>
        <tr><td>Subject6</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
        <tr><td>Subject7</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
        <tr><td>Subject8</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
      </tbody>
      <tfoot>
        <tr><td>Total</td><td>202</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
      </tfoot>
    </table>
  </div>
  <input type='button' onclick='sort()' value='sort by sum' />
  <script>
    function sort() {
      var t = $('#bt_01').find('tbody');
      var arr = [];
        // find all tr
      t.find('tr').each(function(idx, tr) {
        tr = $(tr);
        // find all td and calculate the sum
        var sum = 0;
        tr.find('td').each(function(idx, td) {
          td = $(td);
          var v = +td.text();
          if (!isNaN(v)) sum += v;
        });
        // move them to arr
        arr.push({sum: sum,tr: tr.detach()});
      });
      // sort it
      arr.sort(function(a, b) {
        if (a.sum < b.sum) return 1;
        if (a.sum > b.sum) return -1;
        return 0;
      });
      // attach back the tr in order
      for (var z in arr) t.append(arr[z].tr)
    }
  </script>
</body>    
</html>

答案 2 :(得分:0)

我假设你想要&#34;总计&#34;排序后表格末尾的行。否则代码可以缩短10-12行。

我想出了这个解决方案。为方便起见,我已经注释掉了所有部分。我们提供了一些帮助getElementsByTagNameremoveChildcreateElement和{{3}你可以实现你想要做的事情。这很简单。我建议你通过它。主要是创建一个包含三个属性的对象数组。 并且属性是实际的tr元素,它的总和和第一个td元素,它包含subject1,2,3 ....和Total string 。然后用appendChild对它们进行排序,然后将它们串行添加到你的tbody中元件

&#13;
&#13;
var radio=document.getElementById('radio');
if(radio.checked == true){   //check for radio element is checked or not
   radio.checked=false;
}
var table=document.getElementById('bt_01');
var serialTdArr=[]; //array which will hold the array of objects
var storageForTotal='';// store the tr element that has 'Total' as value of its first td element
function Turnthis(e){

   var tbody=document.getElementsByTagName('tbody')[0]; //get the current tbody element

    var tr=tbody.getElementsByTagName('tr'); //get all tr elements inside tbody
	
	for(i=0;i<tr.length;i++){  // loop over the tr elements
	    var sum=0;
	    var td=tr[i].getElementsByTagName('td');  //get all td element inside every tr element
		for(j=1;j<td.length;j++){
		   
			
			sum+=parseInt(td[j].innerHTML);  // sum them up
			
		   
		}
		var firstTd=td[0].innerHTML;  //save every subject1,subject2,3,...and Total string to a seperate variable
		
		serialTdArr.push({index:tr[i],sum:sum,pointer:firstTd});  // an object which holds the tr element,its sum and its first td element value is pushed inside serialTdArr
		
		
	}
	
	
	var sortedArr=serialTdArr.sort(function(a,b){  // sort them down from higher to lower
	     
		if(a.sum < b.sum){
		   return 1;
		}
		if(a.sum > b.sum){
		   return -1;
		}
		return 0;
	   
	});
	
	
	     
		table.removeChild(tbody);  // remove the current tbody
		var newTbody=document.createElement('tbody'); // create a new tbody
		table.appendChild(newTbody); // append it to table
		
	for(i=0;i<sortedArr.length;i++){
	  if((sortedArr[i].pointer) != 'Total'){  // if it has no  "Total" string then add them to tbody
	    
	
	   newTbody.appendChild(sortedArr[i].index); // add to tbody
	}else{
	  
	   storageForTotal=sortedArr[i].index;  // 'Total' row will be seperated and stored in a variable to be added later at the end of the table
	
	}
	
	}
	newTbody.appendChild(storageForTotal);  // add the tr which 'Total' to the last of td element
	
	
}
&#13;
<div id="na_1" style="border: 1px solid gray;width: 450px;padding:10px;">
<form>
<input type="radio" id='radio' value="Sort Them All" onchange="Turnthis();"/>Sort Them All

</form>
<table id="bt_01" border="1" width="100%">
<thead>
<tr><td>head1</td><td>head2</td><td>head3</td><td>head4</td><td>head5</td><td>head6</td><td>head7</td></tr>
</thead>
<tbody>
<tr><td>Subject1</td><td>501</td><td>501</td><td>501</td><td>550</td><td>560</td><td>570</td></tr>
<tr><td>Subject2</td><td>620</td><td>640</td><td>605</td><td>650</td><td>600</td><td>604</td></tr>
<tr><td>Subject3</td><td>730</td><td>730</td><td>740</td><td>750</td><td>760</td><td>790</td></tr>
<tr><td>Subject4</td><td>700</td><td>701</td><td>700</td><td>702</td><td>700</td><td>703</td></tr>
<tr><td>Subject5</td><td>220</td><td>201</td><td>202</td><td>222</td><td>210</td><td>203</td></tr>
<tr><td>Subject6</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
<tr><td>Subject7</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
<tr><td>Subject8</td><td>200</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
<tr><td>Total</td><td>202</td><td>201</td><td>200</td><td>202</td><td>200</td><td>203</td></tr>
</tbody>  
&#13;
&#13;
&#13;