简体   繁体   中英

Dynamic sorting in jquery DataTables

I'm using DataTables with the columns.render option to implement custom sorting for a table. That works fine when the logic within the sort function only depends on static data. However, I'd like to provide some controls to my users controlling how the sorting should happen. The problem is that it seems like DataTables is caching the first sort result, so when the user tries to change the sorting controls it doesn't have any effect.

In short, I'd like to have a dynamic sort function.

Obviously this is best explained with an example. The idea is to allow the "Info" column to be sorted either by "customer name" or "price", depending on what the user selects in the radio above the table. Run it and you'll see that the sorting only works for the initial radio selection.

 $(function() { var opts = { "columns": [{ 'searchable': false }, { 'render': function(data, type, row, meta) { if (type === 'sort') { var sel = $("input[name=infoFilterOptions]:checked").val(); return $(sel, $(data)).data('value'); } return data; } }] }; $("#the_table").DataTable(opts); }); 
 <html> <head> <script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.css" /> <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js"></script> </head> <body> <div style="color:green; margin-bottom: 10px;"> <div style="display: inline-block; margin-right: 10px;">Sort <i>Info</i> column by:</div> <label class="radio-inline"> <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-price" checked>Price </label> <label class="radio-inline"> <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-customer-name">Customer name </label> </div> <table id="the_table" class="stripe"> <thead> <tr> <th>Id</th> <th>Info</th> </tr> </thead> <tbody> <tr> <td>1</td> <td> <div>Customer name: <span class="info-customer-name" data-value="John">John</span> </div> <div>Price: <span class="info-price" data-value="42.42">$42.42</span> </div> </td> </tr> <tr> <td>3</td> <td> <div>Customer name: <span class="info-customer-name" data-value="Melvyn">Melvyn</span> </div> <div>Price: <span class="info-price" data-value="14.0">$14.00</span> </div> </td> </tr> <tr> <td>18</td> <td> <div>Customer name: <span class="info-customer-name" data-value="Aaaaardvark">Aaaaardvark</span> </div> <div>Price: <span class="info-price" data-value="22.3">$22.30</span> </div> </td> </tr> </tbody> </table> </body> </html> 

Allan answered this question over on the DataTables forums . First class support, as always!

Short answer is that DataTables is indeed caching the sort result. You need to invalidate the data in the table (via row().invalidate() or rows().invalidate() ) in order to recompute the sort order.

This does the trick:

$('input[type=radio][name=infoFilterOptions]').on('change', function() {
    $("#the_table").DataTable().rows().invalidate();
});

Here's the full example from above including this fix:

 $(function() { var opts = { "columns": [{ 'searchable': false }, { 'render': function(data, type, row, meta) { if (type === 'sort') { var sel = $("input[name=infoFilterOptions]:checked").val(); return $(sel, $(data)).data('value'); } return data; } }] }; $("#the_table").DataTable(opts); $('input[type=radio][name=infoFilterOptions]').on('change', function() { $("#the_table").DataTable().rows().invalidate(); }); }); 
 <html> <head> <script type="text/javascript" src="https://code.jquery.com/jquery-3.1.0.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.css" /> <script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.12/datatables.min.js"></script> </head> <body> <div style="color:green; margin-bottom: 10px;"> <div style="display: inline-block; margin-right: 10px;">Sort <i>Info</i> column by:</div> <label class="radio-inline"> <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-price" checked>Price </label> <label class="radio-inline"> <input style="margin-top: 0;" type="radio" name="infoFilterOptions" value=".info-customer-name">Customer name </label> </div> <table id="the_table" class="stripe"> <thead> <tr> <th>Id</th> <th>Info</th> </tr> </thead> <tbody> <tr> <td>1</td> <td> <div>Customer name: <span class="info-customer-name" data-value="John">John</span> </div> <div>Price: <span class="info-price" data-value="42.42">$42.42</span> </div> </td> </tr> <tr> <td>3</td> <td> <div>Customer name: <span class="info-customer-name" data-value="Melvyn">Melvyn</span> </div> <div>Price: <span class="info-price" data-value="14.0">$14.00</span> </div> </td> </tr> <tr> <td>18</td> <td> <div>Customer name: <span class="info-customer-name" data-value="Aaaaardvark">Aaaaardvark</span> </div> <div>Price: <span class="info-price" data-value="22.3">$22.30</span> </div> </td> </tr> </tbody> </table> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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