In my Laravel project, I'm using the datatables where I use the filtering for specific column. But the main problem is that in my dropdown list I want to render the head column name for the specific column. can anyone help me out of this problem on how to get this?
<script>
$(document).ready(function() {
$('#exampletable').DataTable( {
initComplete: function () {
this.api().columns([3,4,5,7]).every( function () {//THis is used for specific column
var column = this;
var select = $('<select><option value="">Specific column Name</option></select>')
// .appendTo( $(column.footer()).empty() )
.appendTo( '#filltertable' )
.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 ) {
var val = $('<div/>').html(d).text();
select.append( '<option value="'+val+'">'+val+'</option>' )
} );
} );
}
} );
} );
</script>
Now I've solve this problem what I actually want's
<script>
$(document).ready(function() {
$('#exampletable').DataTable( {
"ordering": false,
initComplete: function () {
this.api().columns([2,3,4,8]).every( function (d) {//THis is used for specific column
var column = this;
var theadname = $('#exampletable th').eq([d]).text();
var select = $('<select class="mx-1"><option value="'+d+'">'+theadname+': All</option></select>')
.appendTo( '#filtertable' )
.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 ) {
var val = $('<div/>').html(d).text();
select.append( '<option value="'+val+'">'+val+'</option>' )
} );
} );
}
} );
} );
</script>
Related
Using the following code of multi-filtering select inputs in Datatables is it possible to show only available values in the other select inputs upon a selection in one filter? To be more precise, in this example if I select 'Tokyo' as an Office, I would like to populate only the values 'Accountant', 'Integration Specialist', 'Support Engineer' and 'Regional Marketing' in the dropdown menu of Position.
$(document).ready(function() {
$('#example').DataTable( {
initComplete: function () {
this.api().columns([1,2]).every( function () {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).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>' )
} );
} );
}
} );
} );
////// here I get the unique values of each filtered `select` option
$('select').on('change', function () {
var dtable = $('#datatable').DataTable();
var filteredArray = [];
var filteredArray2 = [];
dtable.column(1, { search: 'applied' }).data()
.unique()
.sort()
.each(function (value, index) {
filteredArray.push(value);
});
dtable.column(2, { search: 'applied' })
.data()
.unique()
.sort()
.each(function (value, index) {
filteredArray2.push(value);
});
console.log(filteredArray);
console.log(filteredArray2);
});
In my case I have filters in two columns only as it is shown in the above snippet, so upon selection in one of the two filters I would ideally like to show only available values in the other filter.
Although I have managed to get the unique values of each filter upon a selection I am struggling to hide all the input values that do not exist in the filteredArrays
Here is one approach for doing this.
The end result is as follows:
Building a drop-down which only contains the unfiltered (visible) values of a column is relatively straightforward. At the heart of doing this we use the following:
columns( { search: 'applied' } ).data()[index]
Most of the complexity relates to managing the inter-related states of the two drop-downs. After loading the page, whichever drop-down gets used first is designated as the "primary" drop-down and the other is the "secondary". Whenever the user selects a new value from the primary drop-down, we have to clear the secondary drop-down; and then after the primary drop-down filter has been applied, we have to re-build the secondary drop-down's list of values.
The end result is this:
<script type="text/javascript">
/* Each drop-down selection affects the values in the other drop-downs */
var primaryColIdx;
var secondaryColIdx;
$(document).ready(function() {
$('#example').DataTable( {
initComplete: function () {
populateDropdowns(this);
}
} );
} );
function populateDropdowns(table) {
table.api().columns([1,2]).every( function () {
var column = this;
//console.log("processing col idx " + column.index());
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function () {
var dropdown = this;
doFilter(table, dropdown, column);
rebuildSecondaryDropdown(table, column.index());
} );
column.data().unique().sort().each( function ( val, idx ) {
select.append( '<option value="' + val + '">' + val + '</option>' )
} );
} );
}
function doFilter(table, dropdown, column) {
// first time a drop-down is used, it becomes the primary. This
// remains the case until the page is refreshed:
if (primaryColIdx == null) {
primaryColIdx = column.index();
secondaryColIdx = (primaryColIdx == 1) ? 2 : 1;
}
if (column.index() === primaryColIdx) {
// reset all the filters because the primary is changing:
table.api().search( '' ).columns().search( '' );
}
var filterVal = $.fn.dataTable.util.escapeRegex($(dropdown).val());
//console.log("firing dropdown for col idx " + column.index() + " with value " + filterVal);
column
.search( filterVal ? '^' + filterVal + '$' : '', true, false )
.draw();
}
function rebuildSecondaryDropdown(table, primaryColIdx) {
var secondaryCol;
table.api().columns(secondaryColIdx).every( function () {
secondaryCol = this;
} );
// get only the unfiltered (unhidden) values for the "other" column:
var raw = table.api().columns( { search: 'applied' } ).data()[secondaryColIdx];
// the following uses "spread syntax" (...) for sorting and de-duping:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
var uniques = [...new Set(raw)].sort();
var filteredSelect = $('<select><option value=""></option></select>')
.appendTo( $(secondaryCol.footer()).empty() )
.on( 'change', function () {
var dropdown = this;
doFilter(table, dropdown, secondaryCol);
//rebuildSecondaryDropdown(table, column.index());
} );
uniques.forEach(function (item, index) {
filteredSelect.append( '<option value="' + item + '">' + item + '</option>' )
} );
}
</script>
I am trying to make two functions work together that both work on their own.
Number 1: Is my table with a dropdown filter inside a control panel which I am trying to add a secondary checkbox filter to, everything works fine here.
http://jsfiddle.net/btofjkus/12/
$(document).ready(function () {
$('#example').DataTable({
ordering: false,
bLengthChange: false,
initComplete: function () {
this.api().columns(2).every(function () {
var column = this;
var select = $('<select><option value="">Show all</option></select>')
.appendTo($("#control-panel").find("div").eq(1))
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val());
column.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
console.log(select);
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
}
});
console.log()
});
Number 2: Is an example I found online of filtering a DataTable with a button as you can see it works on its own but I am trying to change it slightly from a button to a checkbox so the filter can be released once it is unchecked.
You will have noticed the checkbox I made for this in Number 1. #checkbox-filter.
https://jsfiddle.net/annoyingmouse/ay16vnp1/
$(function () {
var dataTable = $('#example').DataTable({
searching: true,
info: false,
lengthChange: false
});
$('#filterButton').on('click', function () {
dataTable.draw();
});
});
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var target = 'Software Engineer';
var position = data[1]; // use data for the age column
if (target === position){
return true;
}
return false;
}
);
Now you can see the two functions I am trying to put all this together into one table (Number 1) at http://jsfiddle.net/btofjkus/12/.
What I want to do is create a checkbox filter for "Software Engineers" from the "Position" column in Number 1.
This looks complicated when I write it down with all these codeblocks but it's really just merging two functions together in the correct way.
I have tried tearing the code apart myself and gluing it together but everything I try seems to be wrong.
Example: (failure)
$(document).ready(function () {
$('#example').DataTable({
ordering: false,
bLengthChange: false,
initComplete: function () {
this.api().columns(2).every(function () {
var column = this;
var select = $('<select><option value="">Show all</option></select>')
.appendTo($("#control-panel").find("div").eq(1))
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val());
column.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
console.log(select);
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
}
});
console.log()
});
$(document).ready(function() {
if $('#checkbox-filter').is(':checked' function() {
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var target = 'Software Engineer';
var position = data[1]; // use data for the age column
if (target === position){
return true;
}
return false;
}
);
});
});
As you can see above I tried mashing the code together with no luck, I have also tried some methods that seem to invoke the function but not when #checkbox-filter is checked.
The example below makes the dropdown filter only select "Software Engineers" from the "Position" column which is my criteria for this checkbox filter (but only when its checked).
$(document).ready(function () {
$('#example').DataTable({
ordering: false,
bLengthChange: false,
initComplete: function () {
this.api().columns(2).every(function () {
var column = this;
var select = $('<select><option value="">Show all</option></select>')
.appendTo($("#control-panel").find("div").eq(1))
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val());
column.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
console.log(select);
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
}
});
console.log()
});
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var target = 'Software Engineer';
var position = data[1]; // use data for the position column
if (target === position){
return true;
}
return false;
}
);
How can I make this work only when the checkbox is selected. And release when it is deselected.
UPDATE:
This kind of works but not as it should (once checked try interacting with the dropdown filter) you will see it kind of works, but it doesn't change back when it is unchecked, it also does not filter the visible data when checked meaning I have to interact with the dropdown menu to see results. How can I fix this?
http://jsfiddle.net/btofjkus/13/
$(document).ready(function () {
$('#example').DataTable({
ordering: false,
bLengthChange: false,
initComplete: function () {
this.api().columns(2).every(function () {
var column = this;
var select = $('<select><option value="">Show all</option></select>')
.appendTo($("#control-panel").find("div").eq(1))
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val());
column.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
console.log(select);
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
}
});
console.log()
});
//changes below
$('#checkbox-filter').change(function() {
if ($(this).is(':checked')) {
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var target = 'Software Engineer';
var position = data[1]; // use data for the position column
if (target === position){
return true;
}
return false;
}
);
}
});
Here is the working solution jsfiddle
$(document).ready(function () {
var dataTable = $('#example').DataTable({
ordering: false,
bLengthChange: false,
initComplete: function () {
this.api().columns(2).every(function () {
var column = this;
var select = $('<select><option value="">Show all</option></select>')
.appendTo($("#control-panel").find("div").eq(1))
.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>')
});
});
}
});
$('#checkbox-filter').on('change', function() {
dataTable.draw();
});
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var target = 'Software Engineer';
var position = data[1]; // use data for the age column
if($('#checkbox-filter').is(":checked")) {
if (target === position) {
return true;
}
return false;
}
return true;
}
);
});
Please give me a piece of advice.
I'm trying to write a function from 2 similar functions by combining its common parts.
From these 2 functions, I'd like to get "selected1" & "selected2", and use these value in the next function, calc.
var selected;
var selected1;
var selected2;
$( '.type1' ).bind('change', function () {
var values = [];
$( 'input.type1:checkbox:checked' ).each(function ( _, el ) {
values.push( base64decode( $( el ).data( 'val' ) ) );
if ( values.length > 1 ) {
values[0] = $.map(values[0], function (val, i) {
return values[0][i] | values[1][i];
});
values.splice(1,1);
}
});
selected1 = result;
calc();
});
$( '.type2' ).bind('change', function () {
var values = [];
$( 'input.type2:checkbox:checked' ).each(function ( _, el ) {
values.push( base64decode( $( el ).data( 'val' ) ) );
if ( values.length > 1 ) {
values[0] = $.map(values[0], function (val, i) {
return values[0][i] | values[1][i];
});
values.splice(1,1);
}
});
selected2 = result;
calc();
});
function calc () {
var selected3 = $.map(selected1, function (val, i) {
return selected1[i] & selected2[i];
});
selected = base64encode( selected3 );
overlays();
};
When I write as above, both selected1&2 are defined as global variables, so function calc works.
However, it doesn't work on my rewrite code. The firebug says "TypeError: a is undefined".
Here is my code:
function tab (checkedTab, selected) {
var values = [];
checkedTab.each(function ( _, el ) {
values.push( base64decode ($( el ).data( 'val' ) ) );
if ( values.length > 1 ) {
values[0] = $.map(values[0], function (val, i) {
return values[0][i] | values[1][i];
});
values.splice(1,1);
}
});
selected = values[0];
};
$( '.type1' ).bind('change', function () {
tab ($( 'input.type1:checkbox:checked' ), 'selected1');
calc();
});
$( '.type2' ).bind('change', function () {
tab ($( 'input.type2:checkbox:checked' ), 'selected2');
calc();
});
Could someone please tell me why my code doesn't work?
Thank you very much for your comments, Peter.
After debugging variables, it finally works!
This may not be the best way, but I will post my rewrite code as reference.
var values;
function tab (checkedTab) {
values = [];
checkedTab.each(function ( _, el ) {
values.push( base64decode ($( el ).data( 'val' ) ) );
if ( values.length > 1 ) {
values[0] = $.map(values[0], function (val, i) {
return values[0][i] | values[1][i];
});
values.splice(1,1);
}
});
return values[0];
};
$( '.type1' ).bind('change', function () {
selected1 = tab ($( 'input.type1:checkbox:checked' ));
calc();
});
$( '.type2' ).bind('change', function () {
selected2 = tab ($( 'input.type2:checkbox:checked' ));
calc();
});
The functionality for select options for all the columns as mentioned on the website of data tables is mentioned below. How do i make it filter the table data on the drop down values of the first column only and also place the select drop down somewhere else rather than the usual header section.see link for example
initComplete: function () {
var api = this.api();
api.column().indexes().flatten().each( function (i) {
var column = api.column(i);
var select = $('<select><option value=""></option></select>').appendTo('$selectTriggerFilter').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>' )
} );
} );
}
I am using the following code . As soon as i remove the dom options the select options appear but not without dom.
$(document).ready(function() {
$('#tableTrigger').DataTable({
"lengthMenu": [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"] ],
searching: false,
"scrollY": "200px",
"dom": 'frtipS',
"deferRender": true,
initComplete: function ()
{
var api = this.api();
api.columns().indexes().flatten().each( function ( i )
{
if(i == 0){ //Create just one SelectBox
var select = $('<select class='+i+'><option value=""></option></select>')
.appendTo( '#selectTriggerFilter')
.on( 'change', function () {
var val = $(this).val();
column( i ).search( val ? '^'+$(this).val()+'$' : val, true, false ).draw();
});
column( i ).data().unique().sort().each( function ( d, j ) {
select.append( '<option value="'+d+'">'+d+'</option>' );
} );
}
else return;
});
}
});
});
CAUSE
There are some problems with your code:
searching should not be set to false otherwise search() function will not work
column variable is not defined
SOLUTION
Below is corrected code.
$(document).ready(function() {
$('#tableTrigger').DataTable({
"lengthMenu": [
[10, 25, 50, 100, -1],
[10, 25, 50, 100, "All"]
],
"scrollY": "200px",
"dom": 'rtipS',
// searching: false,
"deferRender": true,
initComplete: function () {
var column = this.api().column(0);
var select = $('<select class="filter"><option value=""></option></select>')
.appendTo('#selectTriggerFilter')
.on('change', function () {
var val = $(this).val();
column.search(val ? '^' + $(this).val() + '$' : val, true, false).draw();
});
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>');
});
}
});
});
Notes
I have omitted f in "dom": 'frtipS' since I think you wanted to exclude that initially by setting searching to false. Include f if you want to have search box along with the drop-down filter.
There is no sense in setting lengthMenu if you're omitting l in dom property.
DEMO
See this jsFiddle for demonstration of corrected code.
You can place search section anywhere in the dom. then your event call (click, select, keyup). call serach api like below.
var dTable= $("example").DataTable();
dTable.columns(i).search(v).draw();
Here i is your datatable column index and v is the search value.
Right, this may be something obvious but being new to jquery/javascript it's confusing me. I'm going through tutorials (the code for the bit that isn't working is jsfiddle.net/wqbd6qeL ). But it's not working for me. Now my html is similar/identical to his to my eyes. I'm pretty sure my problem is how I've attempted to implement his code. The javascript is running, as is the css that highlights. Have I implemented the below correctly? (the var = table bit).
Oh! and the condition (== "Fail") I've tested a few different ways. With not equal etc. But it never highlights anything : (. But the css is definitely being reached.
<script>
//listTable
var lt = $(document).ready(function () {
$('#listTable').DataTable({
initComplete: function () {
var api = this.api();
api.columns().indexes().flatten().each(function (i) {
var column = api.column(i);
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).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>')
});
});
}
});
$('#addbtn').click(addRow);
});
//no idea why this is not working??
var table = $('#listTable').DataTable({
fnRowCallback: function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (aData[2] == "Fail") {
$(nRow).addClass('highlight');
}
}
});
</script>
you should put the block under your comment
//no idea why this is not working??
inside the function
var lt = $(document).ready(function () {....}));
In fact you can just copy
fnRowCallback: function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (aData[2] == "Fail") {
$(nRow).addClass('highlight');
}
}
in front of the line
initComplete: function () {
and remove everything below your comment .. dont forget to add a comma after fnRowCallback.
Hope this is what you want.
EDIT:
here is the final result:
<script>
//listTable
var lt = $(document).ready(function () {
$('#listTable').DataTable({
fnRowCallback: function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
if (aData[2] == "Fail") {
$(nRow).addClass('highlight');
}
},
initComplete: function () {
var api = this.api();
api.columns().indexes().flatten().each(function (i) {
var column = api.column(i);
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).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>')
});
});
}
});
$('#addbtn').click(addRow);
});
</script>