javascript - JS/HTML 如何对固定子行的表格进行排序

标签 javascript html sorting

我有下表设置:

table {
    border-collapse: collapse;
}

table, th, td {
    border: 1px solid black;
}
<table>
  <thead>
    <tr>
      <th>System Name</th>
      <th>TotalSystemGB</th>
      <th>Drive</th>
      <th>Total GB</th>
      <th>Used GB</th>
      <th>Free GB</th>
    </tr>
  </thead>
  <tbody>
    <tr class="mainRow">
      <td>System 1</td>
      <td>1100</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 1</td>
      <td></td>
      <td>C:</td>
      <td>100</td>
      <td>50</td>
      <td>50</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 1</td>
      <td></td>
      <td>D:</td>
      <td>1000</td>
      <td>750</td>
      <td>250</td>
    </tr>
    <tr class="mainRow">
      <td>System 2</td>
      <td>820</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 2</td>
      <td></td>
      <td>C:</td>
      <td>120</td>
      <td>70</td>
      <td>50</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 2</td>
      <td></td>
      <td>D:</td>
      <td>700</td>
      <td>500</td>
      <td>200</td>
    </tr>
    <tr class="mainRow">
      <td>System 3</td>
      <td>3080</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 3</td>
      <td></td>
      <td>C:</td>
      <td>80</td>
      <td>30</td>
      <td>50</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 3</td>
      <td></td>
      <td>D:</td>
      <td>1000</td>
      <td>750</td>
      <td>250</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 3</td>
      <td></td>
      <td>E:</td>
      <td>2000</td>
      <td>1500</td>
      <td>500</td>
    </tr>
  </tbody
</table>

我希望有以下行为:

  • 按“System Name”和“TotalSystemGB”排序时,只有数据根据 mainRows 排序,但 subRows 仍正确附加。
  • 按总 GB、已用或可用 GB 排序时,子行仅在 mainRow 中排序。

我目前使用 sortable但我看不出有什么方法可以让它按照我想要的方式工作,尤其是在保持子行附加到主行方面。

有什么巧妙的方法可以解决这个问题吗?

最佳答案

要对主要行进行排序,您需要找到 mainRows 及其对应的 subRows,然后基本上将它们附加到适当的位置。

对于子行,您还需要找到 mainRows,然后仅将它们追加到相应的 mainRow 之后。

var last_column;

function get_mains()
{
  var mains = document.querySelectorAll(".mainRow");
  var mains_array = []
  
  mains.forEach( item => mains_array.push(item) );
  return mains_array;
}



function order_mains(column)
{
	var mains_array = get_mains();
 	var table = document.getElementById("body");
  
 	mains_array.sort( function (a, b) {
    let a_text = a.querySelectorAll("td")[column].innerText;
    let b_text = b.querySelectorAll("td")[column].innerText;
    let truthy;
    if (column)
    {
    	return +a_text < +b_text;
    }
    else
    {
    	return a_text.localeCompare(b_text);
    }
  });  
  
  if (last_column === column)
  {
  	mains_array.reverse();
  }

  for (let item of mains_array)
  {
    var siblings = [];
    var sibling = item.nextElementSibling;
    
    table.appendChild(item);
    
    do
    {
      if (sibling.className === "mainRow")
      {
        break;
      }
      siblings.push(sibling);
    }
    while ( sibling = sibling.nextElementSibling);
    
    for (let sib of siblings)
    {
      table.appendChild(sib);
    }
  }
  last_column = (last_column === column) ? -1 : column;
}



function order_subs(column)
{
	var mains_array = get_mains();
  var tbody = document.getElementById("body");
  for (let item of mains_array)
  {
    var siblings = [];
    var sibling = item.nextElementSibling;

    do
    {
      if (sibling.className === "mainRow")
      {
        break;
      }
      siblings.push(sibling);
    }
    while ( sibling = sibling.nextElementSibling);
    
	 	siblings.sort( function (a, b) {
    let a_text = a.querySelectorAll("td")[column].innerText;
    let b_text = b.querySelectorAll("td")[column].innerText;
    return +a_text < +b_text;
 		});     
    
    if (last_column === column)
    {
      siblings.reverse();
    }   
    
    for (let sib of siblings)
    {
      body.insertBefore(sib, item.nextElementSibling);
    }
  }
  last_column = (last_column === column) ? -1 : column;
}
table {
    border-collapse: collapse;
}

table, th, td {
    border: 1px solid black;
}
<table id="the_table">
  <thead>
    <tr>
      <th onclick="order_mains(0)">System Name</th>
      <th onclick="order_mains(1)">TotalSystemGB</th>
      <th>Drive</th>
      <th onclick="order_subs(3)">Total GB</th>
      <th onclick="order_subs(4)">Used GB</th>
      <th onclick="order_subs(5)">Free GB</th>
    </tr>
  </thead>
  <tbody id="body">
    <tr class="mainRow">
      <td>System 1</td>
      <td>1100</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 1</td>
      <td></td>
      <td>C:</td>
      <td>100</td>
      <td>50</td>
      <td>50</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 1</td>
      <td></td>
      <td>D:</td>
      <td>1000</td>
      <td>750</td>
      <td>250</td>
    </tr>
    <tr class="mainRow">
      <td>System 3</td>
      <td>820</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 3</td>
      <td></td>
      <td>C:</td>
      <td>120</td>
      <td>70</td>
      <td>50</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 3</td>
      <td></td>
      <td>D:</td>
      <td>700</td>
      <td>500</td>
      <td>200</td>
    </tr>
    <tr class="mainRow">
      <td>System 2</td>
      <td>3080</td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 2</td>
      <td></td>
      <td>C:</td>
      <td>80</td>
      <td>30</td>
      <td>50</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 2</td>
      <td></td>
      <td>D:</td>
      <td>1000</td>
      <td>750</td>
      <td>250</td>
    </tr>
    <tr class="subRow">
      <td>&nbsp;&nbsp;&nbsp;&nbsp;System 2</td>
      <td></td>
      <td>E:</td>
      <td>2000</td>
      <td>1500</td>
      <td>500</td>
    </tr>
  </tbody>
</table>

关于javascript - JS/HTML 如何对固定子行的表格进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44127125/

相关文章:

php - 检查我的网站时,源代码中缺少 wp-content 文件

c - 在 C 中不使用指针对结构体数组进行排序

javascript - array.map 正在改变我的原始数组

html - 如何在 angularjs 中为表单字段生成 json 数据

html - 将两个表与一个错位的另一个表对齐

c - qsort比较功能不起作用

python - 按字符频率对字符串进行排序,按字母顺序打破联系

java - 在 Java 中对 Stripes 框架的 Ajax 调用会导致请求正文为空

javascript - 当存在具有特定名称的键时,数组将对象推送到数组中

javascript - 如何在鼠标悬停时显示弹出文本?