سؤال

I am using the dataTables plugin and re-using code I have on another page to have a select that filters one specific column. When this failed to filter correctly I was confused as it's the same code I've used previously.

Upon inspection, I have now just discovered that the cause is using child rows with dataTables - http://datatables.net/examples/api/row_details.html

HTML

<select name="col4_filter" id="col4_filter">
    <option value="">All</option>
    <!-- Other Options -->
</select>

<table>
    <thead>
        <tr>
            <th>1</th>
            <th>2</th>
            <th>3</th>
            <th>4</th>
            <th>5</th>
            <th>6</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>

jQuery (quite a lot but all dataTables related)

if (!jQuery().dataTable) {
    return;
}

/*
 * Insert a 'details' column to the table
 */
var nCloneTh = document.createElement('th');
var nCloneTd = document.createElement('td');


nCloneTd.innerHTML = '<span class="row-details row-details-close"></span>';

$('table thead tr').each(function() {
    this.insertBefore(nCloneTh, this.childNodes[0]);
});

$('table tbody tr').each(function() {
    this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
});

var oTable = $('table').dataTable({
    "sDom": 'T<"clear">lfrtip',
    "aaSorting": [],
    "aLengthMenu": [
         [15, 20, -1],
         [15, 20, "All"] // change per page values here
     ],
     // set the initial value
     "iDisplayLength": 15,
     "sPaginationType": "bootstrap",
     "oLanguage": {
         "sLengthMenu": "_MENU_ records",
         "oPaginate": {
             "sPrevious": "Prev",
             "sNext": "Next"
         }
     }
 });


 /* Formatting function for row details */
 function fnFormatDetails (oTable, nTr, row_id) {
     var id = row_id.split('_').pop();

     var sOut = '<table>';
     sOut += '<tr><td id="details_' + id + '">Finding Child Rows... <img src="/images/portal/loading.gif" alt="Finding Child Rows..." /></td></tr>';
     sOut += '</table>';

     $.ajax({
         type: 'GET',
         url: '/ajax_find_child_rows',
         dataType: "html",
         data: { id: id }, 
         success: function(data) {
             $('#details_' + id).html(data);
         },
         error: function() {
             $('#details_' + id).html('No child rows found');
         }   

     });

     return sOut;
 }


 /* Add event listener for opening and closing details
  * Note that the indicator for showing which row is open is not controlled by DataTables,
  * rather it is done here
  */
 $('table').on('click', 'tbody td .row-details', function() {
     var nTr = $(this).parents('tr')[0];

     if (oTable.fnIsOpen(nTr)) {
         /* This row is already open - close it */
         $(this).addClass("row-details-close").removeClass("row-details-open");
         oTable.fnClose(nTr);
     } else {
         /* Open this row */     
         var row_id = ($(this).parent().parent().attr('id'));           

         $(this).addClass("row-details-open").removeClass("row-details-close");
         oTable.fnOpen(nTr, fnFormatDetails(oTable, nTr, row_id), 'details');
     }
 });

function fnFilterColumn(i) {
     oTable.fnFilter($('#col'+(i+1)+'_filter').val(), i);
}

$("#col4_filter").change( function() { fnFilterColumn(3); });

The symptoms were that the filter failed to work and reset when a blank option was selected.

e.g. just adding one to the index doesn't work:

$("#col4_filter").change( function() { fnFilterColumn(4); }); // 4 instead of 3 (selector doesn't matter just now)

and after resetting the select after the failed filter, the filter doesn't reset.

The weird thing is that if I use the previous column ($("#col4_filter").change( function() { fnFilterColumn(2); });) then it will work for some reason.

I'm guessing that the column insertion is messing up the filter because the index of the column is off.

هل كانت مفيدة؟

المحلول

Apologies, just realised what my error was.

function fnFilterColumn(i) {

    oTable.fnFilter($('#col4_filter').val(), i);  // hard-coding selector
}

$("#col4_filter").change( function() { fnFilterColumn(4); }); // add 1 to the column index to account for dynamically added column

I got so mixed up in finding the error I failed to remember that whilst I was changing the column index that then the fnFilterColumn would be looking for an element's value that doesn't exist to filter by.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top