Running a function on an image created in the DOM - javascript

I'm using dataTables to retrieve, display and organise data from a PHP script (which in turn pulls the information from a MySQL database).
Using the following code, dataTables retrieves the information and puts it into a.. well, table.
$('#content div').html( '<table id="example"></table>' );
var oTable = $('#example').dataTable( {
"bJQueryUI": true,
"bProcessing": true,
"bServerSide": true,
"sPaginationType": "full_numbers",
"sAjaxSource": "dataTables.php",
"aoColumns": [
/* UID */ { "bSearchable": false,
"bVisible": false },
/* Datetime */ { "asSorting": [ "desc" ] },
/* Staff Name */ null,
/* Room */ null,
/* Reason */ null,
/* Urgency */ null,
/* Processed? */ null ],
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var sDirectionClass;
if ( aData[6] === null ) {
sDirectionClass = "new";
if ( row % 2 !== 0 )
sDirectionClass = "new_odd";
} else {
sDirectionClass = "std";
}
row++;
$(nRow).addClass( sDirectionClass );
return nRow;
}
} );
Most of this, I hope, is quite straightforward - this function takes the sAjaxSource property and looks at my dataTables.php file, which simply reads the MySQL DB and returns some information in a JSON-encoded format.
This all works fine, but I'm trying to turn one of my table's columns into a clickable link.
The brief PHP for this is;
if ( $aColumns[$i] == "Processed" )
{
$link = '<img src="tick.png" id="' . $aRow[ $aColumns[0] ] . '" />';
$row[] = ( empty( $aRow[ $aColumns[$i] ] ) ) ? $link : $aRow[ $aColumns[$i] ];
}
The pseudo for that is basically if Processed field is NULL display an image with the UID of that row; otherwise display the value of Processed field.
What I'd like to do now is make that image JS-clickable to run an AJAX function. I thought that the following code (in situ immediately after the above JS):
oTable.find('img').click(function(){
var process = $(this).attr("id");
$.ajax({
url: "check_alerts.php",
data: { process: id }
}).done(function() {
oTable.fnDraw(false);
});
});
Unfortunately, it appears to do nothing. I'd imagine this is because the img I'm creating is created in the DOM and as such when the above function runs, it won't find any img tags.
How can I amend the code so that those images will run my AJAX function?
Thanks in advance,

You need to use the jquery.on() which is specifically meant to bind events on dynamic content.
Try this:
//replace table with the table pointer (class,id)
$('table').on('img','click',function(){
//do your thing
});

To make sure that your new DOM elements also listen to the click event you should use "on".
oTable.on("click", "img", function() {
var process = $(this).attr("id");
$.ajax({
url: "check_alerts.php",
data: { process: id }
}).done(function() {
oTable.fnDraw(false);
});
});
See the documentation

Did you try using firebug to see if the image tag is generated.
Than try running your image click binding function in firebug console tab. If that works than probably you are trying to bind the click event too soon in your original page execution cycle.

Related

Datatables has only 10 rows accessible outside the DataTables creation function

I am using Django and in one of my tamplates I use datatables (1.10.19) to display my table data.
This is how my code looks like:
$(document).ready( function () {
table = $('#mytable').DataTable({
"pagingType": "full_numbers",
data: dataSet,
columns: [
{ title: "Naslov zahtjeva" },
{ title: "Datum slanja" },
{ title: "Status" },
{ title: "Rok Izvršenja." },
{ title: "Id zahtjeva" },
],
"fnCreatedRow": function(row, data, index){
$(row).addClass("clickable-row");
$(row).attr('data-href', data[4]);
$(row).addClass("table_row_point");
},
});
Problem occurs at the line -> $(row).attr('data-href', data[4]);
I have a different function that is suposed to use that 'ID' from 'data-href' attribute in order to go to another page like this
jQuery(document).ready(function($) {
$(".clickable-row").click(function() {
window.location = $(this).data("href");
});
});
Thing is it works fine for first 10 rows, and when I try 'console.log( this );' I get
Only for the first 10 rows, and it acts like other 3000 don't even exist, I believe it is connected to the default value of 10 rows that appear, but it makes no sense to me for data to be displayed normally, but the 'tr' element not to exist for all, but 10 of them.
Note: When I place this function into DataTable creation code (1st snippet) it shows all the tr elements
$('#mytable tbody').on( 'click', 'tr', function () {
console.log( this );
} );
If someone has any idea it would be much appreciated
fnCreatedRow function is executed everytime datatable creates the <tr> element in the dom. Since you have enabled pagination, function is run only on the <tr> elements created at the time. If you move on to next page, you'll see that console prints next set of rows.
By the way I think createdRow is preferred over old fnCreatedRow naming convention. https://datatables.net/reference/option/createdRow

Javascript on objects don't work in DataTable rows

I just implemented a DataTable in my app, but it seems like javascript doesn't work within the DataTable.
I've attached all code below for better readability.
As you can see, the ccbtn_action="delete" bit is present, but Chrome/IE/FF doesn't seem to want to do anything when the glyphicon is clicked.
This code works perfectly when called from outside the DataTable.
What gives? Is it something to do about JavaScript not being applied to dynamically generated elements?
Thank you!
Here is the Javascript code that doesn't work:
$(document).ready(function(){
// Delete Records
$('[ccbtn_action="delete"]').on('click', function() {
var type = $(this).attr('ccbtn_value_type');
var value = $(this).attr('ccbtn_value_id');
console.log('type=' + type + '&id=' + value);
if (confirm('Are you sure you want to PERMANENTLY delete this record? There is NO TURNING BACK!')) {
$.ajax({
type: 'POST',
url: 'includes/crmcore_action.php?action=cc_delete',
data: 'type=' + type + '&id=' + value,
success:
function() {
$('#cc_pagetop_status').html("<div class='alert alert-success'><strong>Success!</strong> The record was successfully deleted.</div>");
if (type == "company")
{
window.location = "companies_list.php";
}
else
{
location.reload();
}
}
});
} else {
// Do nothing!
}
});
});
Here is the code for the DataTable:
$(document).ready(function() {
var t = $('#DataTable').DataTable({
"order": [[ 1, 'asc' ]],
ajax: {
url: 'includes/dt_ss.php?getwhat=company',
dataSrc: ''
},
columns: [
{data: null},
{"data": null,
"render": function (data, type, row)
{
return ''+data.name+'';
}
},
//{data: 'name'},
{data: 'tel'},
{
"data": "id",
"render": function ( data, type, full, meta )
{
return '<span class="glyphicon glyphicon-remove" ccbtn_action="delete" ccbtn_value_type="company" ccbtn_value_id="'+data+'" data-toggle="tooltip" data-placement="bottom" title="Click me to delete"></span>';
}
}
],
});
t.on( 'order.dt search.dt', function () {
t.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {
cell.innerHTML = i+1;
} );
} ).draw();
});
Since the js looks ok, this is most probably a timing issue. You part of script that binds the events is executed before the actual elements are created.
To fix that, you can:
Make sure the script runs binding after elements creation
Use dynamic binding (like .delegate() http://api.jquery.com/delegate/)
Try delegating your event like this:
$('#DataTable').on('click', '[ccbtn_action="delete"]', function() { ...
My guess is the click event is attached before your ajax request loads the DataTable rows. You can read more here about jQuery event delegation with on(). Specifically:
Event handlers are bound only to the currently selected elements; they must exist at the time your code makes the call to .on()
Try like this, but jquery version must be 1.9+
$(document).on('click', '[ccbtn_action="delete"]', function() { // your remaining code

Pass a JavaScript variable to a shiny app contained in a iframe

I have a website with a DataTable. Following this I create a js event on clicking on a row. The event stores an id corresponding to the clicked row in a variable and following this I posted a message to the shiny-iframe.
$(document).ready(function() {
var table = $('#example').DataTable( {
"columnDefs": [
{
"targets": [ 0 ],
"visible": false,
"searchable": false
}
]
});
$('#example tbody').on('click', 'tr', function () {
var data = table.row( this ).data();
var table_row_id = data[0];
var frame = document.getElementById('shiny-iframe');
frame.contentWindow.postMessage(table_row_id, '*');
} );
} );
Still I am not sure how to proceed from here. The end result is to have shiny reloading the app in the iframe with as argument the variable stored in table_row_id.

Custom rendering when using server side processing

I was wondering if the rendering of the table after receiving an ajax response can be modified. This seems related to the render function described here: https://www.datatables.net/manual/orthogonal-data.
My server returns Data like
{
"name":
{
id: "123456",
value: "Tiger Nixon"
}
}
I want to add to each name cell the id of the name as data-attribute or as id for the td and want to add a .on( "click", handler ) for each cell.
Is this possible?
Thanks in advance
You can use DT_RowData or DT_RowAttr (requires DataTables 1.10.5 or higher) parameters in your returned data to assign attributes to <tr> element which you can later retrieve in click handler, see Server-side processing chapter in the manual.
Alternatively you can use render method but it may not be as effective. I assumed below that index of your name column is 0 and that you want to set data-id attribute.
var table = $('#example').DataTable({
"columnDefs": [{
"data": "name.value",
"targets": 0,
"render": function ( data, type, full, meta ) {
if(type === 'display'){
$('#example').DataTable().cell(meta.row, meta.col).nodes().to$().attr('data-id', full['name']['id']);
}
return data;
}
}]
});
You can add click event handler using the code below:
$(document).ready(function(){
var table = $('#example').DataTable({
// Define DataTables initialization options here
});
$('#example tbody').on('click', 'td', function(){
// Use table to access various API function
//
// For example:
// var data_cell = table.cell(this).data();
});
});
This is possible by using the columns.createdCell function.
The answer of Gyrocode is correct for an old DataTables version.

Data tables copy,save only selected rows on individual multi filter select

I am trying to copy the selected rows in the table, when I click the buttons for copy,csv, excel, print the entire table copying and downloading.
How to get the selected rows in the table, and copied to clipboard, save as the file.
Javascript:
$(document).ready(function() {
var table = $('#example').DataTable( {
"dom": 'T<"clear"><"H"lfr>t<"F"ip>',
"tableTools": {
"sSwfPath": "/swf/copy_csv_xls_pdf.swf"
},
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>' )
} );
} );
}
} );
$('#submitFrm').click( function() {
var data = table.$('input, select').serialize();
alert(
"The following data would have been submitted to the server: \n\n"+
data.substr( 0, 120 )+'...'
);
return false;
} );
} );
With copy, save, print, buttons and also the individual filter on the column.But the thing is selected rows are not copying in the clipboard and csv after downloading showing entire data not selected rows.
How to copy,csv .. only the selected rows in the table.
Thanks
http://jsfiddle.net/dbecbww1/
just an example. for additional questions, you might need to
post again another question.
check if it is also working for your buttons, if not,
configure your datatableTools.tableTools.js
function "_fnGetDataTablesData", try to debug.
I've tried manipulating it before.
FYI:
you can set which columns you only need to copy for your files.
NOTE: set your swf path normally, which I think you have done already. the swf path for the fiddle is not working so the buttons won't work. I've been searching for working swf paths online but to no avail. Mine works perfectly fine in my local project, though.

Categories

Resources