能否用yadcf按类过滤DataTable行?多列类筛选需求咨询
Absolutely, yadcf is a perfect tool to solve this problem—way more flexible for custom filter logic than basic DataTables search, and it will work across all pages, not just the first one. Let's walk through how to adapt your existing setup to make this work.
Step 1: Ensure yadcf is Loaded
First, double-check you've included yadcf's CSS and JS files in your page:
<link rel="stylesheet" href="path/to/yadcf.css"> <script src="path/to/yadcf.js"></script>
Step 2: Build a Custom yadcf Filter for 'lime' Rows
We'll create a custom filter that checks if any <td> with the lime class exists in a row. This will work across all pagination pages, which fixes your original issue.
Step 3: Integrate with Your Existing DataTable Setup
Replace your current $.fn.DataTable.ext.search.push(...) and #showLime handler with this yadcf implementation. Here's your full modified code:
const table = $('#example').DataTable( { responsive: { details: { } }, "ajax": "console.json", "search": { "regex": true }, "columns": [ { "class": 'details-control', "orderable": false, "data": null, "defaultContent": '' }, { "data": "time" }, { "data": "firstgoal" }, { "data": "score" }, { "data": "league" }, { "data": "teams", "defaultContent": "0" }, { "data": function (data, type, dataToSet) { return data.nextover + "% (" + data.sno + ")";} }, { "data": "pi1", "render": function (data, type, row) { return '<span class="show-modalp1" data-modal-id="'+ row.gameid + '">' + data + '</span>'; }}, { "data": "pi2", "render": function (data, type, row) { return '<span class="show-modalp2" data-modal-id="'+ row.gameid + '">' + data + '</span>'; }}, { "render": function (data, type, JsonResultRow, meta) { return '<img src="'+JsonResultRow.rc+'" class="center">'; }} ], "order": [[1, 'asc']], rowCallback: function(row, data, index){ if((data["nextover"] >85 && data["sno"]>14) || (data["nextover"] >70 && data["sno"]>10 && data["time"]>=70) || (data["nextover"] >55 && data["sno"]>5 && data["time"]>=81)) { $(row).find('td:eq(6)').css('background-color', 'lime').addClass('lime'); } else { $(row).find('td:eq(6)').css('background-color', 'mistyrose'); } var chars = data["pi2"].split(':'); if(Number(chars[0])+Number(chars[1])>15) { $(row).find('td:eq(8)').css('background-color', 'lime').addClass('lime'); } else { $(row).find('td:eq(8)').css('background-color', 'mistyrose'); } var chars2 = data["pi1"].split(':'); if(Number(chars2[0])+Number(chars2[1])>70) { $(row).find('td:eq(7)').css('background-color', 'lime').addClass('lime'); } else { $(row).find('td:eq(7)').css('background-color', 'mistyrose'); } }, drawCallback: function(settings) { $(".show-modalp1").each(function() { var id = $(this).attr('data-modal-id'); $(this).popover({ content: function() { return '<div style="width: 440px; height=220px"><iframe src="../pressure/showgraph.php?gameid=' + id + '&pi=pi1" width=440 height=220></iframe></div>'; }, trigger: 'hover', placement: 'left', html: true, title: 'Pressure Index 1 = (10*SOT)+(10*SOFT)+1 per 5%poss' } ); }); $(".show-modalp2").each(function() { var id = $(this).attr('data-modal-id'); $(this).popover({ content: function() { return '<div style="width: 440px; height=220px"><iframe src="../pressure/showgraph.php?gameid=' + id + '&pi=pi2" width=440 height=220></iframe></div>'; }, trigger: 'hover', placement: 'left', html: true, title: 'Pressure Index 2 = 1 *dangerous attack - 1 point if no corners in last 8' } ); }); }, } ); // Initialize yadcf with custom filter for lime rows yadcf.init(table, [ { column_number: 0, // Attach filter to the first (details-control) column filter_type: 'custom_func', custom_func: function(filterVal, columnVal, rowValues, rowIdx) { // Check if the row has any td with 'lime' class const row = table.row(rowIdx).node(); return filterVal === 'show' ? $(row).has('td.lime').length > 0 : true; }, filter_container_id: 'lime-filter-container', data: [{ value: '', label: 'Show All Rows' }, { value: 'show', label: 'Show Only Lime Rows' }], select_type: 'select' // Use 'select2' here if you want a nicer dropdown UI } ]); // Keep your existing event handlers $('#example').on('draw.dt', function () { $('[data-toggle="tooltip"]').tooltip(); }); // Add event listener for opening and closing details $('#example tbody').on('click', 'td.details-control', function () { var tr = $(this).parents('tr'); var row = table.row( tr ); if ( row.child.isShown() ) { row.child.hide(); tr.removeClass('shown'); } else { row.child( format(row.data()) ).show(); tr.addClass('shown'); } } ); $('#reset').on('click', function () { table.columns(1).search("").draw(); table.ajax.reload(null, false); }) $('#secondhalf').on('click', function () { regExSearch = '(4[6-9]|[5-8][0-9]|90)'; table.column(1).search(regExSearch, true, false).draw(); }); $('#firsthalf').on('click', function () { regExSearch = '([1-3][0-9]|4[0-5])'; table.column(1).search(regExSearch, true, false).draw(); }); $('#halftime').on('click', function () { table.columns(1).search("HT").draw(); }); setInterval( function () { table.ajax.reload( null, false ); }, 30000 );
Step 4: Add the Filter UI Container
Add this HTML above your table to display the filter dropdown:
<div id="lime-filter-container" class="yadcf-filter-wrapper"></div>
Why This Fixes Your Original Issue
Your initial ext.search approach only checked rows currently in the DOM (so only the first page). yadcf's custom filter works with DataTables' full dataset, checking every row regardless of pagination. It also provides a clean, reusable UI that integrates seamlessly with your existing controls.
Bonus Customization
If you want to restrict the filter to only check columns 6, 7, and 8 (your lime-targeted columns), modify the custom function to:
return filterVal === 'show' ? $(row).find('td:eq(6), td:eq(7), td:eq(8)').hasClass('lime') : true;
内容的提问来源于stack exchange,提问作者Mike Hobson

