Apps Script Reload Datatable after GS Function - javascript

So I have made a Crud web application that also builds a PDF document, all this is done by a GS function when a submit button is clicked, it also appends the data into a Google Sheet. I also have a Datatable that loads data from the same spreadsheet, but I cannot find a way to refresh or reload the table after the GS function is done
<script>
google.script.run.withSuccessHandler(showData).gettableData();
function showData(dataArray){
$(document).ready(function(){
$('#data-table').DataTable({
data: dataArray,
columns: [
{"title":"IDs"},
{"title":"Names",
render: function (data, type, row) {
return data + ' ' + row[2] + '';
},},
{"title":"Name2"},
{"title":"Address"},
{"title":"Date"},
{"title":"Version"},
{"title":"Total"},
{"title":"",
render: function (data, type, row, meta) {
if (type === "display") {
data = '<a class="btn btn-small" href="' + data + '" target="_blank">View</a>';
}
return data;
}},
{"title":"",
render: function(data, type, row, meta) {
return '<button data-target="modal1" class="btn btn-small modal-trigger" id="' + row[0] + '" onclick="editPastForms((this.id))">Edit</button>';}
}
],
columnDefs: [
{ "visible": false, "targets": [0,2] },
{
targets: [1, 2, 3, 5, 6, 7, 8],
orderable: false
},
{ className: "center-align", targets: [7,8] }
],
lengthMenu: [
[25],
[25],
],
order: [[4, 'desc']],
"bLengthChange": false,
});
});
}
</script>
I have tried adding a function to reloaded the page using a .withSuccessHandler() however I get an error saying the iFrame permissions won't allow this
&
I have tried simply rerunning the google.script.run.withSuccessHandler(showData).gettableData(); function, but I get an error saying that I cannot reinitialise the datatable
All examples I have found online only refer to Ajax (I have no idea what that is lol) and nothing really for Apps Script. If anyone has any solutions or links to something that can help me out I would be so appreciative

Related

Datatables: dynamic page load in modal, based on row values

I am trying something really complex here, and I have not worked out a way to implement a solution yet. The part I work on looks like this:
1. simple page A that dynamically loads datatable from db.Last col is a button.
2. an html page B that loads different things according to 2 values stored at at local storage. these are available in the aforementioned table.
Now the part I cannot figure out:
3. Into the simple page A, there is a modal div. I want to load the B page into this modal on button click, and load different data, according to the values stored at local storage.
Here is my code so far:
function getadminprojects(){ //function that dynamically loads datatable
$.ajax({
url: "http://....../CustomServices/DBDistApps",
type: "GET",
dataType: 'json',
async: false,
success: function(data) {
$('#projectsdt').show();
projectsTable = $('#projectsdt').DataTable({
"pageLength": 10,
"data": data,
"scrollX": true,
"order": [[ 4, "desc" ]],
//"aaSorting": [],
"columns": [
{ "data": "code" },
{ "data": "descr" },
{ "data": "manager" },
{ "data": "customer" },
{ "data": "link_date" },
{ "data": "delink_date"},
{ "data": "type"},
{
"data": null,
"defaultContent": "<button class='btn btn-warning' onclick='openmodal2();'>button1</button>"
},
{
"data": null,
"defaultContent": "<button class='btn btn-success' onclick='localStorage.setItem('username',"+row.customer+");localStorage.setItem('projectid',"+row.code+"); projectpopmodal(); '>button2</button>"
},
] ,
});
$('#projectsdt thead').on('click', 'tr', function () {
var data2 = table.row( this ).data();
alert( 'You clicked on '+data2[0]+'\'s row' );
} );
$('#projectsdt').show();
$('#projectsdt').draw();
}
});
}
function projectpopmodal(){
$('#showfreakinmap').load('newprojects.html');
$('#fsModal').modal('show');
}//function to load page B into modal of page A
Thank you in advance!

DataTable with Server-side processing

My current problem is how could I properly perform pagination in DataTable to generate lengthMenu (Showing 1 to 10 of 57 entries) dynamically and only load data when next page is clicked.
So far my understanding on server-side processing is like this:My web service is returning data from database using MySQL with limit and offset in JSON format. Assuming that the JSON data is correct how could I properly paginate my DataTable?
Below is my code:
var Table1 = $('#table').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": SomeWorkingURLS,
"dataType": "jsonp"
},
"columns": [
{ "data": "Column1" },
{ "data": "Column2" },
{ "data": "Column3" },
{ "data": "Column4" }
],
"columnDefs": [
{
"render": function ( data, type, row ) {
return data + "<hr>" + row.data1;
},
"targets": 0
},
{
"render": function ( data, type, row ) {
return data + "<br>" + row.data2 ;
},
"targets": 1
},
{
"render": function ( data, type, row ) {
return data ;
},
"targets": 2
},
{
"render": function ( data, type, row ) {
if (row.status == '2'){
return '<button class="fas fa-edit btn-success" data-toggle="tooltip" title="Edit" value="' + data + '">Verify</button>'
+ ' <button class="fas fa-undo btn-danger" data-toggle="tooltip" title="Resend" value="' + data + '"> Authenticate</button>';
}
else{
return '<button class="fas fa-edit btn-success" data-toggle="tooltip" title="Edit" value="' + data + '">Authenticate</button>';
}
},
"targets": 3
},
{ "width": "14%", "targets": 0 },
{ "width": "60%", "targets": 1 },
{ "width": "10%", "targets": 2 },
{ "width": "16%", "targets": 3 , "class":"dt-center"},
],
"destroy": true,
"searching" :false
});
Table1.draw();
$("select[name*='table_outbound_shipment_list']").removeClass('form-control');
$("#table_outbound_shipment_list_length").remove();
$('.form-control.form-control-sm').removeClass('form-control');
My web service would always return 10 row of data (or am I doing wrong here?)
My reference:https://datatables.net/examples/data_sources/server_side
There are libraries and helper classes for server-side processing that help with preparing server-side response.
For example, DataTables distribution includes ssp.class.php helper calss and sample script to aid in generating response if you're using PHP.
Otherwise, you can inspect sent parameters and paginate your results based on start and length request parameters.

Change only selected row/cell in DataTable

I have this piece of code where table cell is edited and updated.
$.ajax({
url: url_base + 'update',
type: "POST",
data: params,
dataType: 'json', // data type
contentType: "application/json; charset=utf-8",
success: function(res) {
/*var params = {};
callFunction("getWords", params,
function(bSuccess, res) {
$('#example').dataTable().fnDestroy();
var table = $('#example').DataTable({
data: res,
"columns": [
{ "bSortable": false, "targets": 0, "data": 'UserWord' },
{ "bSortable": false, "targets": 1, "data": 'UserWordAlt1' },
{
"targets": 2,
"data": 'UserWord',
"render": function(data) {
return '<button alt="Edit" class="btn btn-primary" value="' + data + '" onclick="edit(this)"><i class="far fa-edit"></i></button> ' + '<button class="btn btn-danger" id=' + data + ' onclick="del(this)"><i class="fas fa-trash-alt"></i></button>'
}
}
],
"order": [
[1, 'asc']
]
});
}
);*/
$('#updateAnliegenModal').modal('hide');
alertify.success('New word updated successfully');
},
error: function(xhr, resp, text) {
console.log(xhr)
}
})
});
The thing is, when I update row I want to affect changes only for that row. Not to refresh the dataTable. In my current case I lost focus from that row which I am updating because table is reloaded again and rows are sorted by new data. Another problem is when I search for a specific word using the search feature of DataTable. If I want to update that found word I want to display only that searched word, not to reload the whole table.
I commented that part where new table is reloading... Actually I am calling again the same getWords function which on success destroys the current datatable and reloads the new one.

DataTable fixed header not working for scrollable table

I've been working with dataTables for a short period of time and I have a DataTable with two columns:
TableVehUsage = $("#TableVehUsage ").DataTable({
data: [],
ordering: true,
paginate: false,
"info": false,
fixedHeader: {header: true},
columns: [
{ data: "Vehicle", title: "Vehicle" },
{ data: "Serial", title: "Serial" }
],
"columnDefs": [
{
"targets": 0,
"render": function (data, type, full, meta) {
// If it is rendering the cell contents
if (type === 'display') {
switch (data) {
case "-":
return "-";
default:
if (full.IsOnSale == true)
return '<span style="color:red" onclick="ToParentTab(' + full.Id + ')">' + data + '</span>';
else
return '<span onclick="ToParentTab(' + full.Id + ')">' + data + '</span>';
}
}
return (isNaN(data)) ? -1 : +data;
}
} }]
});
I have some situation when all the data don't fit in the page and the user needs to scroll down to see all the info. I've tried to use Fixed Header by adding to my javascript the line fixedHeader: {header: true} and in the html:
<script src="https://cdn.datatables.net/fixedheader/3.1.2/js/dataTables.fixedHeader.min.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/fixedheader/3.1.2/css/fixedHeader.dataTables.min.css">
But is not working for me :(
What am I doing wrong?
I found a DataTable plugin that may be of help. Information on it is located at https://datatables.net/extensions/scroller/
Using this, my definition looks like this:
var table1 = $('#example').DataTable({ paging: true,   
scrollY:        200,
deferRender:    true,
scroller:       true });
I made a jsFiddle at https://jsfiddle.net/bindrid/oywvh1ek/6/
Try adding your data in a different variable with only the 'value' part of the key-value pair in it. For example, in the case of
{"vehicle":"Audi"},
your 'data' variable should have only ["Audi"] in it.
The below code worked perfectly for me.
$("<your_table_name>").DataTable({
data:data,
fixedHeader:true,
"scrollX": true,
"scrollY": "200px",
"scrollCollapse": true,
columns: [
{ title: 'Vehicle' },
{ title: 'Serial' }
]
});
I had a problem where my fixedHeader was working until I got about halfway down the page, then it disappeared. Here is what I did to get it working:
At the top of my JS file:
$(document).ready(function () {
DrawDataTable();
//This enables the table header to stick to the top of the page when the user is scrolling
var employeeData = $('#employee-table').DataTable();
employeeData.fixedHeader.adjust();
});
Then in the same JS file, in my jQuery ajax call, I had to add the line of code that says "fixedHeader": true
Finally, in my HTML file, I had to include the following in my <head> section:
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.12.1/fh-3.2.4/r-2.3.0/datatables.min.css"/>
<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.12.1/fh-3.2.4/r-2.3.0/datatables.min.js"></script>
Do not forget that you will also need to include whatever Bootstrap, JavaScript or jQuery scripts or style sheets in the head as well.

jQuery DataTables loads data from controller but does not display it

In short, I'm loading a list of clients (as JSON) from an MVC controller. I've verified that the data is structured properly, as well that it does get to the client. The only disconnect is that once the data is loaded, DataTables never displays it.
Here's the JavaScript that initializes the table. I'm almost positive it's configured correctly.
I use the dataSrc parameter to execute some extra code before the data is drawn. Note that it is being executed. I've stepped through just about every piece of this.
I also confirmed that $("clients table") finds the correct element.
$clientsTable = $("#clients table").DataTable({
deferRenderer: true,
info:true,
lengthChange: true,
lengthMenu: [25, 50, 75, 100],
processing: true,
saveState: true,
serverSide: true,
ajax: {
url: "LeadScatter/Clients",
type: "GET",
data: function (d) {
$.extend(d, { byPartner: $("#byPartner").val(), byEnabledDisabled: $("[name=byEnabledDisabled]:checked").val() });
},
dataSrc: function (data) {
getTabState("clients").isLoaded = true;
$("#clients .tab-content").fadeIn(_fadeTimeInMs);
$("#clients .dataTables_filter [type=search]").focus();
return data;
},
error: function (response) {
getTabState("clients").isLoaded = false;
selectedClient = undefined;
$("#tabs").tabs({ disabled: defaultDisabledTabs }).tabs("option", "active", 0);
updateSelectedClient();
showTabLoadError("clients", response.statusText);
if (response.status == 403) {
alert(response.statusText, response.status);
$("#clients").find(".dataTables_empty").text("Sorry, but you do not have permission to view Clients.");
}
}
},
columns: [
{ data: "cakeName", className: "button-cell client" },
{ data: "rpls", className: "number-cell" },
{ data: "forcePayoutIncrease", className: "number-cell" },
{ data: "allocation", className: "number-cell" },
{ data: "inMonthCap", className: "number-cell" },
{ data: "inMonthCapType", className: "number-cell" },
{ data: "toggle", className: "button-cell" },
{ data: "pushToDemo", className: "button-cell" }
]
});
Here's the object that DataTables is picking up. I removed extra array elements to save space. Trust that they're constructed correctly:
{
"draw": 1,
"recordsTotal": 784,
"recordsFiltered": 0,
"data": [
{
"id": 7689,
"cakeName": "<input type='radio' name='selected-client' value='7689' data-id='7689' data-cake-name='aa_test1' data-grouping-id='6666' id='selected-client-aa_test1' class='' /><label for='selected-client-aa_test1' class='disabled'>aa_test1</label>",
"rpls": 40,
"forcePayoutIncrease": 0,
"allocation": 0,
"inMonthCap": 0,
"inMonthCapType": "None",
"enabled": true,
"toggle": "<button type='button' class='button toggle' onclick='toggleClientEnabled(7689);'>Disable</button>",
"pushToDemo": "<button type='button' class='button' onclick='pushClientToDemo('aa_test1');'>Push To Demo</button>"
},
....
]
}
DataTables correctly updates the draw parameter with each subsequent request. Everything behind-the-scenes seems to work fine. Here's the HTML table where the data should be rendered:
<table border="1">
<thead>
<tr>
<th>CakeName</th>
<th>RPLS</th>
<th>ForcePayoutIncrease</th>
<th>Allocation</th>
<th>In-Month Cap</th>
<th>In-Month Cap Type</th>
<th></th>
<th></th>
</tr>
</thead>
</table>
And finally, a screenshot of the table. It's initialized but no data is rendered. You can even see that it's getting the "recordsTotal" variable from the returned object and setting it in the footer.
Am I missing something obvious?
Well, this was frustrating to discover, but it turns out that the dataSrc function was causing it.
I missed in the documentation that when using that parameter as a function, you must return the collection of data that's being displayed, not the JSON object as a whole.
So this:
dataSrc: function (data) {
return data;
}
becomes this:
dataSrc: function (data) {
return data.data; //access the data variable from the returned JSON
}
Voila.

Categories

Resources