checkbox not working in data table when paginated - javascript

I have a data table using jquery that display a list of data. I implemented a checkbox on the first column that I can check for each record or check all the records at once. If there is one checkbox or more selected then the approve and reject button would show up. While all these can work at the moment but if I select a next page and start checking any checkbox, the approve/reject button will not display.
Code:
<article class="col-xs-6 text-right">
<button id="approveButton" class="btn btn-success update-button" value="1">Approve</button>
<button id="rejectButton" class="btn btn-danger update-button" value="2">Reject</button>
</article>
var $table = $("#dt_basic").DataTable({
"scrollY": ($(window).height() - 270)+"px",
"scrollX": false,
"pageLength": ' . Yii::$app->params['settings']['listing_length'] . ',
"processing": true,
"serverSide": true,
"columnDefs": [{ "targets": [0, 6], "searchable": false, "orderable": false, "visible": true, className: "text-center-desktop" }],
"deferLoading": ' . $total . ',
"order": [],
"ajax": "' . Yii::$app->urlManager->createUrl(['xxxx']) . '",
"sDom": "<\'dt-toolbar\'<\'col-xs-12 col-sm-9\'f><\'col-sm-3 hidden-xs\'l>>r"+
"t"+
"<\'dt-toolbar-footer\'<\'col-sm-5 col-xs-12 hidden-xs\'i><\'col-xs-12 col-sm-7\'p>>",
"autoWidth" : true,
"preDrawCallback" : function() {
responsiveHelper_dt_basic = new ResponsiveDatatablesHelper($(\'#dt_basic\'), {tablet : 1024, phone : 480});
},
"rowCallback" : function(nRow) {
responsiveHelper_dt_basic.createExpandIcon(nRow);
},
"drawCallback" : function(oSettings) {
responsiveHelper_dt_basic.respond();
var pagination = $(this).closest(".dataTables_wrapper").find(".dataTables_paginate");
pagination.toggle(this.api().page.info().pages > 1);
}
});
$("#approveButton").hide();
$("#rejectButton").hide();
$("#masterCheck").on("click", function (e) {
if ($(this).is(":checked", true)) {
$(".subChk").prop("checked",true);
} else {
$(".subChk").prop("checked", false);
}
});
//This would not detect if checkbox is ticked in next page
$("input:checkbox").on("change",function(){
if ($("input:checkbox:checked").length > 0) {
$("#approveButton").show();
$("#rejectButton").show();
} else {
$("#approveButton").hide();
$("#rejectButton").hide();
}
});
$(".update-button").on("click", function(e) {
e.preventDefault();
var status = $(this).val();
let allVals = [];
$(".subChk:checked").each(function() {
allVals.push($(this).attr("id"));
});
console.log(allVals);
let join_selected_values = allVals.join(",");
$.ajax({
url: "updatewithdrawbulk",
type: "UPDATE",
data: {
ids: join_selected_values,
type: status
},
success: function(data) {
location.reload();
},
error: function (data) {
alert("There is some error, please try again");
}
});
});
After going to next page, checking the master checkbox will work (checked all sub checkbox as well) and approve/reject button will show. My only issue is when I tick any checkbox individually, it will not show the buttons.
I was wondering if this is an issue with the code or jquery data table?

The issue is that when you are attaching these .on bindings - it will only attach for the elements that currently exist in the html to be found.
When your next set of rows are drawn - these do not have the events bound to them.
If you hook into the event callback that tells you when new rows have appeared - you should bind your events again so that these new rows work as expected.
In the sample I would expect this to be achieved within the drawCallback event.

Related

how to destroy table and reinitialize same table with new updated data using Datatables Jquery plugin

I am using Datatables plugin and dynmically populating the table with the data returned from server. on different table draws the returned data has variable no of columns. On each table intilization the code is checking if there has been previous initializations and removes it before creating a new table with dynamic data, using this code:
if ( $.fn.dataTable.isDataTable( '#contracts_forecast' ) ) {
$('#contracts_forecast').DataTable().clear();
$('#contracts_forecast').DataTable().destroy();
$('#contracts_forecast tbody').empty();
$('#contracts_forecast thead').empty();
}
On the serverside I am manually editing the data and updating the database. When the database is updated with new data , I want to refresh the table so the change is reflected in the table. In order to do that I am using an POST SUBMIT event, which is triggered after the data is submitted to server and then call the function getDT(filter_product_code, filter_product_name) to update the table with new data
PROBLEM:
When the post submit event is triggered , it recalls the function getDT(filter_product_code, filter_product_name); and change is reflected. BUT THE NEW TABLE with UPDATED IS ADDED TO CURRENT TABLE WITHOUT THE OLD TABLE BEING DESTROYED Which leaves me with two same tables on screen
p.s I am assuming every time getDT() function is called it should check for if table is initialized and destroy it before creating a new one using the same
$(document).ready(function() {
$('#filter').click(function(){
var filter_product_code = $('#filter_product_code').val();
var filter_product_name = $('#filter_product_name').val();
if(filter_product_code == '' || filter_product_name == '')
{
alert('Select Both filter option');
}
var columns = [];
getDT(filter_product_code, filter_product_name);
function getDT(filter_product_code, filter_product_name) {
$.ajax({
serverSide: true,
type:'POST',
url: "/XXX/_fetch.php",
data: {filter_product_code: JSON.stringify(filter_product_code),
filter_product_name: JSON.stringify(filter_product_name)},
success: function (data) {
data = JSON.parse(data);
columnNames = Object.keys(data.data[0]);
for (var i in columnNames) {
columns.push({data: columnNames[i],
title: capitalizeFirstLetter(columnNames[i])});
}
if ( $.fn.dataTable.isDataTable( '#contracts_forecast' ) ) {
$('#contracts_forecast').DataTable().clear();
$('#contracts_forecast').DataTable().destroy();
$('#contracts_forecast tbody').empty();
$('#contracts_forecast thead').empty();
}
table = $('#contracts_forecast').DataTable({
data: data.data,
columns: columns,
dom: "Bfrtip",
select: true,
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
],
"columnDefs": [
{
"targets": [0],
"visible": false,
"searchable": false
},
{ className: "tablecolumns", targets: "_all" },
]
} );
$('#contracts_forecast').on( 'click', 'tbody td:not(:first-child)', function (e) {
editor.inline( this );
} );
}
});
editor.on( 'postSubmit', function ( e, json, data, action, xhr ) {
getDT(filter_product_code, filter_product_name);
});
}
});
} );
I was doing a mistake by declaring the column variable outside function. Each time the function was called it was adding to already existing columns. So just needed to define column variable inside function.
getDT(filter_product_code, filter_product_name);
function getDT(filter_product_code, filter_product_name) {
var columns = [];
$.ajax({
serverSide: true,
// paging: true,
// retrieve:true,
type:'POST',

Is there a way to pull from multiple SQL tables for one DataTables table?

I use DataTables to present data in a reporting website that I created. I am working on creating a Report Builder where users can select multiple tables and then columns from those tables for a custom report.
What I want to know is whether there's a way to do this with DataTables. I'm able to get the tables names and column names for the custom report, but I've not been able to figure out how to send it to DataTables. I currently use server side processing and send an ajax call using POST to the DataTable.
I know that I can program in a SQL query based on the selected tables and columns, but I cannot seem to figure out how to have the data sent to DataTables.
Here is how I initialize my DataTables:
$(document).ready(function ()
{
// Setup - add a text input to each footer cell
$('#DataTable tfoot th').each(function () //creates the search bar as the footer
{
var title = $(this).text();
$(this).html('<input type="text" placeholder="Search ' + title + '" />');
});
var table = $('#DataTable').DataTable({
"lengthMenu": [[25, 50, 75, 100, 150, -1], [25, 50, 75, 100, 150, 'All']],
"dom": '<"top"Bifpl<"clear">>rt<"bottom"ip<"clear">>',
"buttons": [{
extend: 'collection',
text: 'Export',
buttons: ['export', { extend: 'csv',
text: 'Export All To CSV', //Export all to CSV file
action: function (e, dt, node, config)
{
window.location.href = './ServerSide.php?ExportToCSV=Yes';
}
}, 'csv', 'pdf', { extend: 'excel',
text: 'Export Current Page', //Export to Excel only the current page and highlight the first row as headers
exportOptions: {
modifier: {
page: 'current'
}
},
customize: function (xlsx)
{
var sheet = xlsx.xl.worksheets['sheet1.xml'];
$('row:first c', sheet).attr('s', '7');
}
}]
}
],
"fixedHeader": { //Keeps the header and footer visiable at all times
header: true,
footer: true
},
"select": true, //sets the ability to select rows
"processing": true, //shows the "Processing" when working
"serverSide": true, //sends data to the server for processing
"ajax": { //where the data is sent and processed
"url": "./ServerSide.php",
"type": "POST"
},
stateSave: true, //Saves the current state of the page
columnDefs: [{ visible: false, targets: 0}], //Hides the first column the ID column
initComplete: function () //sets the search
{
var api = this.api();
// Apply the search
api.columns().every(function ()
{
var that = this;
$('input', this.footer()).on('keyup change', function (e)
{
if (that.search() !== this.value & e.keyCode == 13) //you have to hit enter for the search to start
{
that
.search(this.value)
.draw();
}
});
});
}
});
});
$.fn.dataTable.ext.buttons.export =
{
className: 'buttons-alert', //Adds the "Export all to Excel" button
id: 'ExportButton',
text: "Export All To Excel",
action: function (e, dt, node, config)
{
window.location.href = './ServerSide.php?ExportToExcel=Yes';
}
};
Here is what I can currently get to work:
I'm not sure else anyone would need to help me with this, but if I'm missing something let me know and I'll add it.
I need all the data from all selected tables and columns to be in one DataTables table presented on the website. In the image above I'm showing that I've gotten as far as getting the column headers and using aliases for the tables. I'm working through my FilterSort.class.pph file (which is like the ssp.class.php in DataTables) to see if I can get it to present the table.
I figured it out. I was still calling the correct DataTables functions, but I wasn't passing the data to the functions. I ended up having to update my ServerSide.php file and my FilterSort.class.php file. Those are the ones that all of the other reports use to send data from the server to the screen. After some trial and error, I got it to work and didn't need to change anything in the code posted in my question.

How to disable click selected datatable jquery?

I've use datatable jquery with child-row. Normal, I selected a main row, i use
$('#table tbody').on('click', 'tr', function () {
if ($(this).hasClass('selected')) {
$(this).removeClass('selected');
//do this
}
else {
table.$('tr.selected').removeClass('selected');
$(this).addClass('selected');
//do this
}
});
When use this, i click any child-row, it effect together. Now, i want to don't click to child-row, how can i do it, using javascript or jquery ?
Look at the picture sample.
I changed the behavior and fixed some things that can be traced by to DataTables example.
play with this one and see if it is closer to what you want. It assumes a single select. If you pick a row in the child, the parent becomes selected.
http://live.datatables.net/fowiduzi/3/edit
$(document).ready(function () {
var table = $('#example').DataTable({
"data": testdata.data,
select: "single",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": '',
"render": function () {
// Use Font Awesome for the expander in the first cell
return '<i class="fa fa-plus-square" aria-hidden="true"></i>';
},
width: "15px"
},
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "salary" }
],
"order": [[1, 'asc']]
});
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
// get the Font Awesome container
var tdi = tr.find("i.fa");
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tdi.first().removeClass('fa-minus-square');
tdi.first().addClass('fa-plus-square');
}
else {
// check to see if the child row exists.
// dont want to overwrite it if its already there.
if (row.child() && row.child().length > 0) {
row.child.show();
}
else {
// Open this row
row.child(format(row.data())).show();
}
tdi.first().removeClass('fa-plus-square');
tdi.first().addClass('fa-minus-square');
}
});
// Keeps the expander from being selected
table.on("user-select", function (e, dt, type, cell, originalEvent) {
if ($(cell.node()).hasClass("details-control")) {
e.preventDefault();
}
});
// If the parent row gets deselected by the user, deselect any
// selected child rows
table.on("deselect", function (e, dt, type, indexes) {
if (type === 'row') {
var child = dt.row(indexes[0]).child();
if (child && child.length > 0) {
$(child[0]).find(".selected").removeClass("selected");
}
}
});
$("#example").on("click", ".dt-childtable tr", function () {
var tr = $(this).closest("tr");
var childTbl = tr.closest("table");
var parentRow = childTbl.closest("tr").prev();
// see if this row is already selected
var isSelected = tr.hasClass("selected");
// remove previous selects from child table
childTbl.find(".selected").removeClass("selected");
if (isSelected) {
// this is a behavior question do you want the parent row to deselect with
// when the child row is.
//table.rows(parentRow).deselect();
} else {
tr.addClass("selected");
// if the child is selected, make sure the parent is selected but
// don't want to trigger a select event if the row
// is already so check if selected
if (!$(table.row(parentRow).node()).hasClass("selected")) {
table.rows(parentRow).select();
}
}
});
});
This code prevents the rows from being selected/unselected from occurring on the details-control click.
It also uses font-awesome from instead of the icons shown in the datatables example.
$(document).ready(function () {
// Normal table definition
var table = $('#example').DataTable({
"data": testdata.data,
select:"single",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": '',
"render": function () {
Instead of using the images provided from else where and adding it to my project
I use the Font Awesome as the expander
return '<i class="fa fa-plus-square" aria-hidden="true"></i>';
},
width:"15px"
},
{ "data": "name" },
{ "data": "position" },
{ "data": "office" },
{ "data": "salary" }
],
"order": [[1, 'asc']]
});
// Add event listener for opening and closing details
// Note the click event is only on the cell with the details-control class
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var tdi = tr.find("i.fa");
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
// change the two font awesome icons
tdi.first().removeClass('fa-minus-square');
tdi.first().addClass('fa-plus-square');
}
else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
tdi.first().removeClass('fa-plus-square');
tdi.first().addClass('fa-minus-square')
}
});
// This event handler prevents the details-control from changing the select row from occurring
table.on("user-select", function (e, dt, type, cell, originalEvent) {
if ($(cell.node()).hasClass("details-control")) {
e.preventDefault();
}
})
});

Datatables update single column every 5 seconds

I'm using datatables to show several information and button.
This is the javascript used to initialize the datatables
if ( ! $.fn.DataTable.isDataTable( '#datatableTable' ) ) {
datatableTable = $('#datatableTable').DataTable({
responsive: true,
columnDefs: [
{ "width": "25%", "targets": 4},
{
targets: [4,5,6],
//set priority to column, so when resize the browser window this botton stay on the screen because have max priority
visible: (document.getElementById('role').value == '[ROLE_ADMIN]' || document.getElementById('role').value == '[ROLE_FLEET_ENG]'
|| document.getElementById('role').value == '[ROLE_SUPPLIER]'),
responsivePriority: 1,
orderable: false,
searchable: false,
},
...
],
//fix problem with responsive table
"autoWidth": false,
"ajax":{
"url": "datatable/" + $("#selectedCar").val(),
"dataSrc": ...
return json.result.data;
},
"error": function (xhr, error, thrown) {
window.location.href = "/DART/500";
}
},
"columns": [
....
{data:null, render: function ( data, type, row ) {
var datId="deleteDat"+row.idAcquisition;
if (row.datUploaded){
return '<button type="button" class="btn btn-danger" name="deleteDat" target="'+row.idAcquisition+'" id="'+datId+'" data-toggle="modal"'
+'data-target="#deleteDatModal">Delete</button>'
}else
return '<button type="button" class="btn btn-danger" name="deleteDat" target="'+row.idAcquisition+'" id="'+datId+'" data-toggle="modal"'
+'data-target="#deleteDatModal" disabled>Delete</button>'
},
],
"fnDrawCallback": function(data, type, row, meta ) {
//Initialize checkbox for enable/disable user
$("[name='my-checkbox']").bootstrapSwitch({size: "small", onColor:"success", offColor:"danger"});
},
});
}
else {
datatableTable.ajax.url("datatable/" + $("#selectedCar").val()).load();
}
Column 5 (starting from 0) has buttons, each button may be disabled or enabled depends on the datUploaded boolean value.
This variable change if user load file ,but this value has setted after async task, so I don't know in my javascript when this task end.
I thought to update every 5 seconds only this column, but how can I do it?
I find datatableTable.column(5).cells().invalidate().render() but I receive an error (unknow parameter "isShow" for row 0) and update doesn't work.
Can you help me? Thanks
As I said in a comment, you can pass .load() a callback function that will be called automatically when the ajax request is complete. In this callback you can update your table as you prefer. After you update the table, remember to call datatableTable.draw(); to apply the changes.
I don't think invalidate() and render() are necessary.
So your else branch would be something like
datatableTable.ajax.url("datatable/" + $("#selectedCar").val()).load(function() {
/*
...do something to the table...
*/
datatableTable.draw();
});

Using ajax.reload() in dataTables saving input text

I'm working on converting code from dataTables 1.9 to 1.10 as well as using a ajaxSource instead of a prepopulated table.
The issue I have is that my table rows have a input field and when populating the new source I lose the data written in the input field. I have tried many workarounds but can't seem to get something that is seamless.
Below you will find the PHP code generating the table data as well as the input box with class user_list. Since I update the table data every 30 seconds I am trying to pull the written text and place it back without the user knowing that the data updated.
I have tried accomplishing this using:
setInterval(function() {
var predata = $(".user_list:focus").val();
var trid = $(".user_list:focus").closest('tr').attr('id');
mainTable.ajax.reload(null, false);
console.log(predata);
console.log(trid);
$("#" + trid + " .user_list").val(predata);
}, 30000);
However the value of the input is never updated although when console.loging the id is correct. Please assist.
JS:
mainTable = $("#main_dash").DataTable({
"language": {
"url": "../locale/" + locale + "/LC_MESSAGES/" + "dt." + locale + ".txt",
},
"pagingType": "full_numbers",
"pageLength": 10,
"ajax": {
"url": "ajax_tables/main_table.php",
"type": "POST"
},
"columnDefs": [
{ "orderable": false, "targets": 0 }
],
"columns": [
{"data": "flagged"},
{"data": "date"},
{"data": "type"},
{"data": "regarding"},
{"data": "submitted_by"},
{"data": "review"},
{"data": "assign"},
],
"autoWidth":false,
"order": [[1, 'asc']],
"deferRender": true,
"initComplete": function() {
setInterval(function() {
mainTable.ajax.reload(null, false);
}, 30000);
},
});
PHP Code (main_table.php):
foreach ( $data as &$d ) {
$d['DT_RowId'] = $d['groom_id'];
$d['DT_RowClass'] = 'groom-color-' . $d['type_id'];
$d['review'] = '<button class="button button-blue review_item">Review</button>';
$d['assign'] = '<span class="groom_id hidden">' . $d['groom_id'] . '</span><input type="text" class="user_list">';
if ( preg_match('/1969-12-31/', $d['date'] )) {
$d['date'] = $d['date2'];
}
if ( $d['flagged'] ) {
$d['flagged'] = '<img src="images/red_flag.gif">';
} else {
$d['flagged'] = null;
}
}
echo json_encode(array(
"draw" => 1,
"recordsTotal" => $count,
"recordsFiltered" => 1,
"data" => $data,
));
Add an onchange() handler to your input field and write the value with an ajax call to your db.
Then in the next reload the values should be there again.
Of course you should prevent auto-reload while the data is written and reload instead when the changed data was successfully saved to the db and then activate auto reload again. Could be done with a i am busy saving - don't auto-reload now flag.

Categories

Resources