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>
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>
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>
I'm using DataTables to create table. One of columns contains 'i' element and hidden input. I would like to filter data rows by that hidden value, but I can't manage to do that. As far I found that problem is in search() method, I suppose it doesn't search in children elements like 'input' in which I'm keeping my value.
Code fragment:
var select = $('<select><option value=""></option><option value="true">Accepted</option><option value="false">Rejected</option></select>')
.appendTo($(column.footer()).empty())
.on('change', function () {
var val = $(this).val();
column.search(val, true, false) // problem is here
.draw(true);
});
Nevermind, I've managed to achieve this on my own. I needed to define "columnDefs" and inside this "targets" which are columns that you want to filter and "render".
Here's the code:
var table = $('#dataCheck').DataTable({
"sDom": "ltp",
"columnDefs": [{
"targets": [6],
"render": function ( data, type, full, meta ) {
if(type === 'filter'){
return $('#dataCheck').DataTable().cell(meta.row, meta.col).nodes().to$().find('input').val();
} else {
return data;
}
}
}],
initComplete: function () {
this.api().columns().every(function (i) {
var column = this;
if (i == 6)
{
var select = $('<select><option value="..."></option><option value="true">Accepted</option><option value="false">Rejected</option></select>')
.appendTo($(column.footer()).empty())
.on('change', function () {
var val = $(this).val();
column.search(val, true, false)
.draw(true);
});
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
}
});
}
});
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;
}
);
});
Update Here is another example, just a few lines of code... the alert pops up twice!
$(document).ready( function ()
{
var x = $('#example').dataTable(
{
fnRowCallback: function( nRow, aData, iDisplayIndex, iDisplayIndexFull )
{
// Row click
$(nRow).on('click', function()
{
alert(aData);
console.log('Row Clicked. Look I have access to all params, thank You closures.', this, aData, iDisplayIndex, iDisplayIndexFull);
});
}
});
x.fnSetColumnVis( 0, false ); //This line of code causes the click to be called twice
});
I am trying to have a jQuery DataTable that I can click. I also need to hide a few columns...
My thought process was this...
Define a javascript variable which I called tb and assign it equal to the jQuery $('mytable').dataTable(...); and then go and use tb to remove the columns I don't need with a method call like this... tb.fnSetColumnVis( 0, false );. The problem is, if I do that, my onclick method gets called multiple times! So I had to comment that out, but now all my columns are visible.
So I need a way to hide columns and also define a click.
var tb = $('#myrecords-table-table').dataTable(
{
fnRowCallback: function( nRow, aData, iDisplayIndex, iDisplayIndexFull )
{
// Row click
$(nRow).on('click', function()
{
$( "#tabsright" ).tabs({ active : 0 });
$("#newrecordform").show();
$("#nr_name").val(aData[2]);
$("#create_ri_reportid").val(aData[0]);
//Update summary field
getSummary(aData);
var i;
var select = document.getElementById("nr_s_actors");
for(i=0;i<select.options.length;i++)
{
select.options[i].selected=false;
}
$("#nr_s_actors").multiselect("refresh");
//Get the actors that are selected
$.ajax(
{
url: 'phpscripts/getreportrelations.php',
data: 'reportid=' + aData[0],
dataType: 'json',
success: function(data)
{
$.each(data,function(index,value)
{
var id="id_actor_"+value[0];
document.getElementById(id).selected = true;
$("#nr_s_actors").multiselect("refresh");
});
},
error: function (header, status, error)
{
console.log('ajax answer post returned error ' + header + ' ' + status + ' ' + error);
}
});
//TODO find out why this is being called multiple times. Most likely because jQuery script is being included multiple times
//TODO find out how to clear the screen
$.ajax(
{
url: 'phpscripts/getreportinstances.php',
data: 'reportid=' + aData[0],
dataType: 'json',
success: function(data)
{
/*while(document.getElementById("current_ris_div").firstNode())
{
document.getElementById("current_ris_div").removeChild(document.getElementById("current_ris_div"));
}*/
for(var y in data)
{
console.log(data[y],"is the y in data");
var element = document.createElement("DIV");
element.name = "reportinstance_"+y;
element.id = "reportinstance_"+y;
element.innerHTML = data[y]['summary']+"<br/>";
element.innerHTML = element.innerHTML + data[y]['location']+"<br/>";
element.innerHTML = element.innerHTML + data[y]['summary']+"<br/>";
for(var x in data[y]['people'])
{
element.innerHTML = element.innerHTML + data[y]['people'][x] +"<br/>";
}
for(var x in data[y]['behavior'])
{
element.innerHTML = element.innerHTML + data[y]['behavior'][x] +"<br/>";
}
for(var x in data[y]['media'])
{
element.innerHTML = element.innerHTML + "<image src=\""+data[y]['media'][x] +"\"/><br/>";
}
document.getElementById("current_ris_div").appendChild(element);
}
/*$.each(data,function(index,value)
{
console.log(data);
var element = document.createElement("DIV");
element.name = "reportinstance_"+index;
element.id = "reportinstance_"+index;
element.innerHTML = value['summary']+"<br/>";
element.innerHTML = element.innerHTML + value['location']+"<br/>";
element.innerHTML = element.innerHTML + value['summary']+"<br/>";
for(var x in value['people'])
{
element.innerHTML = element.innerHTML + value['people'][x] +"<br/>";
}
for(var x in value['behavior'])
{
element.innerHTML = element.innerHTML + value['behavior'][x] +"<br/>";
}
for(var x in value['media'])
{
element.innerHTML = element.innerHTML + "<image src=\""+value['media'][x] +"\"/><br/>";
}
document.getElementById("current_ris_div").appendChild(element);
});*/
},
error: function (header, status, error)
{
console.log('ajax answer post returned error ' + header + ' ' + status + ' ' + error);
}
});
//Now set the media type
var ii;
var selecti = document.getElementById("nr_s_mediatypes");
for(ii=0;ii<selecti.options.length;ii++)
{
selecti.options[ii].selected=false;
}
console.log("What index should I use", aData);
var iidd = "id_mediatype_"+aData[4];
console.log(iidd);
document.getElementById(iidd).selected = true;
$("#nr_s_mediatypes").multiselect("refresh");
});
}
});
//tb.fnSetColumnVis( 0, false );
//tb.fnSetColumnVis( 1, false );
//tb.fnSetColumnVis( 4, false );
I am not sure why this is happening. Your example code is way too long to read.
Use this Plunker as a base for further questions and drop out all of the stuff of your code that does nothing.
As you can see the Plunker works. I did go a step ahead and changed click to bind and also added an unbind (just to be on the safe side, but the script works without it, too)
fnRowCallback: function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
//This is not realy necessary
$(nRow).unbind('click');
$(nRow).bind('click', function() {
alert ('clicked');
});
}
The solution I ended up implementing was using this thing "aoColumns". What I don't understand about jQuery is how we can just thrown things in like "aoColumns" and fnRowCallback all with different syntax! It doesn't make any sense and there are no patterns!
var tb = $('#myrecords-table-table').dataTable(
{
"aoColumns":
[
{"bVisible":false},
{"bVisible":false},
null,
null,
null
],
fnRowCallback: function( nRow, aData, iDisplayIndex, iDisplayIndexFull )
{
// Row click
$(nRow).on('click', function()
{
$( "#tabsright" ).tabs({ active : 0 });
$("#newrecordform").show();
$("#nr_name").val(aData[2]);
$("#create_ri_reportid").val(aData[0]);
...