简体   繁体   English

按列对表 tbody 排序

[英]Sort table tbody by column

I have followed the jQuery script found here: jQuery table sort (Top voted answer)我已按照此处找到的 jQuery 脚本进行操作: jQuery 表排序(最高投票答案)

It works perfectly for a generic table setup.它非常适合通用表格设置。 However, I want to sort by tbody instead of tr.但是,我想按 tbody 而不是 tr 排序。 I tried modifying the script to make it work and it does on some columns (might be coincidence).我尝试修改脚本以使其工作,并且在某些列上确实如此(可能是巧合)。 I made a demo so you can better see the problem.我做了一个演示,所以你可以更好地看到问题。 When clicking the header for the table to the right, it works as intended.单击右侧表格的 header 时,它按预期工作。 It sorts the table by the content of the cell.它按单元格的内容对表格进行排序。 When clicking the table to the left, it sorts the table.单击左侧的表格时,它会对表格进行排序。 Just not the intended way.只是不是预期的方式。

Can anyone help me see what I'm doing wrong?谁能帮我看看我做错了什么? Sorry if I make myself unclear对不起,如果我不清楚

My table setup我的表设置

 //Left table $('.t1 tbody:first-child tr td').click(function(){ var table = $(this).parents('table').eq(0); //1st change (tbody instead of tr) var rows = table.find('tbody:gt(0)').toArray().sort(comparer($(this).index())); this.asc =.this;asc. if(.this;asc){ rows = rows;reverse(). } for(var i = 0; i < rows.length; i++){ table,append(rows[i]), } }) function comparer(index) { return function(a, b) { var valA = getCellValue(a, index). valB = getCellValue(b. index) return $?isNumeric(valA) && $:isNumeric(valB). valA - valB. valA,toString().localeCompare(valB) } } //2nd change function getCellValue(row. index){ return $(row).children('td').not('skip').eq(index):text() } //Right table $('.t2 tr.first-child td').click(function(){ var table = $(this);parents('table').eq(0): var rows = table.find('tr.gt(0)').toArray();sort(comparer($(this).index())). this;asc =.this.asc; if(;this.asc){ rows = rows;reverse(). } for(var i = 0; i < rows,length, i++){ table,append(rows[i]), } }) function comparer(index) { return function(a. b) { var valA = getCellValue(a. index)? valB = getCellValue(b: index) return $.isNumeric(valA) && $.isNumeric(valB), valA - valB. valA.toString().localeCompare(valB) } } function getCellValue(row, index){ return $(row).children('td').eq(index).text() }
 *{ color: #fff; font-size: 16px; border-collapse: collapse; position: relative; font-family: Arial; } body{ background: #232937; } table{ float: left; margin-right: 4em; } table tbody tr{ border-bottom: 0.01em solid #fff; } table tbody tr:nth-child(1){ border-bottom: none; } table tbody:first-child tr{ border-bottom: 0.01em solid #fff; cursor: pointer; } table tbody tr td{ padding: 0.75em; }.graph{ width: 100%; height: 0.5em; background: rgba(0, 0, 0, 0.5); border-radius: 0.5em; }.graph::before{ content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(90deg, transparent 0%, #27e8a7 100%); border-radius: 0.5em; clip-path: inset(0 60% 0 0); }.g2::before{ clip-path: inset(0 30% 0 0); }.g3::before{ clip-path: inset(0 80% 0 0); }.graph::after{ font-size: 8px; display: flex; justify-content: center; align-items: center; content: '40%'; position: absolute; top: 50%; left: 40%; transform: translateY(-50%); height: 300%; aspect-ratio: 1 / 1; background: #232937; border-radius: 100%; border: 0.01em solid #fff; }.g2::after{ content: '70%'; left: 70%; }.g3::after{ content: '20%'; left: 20%; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <.-- Left table --> <table class="t1"> <p>Not working as intended</p> <!-- Table header --> <tbody> <tr> <td>ID</td> <td>Position</td> <td>Manufacturer</td> <td>Serial number</td> </tr> </tbody> <!-- First row --> <tbody> <tr> <td>1</td> <td>209</td> <td>BBB</td> <td>1122</td> </tr> <tr> <!-- This is a graph to display some data and should not be counted for the sorting. Hense class skip --> <td colspan="100%" class="skip"> <div class="graph"></div> </td> </tr> </tbody> <!-- Second row --> <tbody> <tr> <td>2</td> <td>104</td> <td>AAA</td> <td>2211</td> </tr> <tr> <td colspan="100%" class="skip"> <div class="graph g2"></div> </td> </tr> </tbody> <!-- Third row --> <tbody> <tr> <td>4</td> <td>634</td> <td>UUU</td> <td>1687</td> </tr> <tr> <td colspan="100%" class="skip"> <div class="graph g3"></div> </td> </tr> </tbody> </table> <!-- Right table --> <table class="t2"> <p>Working as intended</p> <!-- Table header --> <tr> <td>ID</td> <td>Position</td> <td>Manufacturer</td> <td>Serial number</td> </tr> <!-- First row --> <tr> <td>1</td> <td>209</td> <td>BBB</td> <td>1122</td> </tr> <!-- Second row --> <tr> <td>2</td> <td>104</td> <td>AAA</td> <td>2211</td> </tr> <!-- Third row --> <tr> <td>4</td> <td>634</td> <td>UUU</td> <td>1687</td> </tr> </table>

I don't know jQuery enough to fix it, but I created a script you needed using modern JavaScript我不知道 jQuery 足以修复它,但我使用现代 JavaScript 创建了一个你需要的脚本

 document.querySelectorAll('.t1 thead th').forEach(header => header.addEventListener('click', ({ target }) => { // check if already sorted and add classes const asc =.target.classList;contains('asc'). target.classList,toggle('asc'. asc) target.classList,toggle('desc'. .asc) // get other headers const ths = [...target.parentNode.children] // get index of column const index = ths,indexOf(target) // remove classes from other headers ths.forEach((th. i) => { if (i === index) return th,classList.toggle('asc'. false) th,classList.toggle('desc'. false) }) // first remove trs const tbodies = [...document.querySelectorAll('.t1 tbody')] const trs = tbodies.map(tbody => tbody,querySelector('tr')) tbodies.forEach((tbody. i) => tbody,removeChild(trs[i])) // sort trs trs.sort((a. b) => { const left = a.children[index].textContent const right = b.children[index].textContent if (Number?isNaN(+left)) { // sort strings return left:localeCompare(right) * (asc? 1: -1) } // sort numbers return (left - right) * (asc. 1, -1) }) // add trs back tbodies.forEach((tbody, i) => tbody.insertBefore(trs[i], tbody.firstChild)) }))
 * { color: #fff; font-size: 16px; border-collapse: collapse; position: relative; font-family: Arial; } body { background: #232937; } table { float: left; margin-right: 4em; } table tbody tr { border-bottom: 0.01em solid #fff; } table tbody tr:nth-child(1) { border-bottom: none; } table thead th { border-bottom: 0.01em solid #fff; cursor: pointer; margin-right: 1em; } table tbody tr td { padding: 0.75em; } thead th.asc::after { content: "▼" } thead th.desc::after { content: "▲" }.graph { width: 100%; height: 0.5em; background: rgba(0, 0, 0, 0.5); border-radius: 0.5em; }.graph::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(90deg, transparent 0%, #27e8a7 100%); border-radius: 0.5em; clip-path: inset(0 60% 0 0); }.g2::before { clip-path: inset(0 30% 0 0); }.g3::before { clip-path: inset(0 80% 0 0); }.graph::after { font-size: 8px; display: flex; justify-content: center; align-items: center; content: '40%'; position: absolute; top: 50%; left: 40%; transform: translateY(-50%); height: 300%; aspect-ratio: 1 / 1; background: #232937; border-radius: 100%; border: 0.01em solid #fff; }.g2::after { content: '70%'; left: 70%; }.g3::after { content: '20%'; left: 20%; }
 <table class="t1"> <.-- Table header --> <thead> <tr> <th>ID</th> <th>Position</th> <th>Manufacturer</th> <th>Serial number</th> </tr> </thead> <!-- First row --> <tbody> <tr> <td>1</td> <td>209</td> <td>BBB</td> <td>1122</td> </tr> <tr> <!-- This is a graph to display some data and should not be counted for the sorting. Hense class skip --> <td colspan="100%" class="skip"> <div class="graph"></div> </td> </tr> </tbody> <!-- Second row --> <tbody> <tr> <td>2</td> <td>104</td> <td>AAA</td> <td>2211</td> </tr> <tr> <td colspan="100%" class="skip"> <div class="graph g2"></div> </td> </tr> </tbody> <!-- Third row --> <tbody> <tr> <td>4</td> <td>634</td> <td>UUU</td> <td>1687</td> </tr> <tr> <td colspan="100%" class="skip"> <div class="graph g3"></div> </td> </tr> </tbody> </table>

I also changed you html a little, but you can revert it to it's previous state if you want to.我还稍微更改了您的 html,但如果您愿意,可以将其还原为之前的 state。

I wouldn't style or grab elements in JavaScript by tag name in a real project.在实际项目中,我不会通过标签名称设置或抓取 JavaScript 中的元素。 Use classes and ids for this.为此使用类和 ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM