Question

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.

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top