jQuery DataTables - custom filter for column that

2019-06-07 12:55发布

问题:

I am using the jQuery DataTables plugin.

I'd like to create a custom filter for a column that contains a text field.

I want to filter based on the value attribute of the input field in the column.

I need to do this so I can avoid having the filter match the html to the search pattern.

For example, I can't search for id or form without finding every row (the text form is found in the id attributes of the text fields).

I've found many questions and forums that say mData is the answer to my problem.

No matter what I try, I can't get it to work.

Here is how I define my columns:

prefColumns:  [ { bSortable: true,  bSearchable: false, sSortDataType: 'dom-checkbox' },
                { bSortable: true,  bSearchable: true  },
                { bSortable: true,  bSearchable: true,  sSortDataType: 'dom-text' },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false } 
              ]

I assign the above array to the aoColumns property like this:

// Find all the pref tables we want to turn into DataTables

var $categoryTables = $('table[id$="cat-table"]');

// Create a jQuery dataTable for each pref category

$categoryTables.dataTable( { 
    sScrollY:    "350px",
    bPaginate:   false,
    bAutoWidth:  false,
    sDom:        '<"prefsFilter"f>t',
    aoColumns:   prefColumns,
    aaSorting:   [[ 1, 'asc' ]]
});

Everything works fine.

Here are my custom sort functions used above (just in case):

$.fn.dataTableExt.afnSortData['dom-text'] = function (oSettings, iColumn) {
    var aData = [];
    $('td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each(function () {
        aData.push( this.value );
    } );
    return aData;
};

// Add a custom sort function for columns that might contain checkbox fields.

$.fn.dataTableExt.afnSortData['dom-checkbox'] = function ( oSettings, iColumn ) {
    var aData = [];
    $('td:eq('+iColumn+')', oSettings.oApi._fnGetTrNodes(oSettings) ).each(function () {
        var $box = $(':checkbox', $(this));
        if ($box.length === 0) {
            aData.push("1");
        }
        else {
            aData.push( $box.is(':checked') ? "2" : "3" );
        }
    } );
    return aData;
};

// Add a custom sort function for columns with slider buttons

$.fn.dataTableExt.afnSortData['slider'] = function (oSettings, iColumn) {
    var aData = [];
    var s = 'input:hidden[id$="State"]';
    $('td:eq('+iColumn+') ' + s, oSettings.oApi._fnGetTrNodes(oSettings) ).each(function () {
        aData.push( this.value );
    } );
    return aData;
};

The third column in my table is the one that contains the text field.

In an attempt to use the mData property, I've been modifying my column definitions with stuff like this:

prefColumns:  [ { bSortable: true,  bSearchable: false, sSortDataType: 'dom-checkbox' },
                { bSortable: true,  bSearchable: true  },

                // add a mData property to the third column

                { bSortable: true,  bSearchable: true,  sSortDataType: 'dom-text', 
                  mData: function (src, type, val) { return type === 'filter' ? $(src).attr('value') : src; } },

                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false, sSortDataType: 'slider'   },
                { bSortable: true,  bSearchable: false } 
              ]

I've tried a bunch of stuff similar to the above and nothing seems to be working like the docs and online examples.

Nothing I've found in any forums or other questions has worked.

If anybody could give me a clue about what I'm misunderstanding, I would really appreciate it.

回答1:

try this for your text column:

{ "bSortable": true ,  "bSearchable" : true,
   "mData": function ( source, type, val ) {
       if (type === 'set') {
            source.disp = val
            source.filter = $(val).attr('value');
            return;
        }
        else if (type === 'filter') {
            return source.filter;
        }

        return source.disp; 
     }

  }

Only downside is that if you change the field and then try to search again - it will not take into account changes. So if you'll find how to invoke mData method again on fly - everything will work as it should.



回答2:

You can use mRender attribute in the aoColumns to specify the selected value of the select box for filtering

"mRender": function ( data, type, full ) {
    if (type === "filter")
    {
          node = $.parseHTML(data);
          var val = $(node).find("select option:selected").text();                     
              return val;
    }
    return data;
}

if you use this method, note you shouldn't use SortDataType='dom-select' on that column