Using ajax.reload() in dataTables saving input text - javascript

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.

Related

checkbox not working in data table when paginated

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.

how to append json array in datatable using render function

I want to append json array into one popover attribute called data-content.
I am using jQuery DataTables plugin to perform UI functionalities. Using data variable table is populated with the data.
How could I insert titleDescription array from data variable into the attribute name called as data-content inside a tag in js , check my fiddle and go to datatable function there inside columnDefs there is render function. In that function I have return and append a tag, there only I have to append titleDescription array.
Check this JSFiddle for demonstration.
You can use the row attribute, and have the data in a non visible column.
Check the example
https://datatables.net/examples/advanced_init/column_render.html
$(document).ready(function() {
$('#example').DataTable( {
"columnDefs": [
{
// The `data` parameter refers to the data for the cell (defined by the
// `data` option, which defaults to the column being worked with, in
// this case `data: 0`.
"render": function ( data, type, row ) {
return data +' ('+ row[3]+')';
},
"targets": 0
},
{ "visible": false, "targets": [ 3 ] }
]
} );
} );
That would do the trick.
You just need to add another column at the last of each row then you can access it from row like this
render : function(data, type, row) {
return '<span class="favlist-icon"></span><span class="immediate-attention-icon"> </span> <span class="docx-name-list-link"> <a class="apopoverdata" href="#" data-content="'+row[4]+'" rel="popover" >'+data+'</a></span>';
}
Here is working fiddle
https://jsfiddle.net/2cn4b8bz/4/
I'm not sure what library you were using for your pop over so I used tooltipster seeing as you had jQuery already for the DataTable. Your data didn't have everything you needed either so I've altered it a wee bit:
$(function() {
$('#documentListing-data').DataTable({
data: json.documentAll.document,
pageLength: 10,
columns:[
{
"data": "documentTitle",
"title": "Name",
"render": (data, type, row) => '' + data + '',
},
{
"data": "category",
"title":"Category",
"render": (data, type, row) => data.map((k, v) => k.trim()).join(", "),
},
{
"data": "publishedDate",
"title":"Published Date"
},
{
"data": "lastUpdatedDate",
"title": "Last Updated Date"
},
],
"drawCallback": function(settings) {
$('.tooltip').tooltipster();
}
});
});
Working JSFiddle. Hope that helps!

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();
});

Enable/Disable Html button based on the data from the server

I am using datatable Jquery and making an ajax call to read data from the server.
Lets say database has 3 attributes "Attribute1 , Attribute2, Status".
Depending upon the Status, the third column on the datatable should be enabled or disabled button.
function test(server_url,table_id){
.ajax({url: server_url,dataType:"html",success: function(result){
var json_obj=JSON.parse(result);
var Columns="<thead><tr>";
var Fields=[],Tool_columns=[];
UserGroupFields=json_obj.columns;
for(i=0;i<json_obj.columns.length;i++){
Columns+="<th>"+json_obj.columns[i]+"</th>";
var field_dic={};
var tool_dic={};
field_dic["label"]=json_obj.columns[i];
field_dic["name"]=json_obj.columns[i];
Fields[i]=field_dic;
Tool_columns[i]=tool_dic;
}
tool_dic["targets"]=-1;
tool_dic["data"]="null";
tool_dic["defaultContent"]="<button this.disabled=true'>Yes</button>";
myTable=('#'+table_id).DataTable({
"order":[[0,"desc"]],
aaData:json_obj.data,
dom: 'T<"clear">lfrtip',
columns:Tool_columns,
tableTools: {
sRowSelect: 'single',
"sRowSelector": "td:not(:last-child)",
"aButtons": [ {
"sExtends": "editButton",
"sButtonText": "Edit",
"target": "#"+table_id
}]
},
"search": {
"regex": true,
"smart": false
}
});
Through above code I am able to add a button to each row read from the server . So how do I now enable or disable it based on the third atrribute of each record "Status".
Type of Data :
Object { columns: Array[3], data: Array[2] }
Data :
[{"column1":"1","Column2":"abc","Status":"Yes"},{"column1":"2","Column2":"xyz","Status":"No"}]
Any leads would be appreciated.
I am new to JQuery and JavaScripts
Thanks
Check the value of status in data and set the button in aaData accordingly.
Added one line in your code :
field_dic["button"]=(json_obj.columns[i]["status"]=="LIVE")?"Button Text":"Button Text";
for(i=0;i<json_obj.columns.length;i++){
Columns+="<th>"+json_obj.columns[i]+"</th>";
var field_dic={};
var tool_dic={};
field_dic["label"]=json_obj.columns[i];
field_dic["name"]=json_obj.columns[i];
field_dic["button"]=(json_obj.columns[i]["status"]=="LIVE")?"<button disabled='disabled'>Button Text</button>":"<button>Button Text</button>";
Fields[i]=field_dic;
Tool_columns[i]=tool_dic;
}
Loop to read "Status" value and set the value accordingly.
for(i=0;i<json_obj.data.length;i++){
if(json_obj.data[i]["Status"]=="Yes"){
json_obj.data[i]["Status"]="<button disabled='disabled'>Button Text</button>";
}
else{
json_obj.data[i]["Status"]="<button>Button Text</button>";
}
}

Javascript keyword "this" becomes undefined

I am using DataTables to create a list of selectable phone numbers, my function is as follow:
function search(areacode) {
areacode = typeof areacode !== 'undefined' ? areacode : 239;
$("#did_search").fadeIn();
var table = $('#example').DataTable( {
"bDestroy": true,
"ajax": "/Portal/manage/search_bulkvs/" + areacode,
"columns": [
{ "data": "did" },
{ "data": "city" },
{ "data": "state" },
{ "data": "action" },
],
"columnDefs": [
{ "visible": false, "targets": 3 }
]
} );
$('#example tbody').on( 'click', 'tr', function () {
var row_object = table.row( this ).data();
$("label[for = did_label]").text(row_object.action);
$('input[name="did"]').val(row_object.action);
} );
}
The end of the function $('#example tbody') -- allows me to select the data from the table that I need and set the value of my label/input for form processing. However, after I run this function a second time I am unable to select this data anymore.
My debugging has led to this error: Uncaught TypeError: Cannot read property 'action' of undefined
I thought that row_object would be defined every time that the function is run, but it looks like it isnt.
Does anyone have any suggestions as to how I can retrieve this data from the table after the function has been run more than once?
If the ajax call replaces the tbody element of the table, you will need to attach your delegated event handler to a non-changing ancestor (e.g. $('#example').on or even $('#example').parent().on(.
You also want to avoid repeatedly setting up handlers if search is called multiple times (or call off before on).
e.g.
$('#example tbody').off('click').on( 'click', 'tr', function () {
var row_object = table.row( this ).data();
$("label[for = did_label]").text(row_object.action);
$('input[name="did"]').val(row_object.action);
} );
Since you're using ajax, you need to bind your click object on each draw using DataTables.fnDrawCallback, like this:
function search(areacode) {
areacode = typeof areacode !== 'undefined' ? areacode : 239;
$("#did_search").fadeIn();
var table = $('#example').DataTable( {
"bDestroy": true,
"ajax": "/Portal/manage/search_bulkvs/" + areacode,
"columns": [
{ "data": "did" },
{ "data": "city" },
{ "data": "state" },
{ "data": "action" },
],
"columnDefs": [
{ "visible": false, "targets": 3 }
],
"fnDrawCallback": function(){
$("tbody tr td",$(this)).click(function(e){
.... Your click code here ....
});
}
} );
}
It is not that this becomes undefined. This error message
Uncaught TypeError: Cannot read property 'action' of undefined
usually means that you are calling a function from an undefined object (here is row_object), or the function you are calling (action) is not on the object.
Yes, the definition of variable row_object is fine. But I think you can console.log it to see whether it is assigned to some value correctly every time.

Categories

Resources