如何为按钮添加多函数?实现表格点击切换升降序排序
Got it, let's get that sort toggle working properly! The main issue right now is your code only runs sortAsc() every time you click, with no tracking of which direction each column is currently sorted in. Here's how to adjust things step by step:
1. Update Your HTML to Track Sort State & Target Fields
First, let's add clear metadata to each header so we know which field to sort and the current direction. We'll use data-sort for the current state and data-sort-field to map to your currentItems object properties:
<div id="appendTable"> <script type="text/html" id="tableJS"> <div class="tableDiv"> <div class="main_head">To Dos</div> <br /> <table id="myTable"> <thead> <tr> <th></th> <th data-sort="asc" data-sort-field="subject">TO DO<div class="sort_arrow"></div> </th> <th data-sort="asc" data-sort-field="resources">ASSIGNED RESOURCES<div class="sort_arrow"> </div> </th> <th data-sort="desc" data-sort-field="duedate">DUE DATE<div class="sort_arrow"></div> </th> <th data-sort="asc" data-sort-field="percentcomplete">% COMPLETE<div class="sort_arrow"></div> </th> <th></th> </tr> </thead> <tbody id="delete_row"> <tr></tr> </tbody> </table> </div> </script> </div> <script type="text/html" id="todo_template"> <tr> <td> <img src="/app/images/todo/todos_incomplete_blue.svg" /></td> <td>%todoTitle%</td> <td>%resources%</td> <td>%duedate%</td> <td>%percentcomplete%</td> <td> <div class="button"> <img src="/app/images/master/actions_btn.svg" /> </div> </td> </tr> </script>
2. Rewrite Your JavaScript to Handle Toggle Logic
Next, we'll adjust the click handler to check the current sort direction, run the right sort function, then flip the direction. We'll also make the sort functions reusable for any field:
// Click handler for sort arrows $(".sort_arrow").click(function() { // Get the parent <th> to access our data attributes const header = $(this).closest("th"); const currentSortDir = header.data("sort"); const sortField = header.data("sort-field"); // Run the appropriate sort based on current direction if (currentSortDir === "asc") { sortDesc(sortField); // Flip to descending for next click header.data("sort", "desc"); } else { sortAsc(sortField); // Flip to ascending for next click header.data("sort", "asc"); } // Clear existing rows and re-render const deleteRow = document.getElementById("delete_row"); while (deleteRow.firstChild) { deleteRow.removeChild(deleteRow.firstChild); } create(); }); // Generic ascending sort function (takes field to sort by) function sortAsc(field) { currentItems.sort((a, b) => { const valA = a[field].toUpperCase(); const valB = b[field].toUpperCase(); if (valA < valB) return -1; if (valA > valB) return 1; return 0; }); } // Generic descending sort function (takes field to sort by) function sortDesc(field) { currentItems.sort((a, b) => { const valA = a[field].toUpperCase(); const valB = b[field].toUpperCase(); if (valA > valB) return -1; if (valA < valB) return 1; return 0; }); }
Key Changes Explained:
- Tracking Sort State: We use the
data-sortattribute on each<th>to remember if we're currently sorted ascending or descending. Every click flips this value. - Reusable Sort Functions:
sortAscandsortDescnow accept afieldparameter, so they can sort any property in yourcurrentItemsarray (not justsubject). - Cleaner Row Removal: Instead of deleting rows one by one, we loop through and remove all child elements of the
<tbody>—this is more reliable. - Column-Specific Sorting: Each header now maps to a specific field via
data-sort-field, so clicking the arrow on "ASSIGNED RESOURCES" will sort by theresourcesproperty, etc.
Bonus: Handle Special Data Types (Optional)
If your duedate is a date string or percentcomplete is a number, you might want to adjust the sort logic for those fields to ensure correct ordering. For example:
// Inside sortAsc, add checks for field type function sortAsc(field) { currentItems.sort((a, b) => { let valA = a[field]; let valB = b[field]; // Handle numbers (like percentcomplete) if (!isNaN(parseFloat(valA)) && !isNaN(parseFloat(valB))) { valA = parseFloat(valA); valB = parseFloat(valB); return valA - valB; } // Handle dates else if (field === "duedate") { valA = new Date(valA); valB = new Date(valB); return valA - valB; } // Default string sort else { valA = valA.toUpperCase(); valB = valB.toUpperCase(); return valA.localeCompare(valB); } }); }
Just update sortDesc similarly by reversing the return values for number/date comparisons.
内容的提问来源于stack exchange,提问作者Patrick S

