How to get current rendered element in datatables - javascript

I need to change rendering of cell based on the element position, without changing data,
In docs I found mData and mRender options, I tried with fnRender (which is depricated), but it gives me position, but changes data in table while rendering, so I wonder if here is any way to get the cell position when it renders, or I should to rerender table myself after each change ?
the following code illustrate my needs:
$(document).ready( function() {
var oTable = $('#example').dataTable( {
"aoColumnDefs": [ {
"aTargets": ['_all'],
"mRender": function ( data, type, full )
{
if (type!='display') return data;
//HOW to get current cell indexes or DOM element here ?
console.log(this,data,type,full);
return data+' ttt';
}
} ]
} );
$('#example > tbody > tr').on('click','td',function() {
console.log(this);
var pos=oTable.fnGetPosition(this);
var value=oTable.fnGetData(this);
oTable.fnUpdate(value.split("").reverse().join(""),pos[0],pos[2]);
});
var button=$('<button>').text('clickme');
button.click(function() { console.log(oTable.fnGetData());});
$('body').append(button);
});
http://live.datatables.net/enirid/3/edit
the sample using fnRender:
$(document).ready( function() {
var oTable = $('#example').dataTable( {
"aoColumnDefs": [ {
"aTargets": ['_all'],
"fnRender": function ( obj, data )
{
console.log(obj,data);
var col=obj.iDataColumn;
//HOW to change display here without changing data of table
return data+' '+col;
}
} ]
} );
$('#example > tbody > tr').on('click','td',function() {
console.log(this);
var pos=oTable.fnGetPosition(this);
var value=oTable.fnGetData(this);
oTable.fnUpdate(value.split("").reverse().join(""),pos[0],pos[2]);
});
var button=$('<button>').text('clickme');
button.click(function() { console.log(oTable.fnGetData());});
$('body').append(button);
});
http://live.datatables.net/opubaj/edit

Try fnCreatedCell.
Attached the example code snippet provided from datatables.net:
$(document).ready( function() {
$('#example').dataTable( {
"aoColumnDefs": [ {
"aTargets": [3],
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
if ( sData == "1.7" ) {
$(nTd).css('color', 'blue')
}
}
} ]
});
} );

Related

How to make a specific search field uppercase?

I'm using an 'Individual column searching' as specified in DataTables' documentation.
What I want to accomplished is to make the second search field (located below the column) value UPPERCASE as the user types a date.
Here's my .js file:
$(document).ready(function() {
// Setup - add a text input to each footer cell
$('#example tfoot th').each( function () {
var title = $(this).text();
$(this).html( '<input type="text" placeholder="Search '+title+'" />' );
} );
// DataTable
var table = $('#example').DataTable({
/*More Code*/
columnDefs: [
{ targets: 0, visible: false },
{ targets: 1, render: $.fn.dataTable.render.moment( 'D-MMM-YY' ) }
],
columns: [
{ /* DATA */},
{ data: "logEntryTime" },
{ /* DATA */},
{ /* DATA */},
{ /* DATA */},
{ /* DATA */},
]
/*More Code*/
});
// Apply the search
table.columns().every( function () {
var that = this;
$( 'input', this.footer() ).on( 'keyup change', function () {
if ( that.search() !== this.value ) {
that
.search( this.value )
.draw();
}
} );
} );
} );
Any ideas?
One simple way to do this is to use css.
text-transform: uppercase;
However, that only changes the appearance of the text. If you need to change the value of the text, then you would use some JS.
input.value.toUpperCase()

Multiple Initialization After Destruction

I have a function that creates an instance of DataTables and for some reason it initializes n-times after destruction. I only noticed this because I add custom fields on init and they were multiplying. I could prevent that but that only deals with the symptom.
To clarify, after I "destroy: the instance and reinitialize it, to change the data source, if it's the second time it initializes twice. Three times if it's the 3rd time, etc.
I speculate that the table variable is part of the closure formed by the function because even if I set table = null the same thing happens.
How can I prevent this?
DataTables Function
/*Create a DataTable on tableElementID using pageUrl as the source*/
function ajaxLoadTable ( pageUrl, tableElementID ) {
window.table = $(tableElementID)
.on( 'init.dt', function () {
//The success function is used internally so it should NOT be overwritten, have to listen for this event instead
//Add our custom fields _length refers to an element generated datatables
if ( additionalElements.saveButton ) {
$(tableElementID + '_length').after('<div class="dataTables_filter"><button>Save All Edits</button></div>');
}
if ( additionalElements.selectState ) {
$(tableElementID + '_length').after('<div class="dataTables_filter"><label>Project State: <select name="projectState" style="width:auto;"><option>Select ...</option><option value="Active">Active</option><option value="Historical">Historical</option></select></label></div>');
}
if ( additionalElements.searchBox ) {
$(tableElementID + '_length').after('<div class="dataTables_filter"><label>Search:<input type="search" id="customSearch" style="width:auto;"></label></div>');
}
})
.DataTable({
"processing": true,
"serverSide": true,
"ajax":{
type: "POST",
url: pageUrl,
data: function ( additionalData ) {
$('.serverData').each( function( index, element ){
if( element.nodeName === "SELECT"){
additionalData[element.name.toUpperCase()] = element.options[element.selectedIndex].value;
return true; //return true is equivalent to continue for $.each
}
additionalData[element.name.toUpperCase()] = element.value;
});
},
dataType: "json"
},
"pageLength": 4,
"lengthMenu": [ 4, 8, 12, 16, 24 ],
"searchDelay": 1500,
"columnDefs":
{ "targets": 0,
"orderable": false,
"data": {
"_": "display"
}
}
});
}
Destruction Function
/*Load the selected project state*/
$('html').on( 'change' , '[name=projectState]' ,function(){
var currentState = $('option:selected', this).val();
$('#projectState').val(currentState);
//Remove the old table records and the datatables. Order matters, otherwise there is unsual behavior.
if( $.fn.DataTable.isDataTable( '#searchTable' ) ) {
window.table.destroy();
window.table = null;
}
$('.projectStateText').html( currentState );
//Get the new table records
ajaxLoadTable( *some undisclosed URL*, '#searchTable');
});

Search within input and select

I have a datatable set up in an application where the rows contain input fields and I have sort and filter the tables based on the text values of the input fields. I managed to get sorting working correctly but I cannot for the life of me get search to work. I think the problem is related to the fact that the table is generated and populated dynamically by another JavaScript that runs prior to datatables being called on it.
Here is the JavaScript so far:
/* Create an array with the values of all the input boxes in a column */
$.fn.dataTable.ext.order["dom-text"] = function ( settings, col )
{
return this.api().column( col, {order:"index"} ).nodes().map( function ( td, i ) {
return $("input", td).val();
} );
}
/* Create an array with the values of all the input boxes in a column, parsed as numbers */
$.fn.dataTable.ext.order["dom-text-numeric"] = function ( settings, col )
{
return this.api().column( col, {order:"index"} ).nodes().map( function ( td, i ) {
return $("input", td).val() * 1;
} );
}
/* Create an array with the values of all the select options in a column */
$.fn.dataTable.ext.order["dom-select"] = function ( settings, col )
{
return this.api().column( col, {order:"index"} ).nodes().map( function ( td, i ) {
return $("select", td).val();
} );
}
$(document).ready(function() {
var table = $("#service_group0").DataTable({
"searching": true,
"ordering": true,
"columns": [
{ "orderDataType": "dom-text", type: \'html\' },
{ "orderDataType": "dom-select",type: \'html\' },
{ "orderDataType": "dom-text" , type: \'string\'},
{ "orderDataType": "dom-text", type: \'string\' },
{ "orderDataType": "dom-text", type: \'string\'},
{ "orderDataType": "dom-select" },
{ "orderDataType": "dom-select" },
{ "orderDataType": "dom-text-numeric"},
{ "orderDataType": "dom-text", type: \'date\'},
null,
{ "orderDataType": "dom-select" },
{ "orderDataType": "dom-text-numeric"},
{ "orderDataType": "dom-select" },
{ "orderDataType": "dom-text", type: \'string\' },
{ "orderDataType": "dom-text", type: \'string\' },
{ "orderDataType": "dom-text", type: \'date\'},
null,
null
],
initComplete: function () {
this.api().columns().every( function () {
var column = this;
if(column.index() == 5){
var select = $("<select id=\'strength_search\'></select>")
.appendTo( $(column.footer()).empty());
var strength_hidden = document.getElementById("strength_hidden").value;
select.append(strength_hidden);
}
else if(column.index() == 6){
var select = $("<select id=\'dose_search\'></select>")
.appendTo( $(column.footer()).empty());
var dose_hidden = document.getElementById("dose_hidden").value;
select.append(dose_hidden);
}
});
}
});
There is simply to much html to paste here so I have created a jsfiddle: http://jsfiddle.net/q715LncL/12/
If you go to the jsfiddle and type stuff into the empty text fields then go to the search box and try to filter based on something you typed in it always returns no results. How can I get it to filter on the changes made to the live inputs?
You need to add a custom filter function that checks the values of the input boxes, DataTables converts the HTML to strings and you can't recover the live value from them, so you would have to do something like this:
$.fn.dataTable.ext.search.push(
function( settings, data, dataIndex ) {
var searchTerm = $('.dataTables_filter input').val();
var $row = $('.dataTable tbody tr').eq(dataIndex);
if(!searchTerm) {
return true;
}
return $row.find('td input').filter(function() {
return ~$(this).val().toLowerCase().indexOf(searchTerm.toLowerCase())
}).size();
}
);
http://jsfiddle.net/q715LncL/14/
SOLUTION
You can use columnDefs to target a specific column using zero-based index in targets option and render to return selected value during searching (type === 'filter') or sorting (type === 'order').
columnDefs: [
{
targets: [0,1,2,3,4,5,6],
render: function(data, type, full, meta){
if(type === 'filter' || type === 'sort'){
var api = new $.fn.dataTable.Api(meta.settings);
var td = api.cell({row: meta.row, column: meta.col}).node();
data = $('select, input', td).val();
}
return data;
}
}
]
Also you need to invalidate cell data once data changes as shown below (according to this solution).
$('tbody select, tbody input', table.table().node()).on('change', function(){
table.row($(this).closest('tr')).invalidate();
});
DEMO
See this jsFiddle for code and demonstration.
NOTES
I have commented code that causes JavaScript errors because of the non-existing elements.

How add more then one button in each row in JQuery datatables and how to apply event on them

I have one button but I need two buttons and perform some MySql when they are clicked to get data from the underlying database.
How can I perform an event using these two buttons?
$(document).ready(function () {
var table= $('#example').dataTable( {
"ajax": "..//wp-content/plugins/jobify/Admin/data.txt",
"columnDefs": [ {
"targets": -1,
"data": null,
"defaultContent": "<button>View Posted Jobs</button>"
} ]
} );
$('#example tbody').on( 'click', 'button', function () {
//var data = table.row( $(this).parents('tr') ).data();
} );
} );
Just assign a class to each button and attach an event handler to each class.
$(document).ready(function () {
var table = $('#example').dataTable( {
"ajax": "../wp-content/plugins/jobify/Admin/data.txt",
"columnDefs": [ {
"targets": -1,
"data": null,
"defaultContent":
'<button class="btn-view" type="button">View Posted Jobs</button>'
+ '<button class="btn-delete" type="button">Delete</button>'
} ]
} );
// Handle click on "View" button
$('#example tbody').on('click', '.btn-view', function (e) {
//var data = table.row( $(this).parents('tr') ).data();
} );
// Handle click on "Delete" button
$('#example tbody').on('click', '.btn-delete', function (e) {
//var data = table.row( $(this).parents('tr') ).data();
} );
});

Call fnServerData in DataTables 1.10

So I'm looking at this example and am trying to make it work for me.
I want to add the select options to my table when I use server side processing. Since I have only used version 1.10 I always get confused when I see this old API.
I don't understand how I can use this function in 1.10:
"sAjaxSource": "../examples_support/server_processing.php",
"fnServerData": function ( sSource, aoData, fnCallback ) {
/* ... additional variables ... */
$.getJSON( sSource, aoData, function (json) {
/* Create the select elements on the first run */
if ( json.sEcho == 1 )
{
$("tfoot th").each( function (i) {
/* Insert the select menu */
this.innerHTML = fnCreateSelect(json.select[i]);
/* Add the event listener for the newly created element */
$('select', this).change( function () {
oTable.fnFilter( $(this).val(), i );
} );
} );
}
/* DataTables callback */
fnCallback(json)
} );
}
The converting guide just lists fnServerData as ajax.
This is my initialization code:
$('#dataTables-outputTest').DataTable({
"processing": true,
"serverSide": true,
"ajax": "/TestData/data-source",
"columns": [
{ "data": "thing1",
"searchable": true},
{ "data": "thing2",
"searchable": true},
...
{ "data": "link",
"searchable": false,
"orderable": false},
],
"initComplete": function () {
this.api().columns().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>' )
} );
} );
}
});
How do I use that function and how do I have to rewrite it to work for me?
It seems I didn't understand what fnServerData did. It can be used to send additional data to the server from the client. So it's the oposite of what I'm trying to do.
I managed to do this by using this code:
"processing": true,
"serverSide": true,
ajax: {
url: '/MyApp/data-source',
data: function ( data ) {
data.someKey = "someValue";
},
},
Then when I print my request on the server I find a new object in the dictionary:
'someKey': ['someValue']

Categories