23

I am using the jQuery plugin DataTables (http://datatables.net) for pagination, search capabilities and filtering.

There is a filter function (http://datatables.net/release-datatables/examples/api/multi_filter_select.html) that places form select elements for each column.

My issue is that I don't want the filter select elements for every column, only some. I've modified the original code as I want Yes/No filtering only, and my first column contains user names.

How do I remove the form select element from the first column?

JavaScript:

<script type="text/javascript">

$(document).ready(function() {

(function($) {
/*
 * Function: fnGetColumnData
 * Purpose:  Return an array of table values from a particular column.
 * Returns:  array string: 1d data array
 * Inputs:   object:oSettings - dataTable settings object. This is always the last argument past to the function
 *           int:iColumn - the id of the column to extract the data from
 *           bool:bUnique - optional - if set to false duplicated values are not filtered out
 *           bool:bFiltered - optional - if set to false all the table data is used (not only the filtered)
 *           bool:bIgnoreEmpty - optional - if set to false empty values are not filtered from the result array
 * Author:   Benedikt Forchhammer <b.forchhammer /AT\ mind2.de>
 */
$.fn.dataTableExt.oApi.fnGetColumnData = function ( oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty ) {
    // check that we have a column id
    if ( typeof iColumn == "undefined" ) return new Array();

    // by default we only want unique data
    if ( typeof bUnique == "undefined" ) bUnique = true;

    // by default we do want to only look at filtered data
    if ( typeof bFiltered == "undefined" ) bFiltered = true;

    // by default we do not wany to include empty values
    if ( typeof bIgnoreEmpty == "undefined" ) bIgnoreEmpty = true;

    // list of rows which we're going to loop through
    var aiRows;

    // use only filtered rows
    if (bFiltered == true) aiRows = oSettings.aiDisplay;
    // use all rows
    else aiRows = oSettings.aiDisplayMaster; // all row numbers

    // set up data array   
    var asResultData = new Array();

    for (var i=0,c=aiRows.length; i<c; i++) {
        iRow = aiRows[i];
        var aData = this.fnGetData(iRow);
        var sValue = aData[iColumn];

        // ignore empty values?
        if (bIgnoreEmpty == true && sValue.length == 0) continue;

        // ignore unique values?
        else if (bUnique == true && jQuery.inArray(sValue, asResultData) > -1) continue;

        // else push the value onto the result data array
        else asResultData.push(sValue);
    }

    return asResultData;
}}(jQuery));


function fnCreateSelect( aData )
{
    return '<select><option value="">Select</option><option value="Yes">Yes</option><option value="No">No</option></select>';
}

   var oTable = $('#results').dataTable({
         "sDom": '<<"filters"f><"clear"><"top"Tp><"clear">rt<"bottom"il>>',
         "iDisplayLength": 5,
         "sPaginationType": "full_numbers",
         "bSortCellsTop": true,
         "oLanguage": {
                    "sSearch": "Search all columns:"
          },
         "aoColumns": [
                null,
                { "sType": "title-string" },
                { "sType": "title-string" },
                { "sType": "title-string" },
                { "sType": "title-string" }
            ],
        "oTableTools": {
            "sSwfPath": "../../scripts/TableTools/copy_cvs_xls_pdf.swf" 
        }         
    });  


 /* Add a select menu for each TH element in the table footer */
    $("thead #filter td").each( function ( i ) {
        this.innerHTML = fnCreateSelect( oTable.fnGetColumnData(i) );
        $('select', this).change( function () {
            oTable.fnFilter( $(this).val(), i );
        } );
    } );    
} );
</script>

HTML:

<table id="results" class="display">
    <thead>
        <tr id="labels">
            <th>1</th>
            <th>2</th>
            <th>3</th>
            <th>4</th>
            <th>5?</th>
        </tr>
        <tr id="filter">
            <td>1</td>
            <td>2</td>
            <td>3</td>
            <td>4</td>
            <td>5?</td>
        </tr>
    </thead>
    <tbody>
    ...
    </tbody>
</table>

8 Answers 8

23

You can modify your selector to ignore the first <td> element. The index of each matched element should be 1 less than the corresponding column index.

/* Add a select menu for each TH element except the first in the table footer */
$("thead #filter td:not(:eq(0))").each( function ( i ) {
    var columnIndex = i + 1;
    this.innerHTML = fnCreateSelect( oTable.fnGetColumnData(columnIndex) );
    $('select', this).change( function () {
        oTable.fnFilter( $(this).val(), columnIndex );
    } );
});

If you wanted to be able to specify the column indexes for which you wanted a filter, one way would be to do something like

var filterIndexes = [3, 4];
$('td', '#filter').each( function ( i ) {
    if ($.inArray(i, filterIndexes) != -1) {
        this.innerHTML = fnCreateSelect( oTable.fnGetColumnData(i) );
        $('select', this).change( function () {
            oTable.fnFilter( $(this).val(), i );
        });
    }
});

Or, if you wanted to control filters by adding a class .filter to any <th> element whose column you wanted to filter, you could do something like

$('th', '#labels').each( function(i) {
    if ($(this).hasClass( 'filter' )) {
        $('td', '#filter').eq(i)
          .html( fnCreateSelect(oTable.fnGetColumnData(i)) )
          .find('select')
          .change(function () { oTable.fnFilter($(this).val(), i); });
    }
});    

Not tested, but you get the idea :)

Sign up to request clarification or add additional context in comments.

2 Comments

Does anyone know where to place the code above? It is exactly what I need - I just dont know where to place it.
@Doug Owings It looks to me you have an error in the second snippet. To check if a value is in an array you have to see if it returns -1 or not. So it should be if($.inArray(i, filterIndexes) != -1)
5

In the current version according to http://www.datatables.net/examples/api/multi_filter_select.html, for one column, I got lucky with this.api().column(0).every:

$(document).ready(function() {
    $('#mytable').DataTable( {
        initComplete: function () {
            this.api().column(0).every( function () {
                var column = this;
                var select = $('<select><option value=""></option></select>')
                    .appendTo( $(column.header()).empty() )
                    .on( 'change', function () {
                        var val = $.fn.dataTable.util.escapeRegex($(this).val());
                        column
                            .search( val ? '^'+val+'$' : '', true, false )
                            .draw();
                    } );
                column.data().unique().sort().each( function ( d, j ) {
                    select.append( '<option value="'+d+'">'+d+'</option>' )
                } );
            } );
        },
    } );
} );

But is "every" still needed then? And how to target multiple columns?

1 Comment

this.api().column( [0,1,2] ).every
5

I seconded matt voda answer, use this code for the first column:

this.api().column( [0] ).every 

and use this code for more:

this.api().column( [0,1,2] ).every 

On the tfoot column which you want to skip, you can leave it blank

Comments

1

The easiest way is put this for unneeded columns:

<input type="hidden">

Comments

0

for basic search you can get idea from:

$('tbody tr').addClass('visible');  


$('thead tr th input:text').keyup(function(event) {      



  if (event.keyCode == 27 || $(this).val() == '')
      {  ``$('tbody tr td ').show();
     }
  }

1 Comment

Thanks for the jsfiddle @Avinash, it helped me with my code.
0
$("tfoot th").each( function ( i ) {
  if(i>=3 && i<=6)
    this.innerHTML = fnCreateSelect( oTable.fnGetColumnData(i) );
  $('select', this).change( function () {
    oTable.fnFilter( $(this).val(), i );
  });
});

This is the best way for insert Filter for Specific Column.

i - Is Number Of Coulmn.

<th></th> - *Tags number must be equal of Columns.

Comments

0

There is even a very easy way: for those columns you don't want filtering just set the visibility to hidden of <th> in <tfoot> Example:

<th style="visibility: hidden;">Something</th>

Comments

0

The easiest way i had done is by giving searchable to false in columns array. And it works like a charm :sparkle:

columns: [
    {data: 'name', name: 'name'},
    {data: 'description', name: 'description'},
    {data: 'company.name', name: 'company_id'},
    {data: 'status', name: 'status', "searchable": false},
    {data: 'created_at', name: 'created_at'},
    { data: null, name: '',  "searchable": false },
],

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.