Datatables - Search in Multiple Columns With a Single Drop Down

DataTables - Search in multiple columns with a single drop down

Lets summarize all things here. It will help other people as well.

You can achieve this as follow:

table.column(4).search(this.value).column(5).search(this.val‌​ue).draw();

It will perform search on 4 column (4 is index of column), after that it will filter data from 5 column against provided filter value and at the end it will draw the table.

One thing to keep in mind is that Filter is applied on both columns, so both columns must contains matching data.

Here is its filddle


This can be achieved by using fnMultiFilter as it documentation explains:

This plug-in adds to DataTables the ability to set multiple column filtering terms in a single call (particularly useful if using server-side processing). Used in combination with the column sName parameter, simply pass in an object with the key/value pair being the column you wish to search on, and the value you wish to search for.

Multiple column filtering in a single dropdown in DataTables

This JS:

$(document).ready(function() {
var table = $('#example').DataTable();
$('select[name="filter"]').change(function() {
if (!$(this).val()) {
table.columns().search("").draw();
} else {
table.columns().search("");
var option = $(this).find(":selected");
var columns = Object.keys(option.data());
console.log(columns)
$.each(columns, function(k, v){
table.columns(parseInt(v, 10)).search(option.data(v));
});
table.draw();
}
});
});

With this HTML:

<select name="filter">
<option value="">No filter</option>
<option data-1="Accountant">Filter Accountant</option>
<option data-2="Tokyo">Filter Tokyo</option>
<option data-1="Accountant" data-2="Tokyo">Filter Accountant in Tokyo</option>
</select>

Should do what you need. We iterate over the data attributes of the selected option and search the relevant column. Working JSFiddle here.

Hope that helps.

Data table specific column filter with multi select drop down

After long search, I found a solution for this. Actually it was very simple. Below is my fix for this option.

There was already an option to search for specific column vise as per the below link,

http://www.datatables.net/examples/api/multi_filter.html


// DataTable
var table = $('#example').DataTable();

// 2 is column id
// "India" is search string
table.column( 2 ).search( 'India' ).draw();

So the above one will search for "India" in a specific column "2" (Say like "Country" column)

Here i need an ability to search for more than one country like "India, Japan etc.,"

So the code will be as follows,

// DataTable
var table = $('#example').DataTable();

// 2 is column id
// "India|Japan|Spain" is search string
table.column( 2 ).search( 'India|Japan|Spain', true, false ).draw();

Updated: We need to add two more parameters in the "search()"
function.

        
search(val_1,val_2,val_3)

where,
val_1 is search string with "|" symbol separated. So it contains regular express chars as per the example.
val_2 is true (To enable regular express in the search)
val_3 is false (To disable smart search. default is true)

Ref: https://datatables.net/reference/api/search()

So I have just added a "pipe" symbol between the search strings.

How to display more than one filter drop-down in the data table?

HTML

$(document).ready(function() {    $('#list').DataTable( {        initComplete: function () {            this.api().columns("4").every( function () {                var column = this;                var select = $('<select><option value=""></option></select>')                    .appendTo( $("#role_menu_placeholder").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>' )                } );            } );                  this.api().columns("5").every( function () {                var column = this;                var select = $('<select><option value=""></option></select>')                    .appendTo( $("#status_menu_placeholder").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>' )                } );            } );        }    } );} );
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css"><div class="body_wrapper">  <div class="pad0 m_b_20">  <div>  <label>Role: </label>  <span id="role_menu_placeholder"></span>  </div>  <div>  <label>Status: </label>    <span id="status_menu_placeholder"></span>  </div>    <div class="e_list">      <table cellspacing="0" id="list">        <thead>          <tr>            <th>Sr.no</th>            <th> Employee Name </th>            <th> Mobile No. </th>            <th> Designation </th>            <th> Role </th>            <th> Status </th>          </tr>        </thead>        <tbody>          <tr>            <td>1</td>            <td>mnbv vfgds</td>            <td>asdf</td>            <td>789654120</td>            <td>Leader</td>            <td>Admin</td>          </tr>
<tr> <td>2</td> <td>poijh</td> <td>asdfasd</td> <td>789145220</td> <td>Employee</td> <td>CSR</td> </tr> </tbody> <tfoot> <tr> <th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th> </tr> </tfoot> </table>
</div> </div> <div class="btn_container "> </div></div><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>

Show dropdown Filter with single value in the datatables

The following approach builds a select list (a drop-down) from the contents of the first column.

For each cell in that column, it splits the comma-separated items into separate pieces of text, and then creates a sorted, unique list for the drop-down.

When you search by selecting an item from the drop-down, it checks if the selected item is contained anywhere in the text of each cell in that column. It uses a custom DataTables filter for this.

In my case, I placed the drop-down in the footer of the table - you can change that.

The table looks like this:

Sample Image

And here is the drop-down:

Sample Image

When an item is selected from the drop-down, you can see the filtering in effect:

Sample Image

The code for this solution is as follows - I have split it up into separate sections/functions to try to make the structure and approach clearer:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>

<body>

<div style="margin: 20px;">

<table id="example" class="display dataTable cell-border" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger , John, Nixon , </td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
</tr>
<tr>
<td>John, Garrett , Winters , </td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton, Winters , Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric , Kelly , Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>$433,060</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>

</div>

<script type="text/javascript">

$(document).ready(function() {

// the DataTable object:
var table = $('#example').DataTable( {
select: false // or, whatever you need in here.
} );

// Setup - add a select list to first footer cell:
$('#example tfoot th').slice(0, 1).each( function () {
var dropdown = buildDropdown();
$(this).html( dropdown );
} );


// add a change event to the select list:
$('#mySelect').change(function() {
table.draw();
});


// create a custom search function for the select list,
// which finds if the selected item is contained in the cell:
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var selectedValue = $('#mySelect').val();
console.log(selectedValue);
if (data[0].includes(selectedValue)) {
return true;
} else {
return false;
}
}
);


function buildDropdown() {
var selectHtml;
// this will hold array of distinct values:
var items = [];
table.columns([0]).data().each(function (data, index) {
data.forEach(function (newItems, index) {
newItems.split(',').forEach(function (newItem, index) {
if ( newItem.trim() !== '' && items.indexOf(newItem) === -1) {
items.push(newItem.trim());
}
});
});
});
// sort and remove duplicates:
var uniqueSortedItems = [...new Set(items)].sort();

selectHtml = '<select id="mySelect"><option value=""></option>';
uniqueSortedItems.forEach(function(item) {
selectHtml = selectHtml + '<option value="' + item + '">' + item + '</option>';
});
selectHtml = selectHtml + '</select>';

return selectHtml;
}


} );

</script>

</body>
</html>

I think this is what you are trying to achieve - but you will need to integrate this into your specific solution, of course.

You will also need to decide what you want to do about the global search function (if you are using it), because it may interfere with the custom search used for the first column.

Datatables with column filter dropdowns and multiple checkbox selection

Try this, which doesn't use any extra JS/jQuery libraries:

// This code has been beautified via http://jsbeautifier.org/ with 2 spaces indentation.
$(document).ready(function() {
function cbDropdown(column) {
return $('<ul>', {
'class': 'cb-dropdown'
}).appendTo($('<div>', {
'class': 'cb-dropdown-wrap'
}).appendTo(column));
}

$('#example').DataTable({
initComplete: function() {
this.api().columns().every(function() {
var column = this;
var ddmenu = cbDropdown($(column.header()))
.on('change', ':checkbox', function() {
var active;
var vals = $(':checked', ddmenu).map(function(index, element) {
active = true;
return $.fn.dataTable.util.escapeRegex($(element).val());
}).toArray().join('|');

column
.search(vals.length > 0 ? '^(' + vals + ')$' : '', true, false)
.draw();

// Highlight the current item if selected.
if (this.checked) {
$(this).closest('li').addClass('active');
} else {
$(this).closest('li').removeClass('active');
}

// Highlight the current filter if selected.
var active2 = ddmenu.parent().is('.active');
if (active && !active2) {
ddmenu.parent().addClass('active');
} else if (!active && active2) {
ddmenu.parent().removeClass('active');
}
});

column.data().unique().sort().each(function(d, j) {
var // wrapped
$label = $('<label>'),
$text = $('<span>', {
text: d
}),
$cb = $('<input>', {
type: 'checkbox',
value: d
});

$text.appendTo($label);
$cb.appendTo($label);

ddmenu.append($('<li>').append($label));
});
});
}
});
});

CSS

/* Styles for the drop-down. Feel free to change the styles to suit your website. :-) */

.cb-dropdown-wrap {
max-height: 80px; /* At most, around 3/4 visible items. */
position: relative;
height: 19px;
}

.cb-dropdown,
.cb-dropdown li {
margin: 0;
padding: 0;
list-style: none;
}

.cb-dropdown {
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
overflow: hidden;
background: #fff;
border: 1px solid #888;
}

/* For selected filter. */
.active .cb-dropdown {
background: pink;
}

.cb-dropdown-wrap:hover .cb-dropdown {
height: 80px;
overflow: auto;
transition: 0.2s height ease-in-out;
}

/* For selected items. */
.cb-dropdown li.active {
background: #ff0;
}

.cb-dropdown li label {
display: block;
position: relative;
cursor: pointer;
line-height: 19px; /* Match height of .cb-dropdown-wrap */
}

.cb-dropdown li label > input {
position: absolute;
right: 0;
top: 0;
width: 16px;
}

.cb-dropdown li label > span {
display: block;
margin-left: 3px;
margin-right: 20px; /* At least, width of the checkbox. */
font-family: sans-serif;
font-size: 0.8em;
font-weight: normal;
text-align: left;
}

/* This fixes the vertical aligning of the sorting icon. */
table.dataTable thead .sorting,
table.dataTable thead .sorting_asc,
table.dataTable thead .sorting_desc,
table.dataTable thead .sorting_asc_disabled,
table.dataTable thead .sorting_desc_disabled {
background-position: 100% 10px;
}

Demo

https://jsfiddle.net/41vgefnf/1/

https://jsfiddle.net/41vgefnf/6/

https://jsfiddle.net/41vgefnf/8/

https://jsfiddle.net/41vgefnf/9/

https://jsfiddle.net/41vgefnf/10/

UPDATE

I moved the filter dropdowns to the header, and styled the dropdowns to look more like dropdown menus. (No JS or jQuery involved in the dropdown functionality; just pure CSS with basic animation — CSS3 transition.)

UPDATE #2

Sorry, I forgot apply the CSS "active" class to selected items.

UPDATE #3

Same like Update #2 case, but for the dropdown menu wrapper. (Sorry for keep forgetting things.. and I edited just to conform/meet to the requirements/changes you've actually requested. :) But I think this update would be the final revision.)

UPDATE #4

Fixed the "active" state change of the dropdown menu wrapper.

CREDITS

Thank you @Giacomo for your Fiddle. =)

Data table specific column filter with multi select drop down

After long search, I found a solution for this. Actually it was very simple. Below is my fix for this option.

There was already an option to search for specific column vise as per the below link,

http://www.datatables.net/examples/api/multi_filter.html


// DataTable
var table = $('#example').DataTable();

// 2 is column id
// "India" is search string
table.column( 2 ).search( 'India' ).draw();

So the above one will search for "India" in a specific column "2" (Say like "Country" column)

Here i need an ability to search for more than one country like "India, Japan etc.,"

So the code will be as follows,

// DataTable
var table = $('#example').DataTable();

// 2 is column id
// "India|Japan|Spain" is search string
table.column( 2 ).search( 'India|Japan|Spain', true, false ).draw();

Updated: We need to add two more parameters in the "search()"
function.

        
search(val_1,val_2,val_3)

where,
val_1 is search string with "|" symbol separated. So it contains regular express chars as per the example.
val_2 is true (To enable regular express in the search)
val_3 is false (To disable smart search. default is true)

Ref: https://datatables.net/reference/api/search()

So I have just added a "pipe" symbol between the search strings.



Related Topics



Leave a reply



Submit