How to use Datatables server-side processing with Google Apps Script - google-apps-script

I'm trying to use datatables in server-side processing mode whereby data is loaded in batches, asynchronously. This is very useful for massive datasets. The documentation is clear enough (https://datatables.net/examples/data_sources/server_side.html), however, I'm struggling to work out how to implement it within Google Apps Script and its HTMLService.
What I'm currently using (which is working) is datatables loading all the data in at once:
$(document).ready(function() {
google.script.run.withSuccessHandler(loadLogList).getLogList();
});
function loadLogList(data) {
if (data) {
for (var i = 0; i < data.length; i++) {
htmlString += "<tr><td>" + data[i][0] + "</td>";
htmlString += "<td>" + data[i][1] + "</td>";
htmlString += "<td>" + data[i][2] + "</td>";
htmlString += "<td>" + data[i][3] + "</td></tr>";
}
$("#LogListBody").html(htmlString);
}
var table = $("#LogList").DataTable( {
"columnDefs": [
{ "orderData":[ 0 ], "targets": [ 1 ] },
{
"targets": [ 0 ],
"visible": false,
"searchable": false
} ],
"paging": true,
"select": true
});
}
The documentation suggests that datatables needs initialising like this:
$(document).ready(function() {
$('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": "../server_side/scripts/server_processing.php"
} );
} );
So somehow I need to provide "ajax" with "google.script.run". Any ideas? I then need to write a function on the server-side (Code.gs) to return json-formatted data. If anyone has sample code for this also I'd be very grateful.
Thanks

Looking at the docs ajax can be configured in a few different way. One is by providing a custom function.
https://datatables.net/reference/option/ajax
Edit based on more info from op. This is the very basic setup:
$('#example').dataTable( {
"processing": true,
"serverSide": true,
"ajax": function (data, callback, settings) {
google.script.run.withSuccessHandler(callback).getLogList(settings);
}
} );

Related

Adding slides to Slick with ajax

so I'm using Slick Carousel and I'm showing in it a list of products from my database limited to 24 for performance reasons. But I need to show all of them, so I made a afterChange function that ajax loads another 24 products everytime the user is 2 slides before the end and add them with slickAdd function to the end of the Slick.
Everything is working fine but when the slickAdd function executes, the slides width changes for some reason from 457px to 451px and I can see a part of the 4th slide on the current slide.(I have 3 shown) Then if I click on the next button again, the width goes back to 457px and everything is ok.
$('.demo').slick({
slidesToShow: 3,
slidesToScroll: 3,
infinite: false,
});
$('.demo').on('afterChange', function(event, slick, currentSlide, nextSlide){
var komponent = $(".komponent-container.active").attr("id");
var loadWhen = currentSlide+6;
if(loadWhen == slick.slideCount){
console.log("loadmore");
$.ajax({
type: "POST",
url: "/project/public/konfigurator",
data: {id: komponent, from_column: slick.slideCount, requestid: "load_more"},
dataType: "json",
success: function (data) {
var data_parser = JSON.parse(data)[0];
if (data_parser.length > 0) {
var html = '';
for (i = 0; i < data_parser.length; i++) {
var produkt_nazov = 0;
if (data_parser[i].produkt.length > 45) {
produkt_nazov = data_parser[i].produkt.substring(0, 45) + "...";
} else {
produkt_nazov = data_parser[i].produkt;
}
html += '<div><div class="item-container"><div class="container-wrapper"><div class="produkt-container"><div class="item-left"><div class="item-image-wrapper"><img draggable="false" id="produkt-img" src="img/konfigurator/'+komponent+'/' + data_parser[i].produkt + '/1.jpg" alt="" /></div><div class="cena">' + data_parser[i].cena + ' €</div></div><div class="item-right"><div class="item-info"><span class="item-title">' + produkt_nazov + '</span><span class="item-description"><span>Výrobca čipu - ' + data_parser[i].vyrobca_cipu + '</span><span>Veľkosť pamäte - ' + data_parser[i].vram_size + '</span><span>Typ pamäte - ' + data_parser[i].vram_type + '</span><span>Frekvencia jadra - ' + data_parser[i].gpu_memory_clockrate + '</span></span></div><div class="spodna-cast"><div class="action-buttons"><a class="detail-button">Detail</a><a class="add-button">Vybrať</a></div></div></div></div></div></div></div>';
}
$(".demo").slick('slickAdd', html);
console.log("add");
}
},
error: function (result) {
alert('error');
}
});
}
});
});
What could be causing this and how to prevent it?
This fixed it for me
$(".demo")[0].slick.setPosition();

How to create jQuery datatable with multiple child rows(nested table)?

Question:
I need to create a table with a nested table format. When a user clicks plus button it should show the nested table. If they click minus button it should hide.
I have done jquery datatable its working fine. but I'm not able to display multiple rows for child table. I have tried so many times I'm not able to display proper format.
This is the link I have referred to create a table
https://datatables.net/examples/api/row_details.html
Database:
Actual data coming from the database as per the below format and I have converted JSON format to display :
C# Code:
return new JsonResult { Data = new { data = test }, JsonRequestBehavior =
JsonRequestBehavior.AllowGet };
I need an output like this with a nested table:
UI CODE:
/* Formatting function for row details - modify as you need */
function format ( d ) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-
left:50px;">'+
'<tr>' +
'<td>City Name</td>' +
'<td>Permission</td>' +
'</tr><tr>' +
'<td>' + d.City+ '</td>' +
'<td>' + d.Permission+ '</td>' +
'</tr>' +
'</table>';
}
$(document).ready(function() {
var table = $('#example').DataTable( {
"ajax": "../ajax/data/objects.txt",
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "UserName" },
{ "data": "Email" },
{ "data": "UserId" },
],
"order": [[1, 'asc']]
} );
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
} );
JSON FORMAT:
{"data":[
{"UserId":"ABC","UserName":"Peter","Email":"abc#gmail.com.com","CityName":"Chennai","Permission":"Manager,LocalUser"},
{"UserId":"ABC","UserName":"Peter","Email":"abc#gmail.com.com","CityName":"Bangalore","Permission":"Admin,LocalUser"},
{"UserId":"xyz","UserName":"Haiyan","Email":"abc2#gmail.com.com","CityName":"Bangalore","Permission":"LocalUser"},
{"UserId":"xyz","UserName":"Haiyan","Email":"abc2#gmail.com.com","CityName":"Chennai","Permission":"LocalUser,Manager"}]}
Technology used: ASP.Net MVC5
Any other way I'm ready to use either linq or modify JSON data format.
You can give Id to your child table like this
function format ( d ) {
// `d` is the original data object for the row
return '<table id="childtable" cellpadding="5" cellspacing="0" border="0" style="padding-
left:50px;">'+
'<tr>' +
'<td>City Name</td>' +
'<td>Permission</td>' +
'</tr><tr>' +
'<td>' + d.City+ '</td>' +
'<td>' + d.Permission+ '</td>' +
'</tr>' +
'</table>';
}
and do the same thing which you did for your parent table
var childTable = $('#childtable').DataTable( {
"ajax": "../ajax/data/objects.txt",
"columns": [
],
"order": [[1, 'asc']]
} );
bind your json object in columns section.

Parse JSON from array and objects to HTML table

I have a MySQL db having columns "Name" "Service" "Cost" the output in JSON gives me like this:
"report": [{
"Name": "John",
"Service": "Hands",
"Cost": "200"
}]
}
I want to be able to convert this to a html table. I have tried this:
$(document).ready(function () {
var json = url;
var tr;
for (var i = 0; i < json.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + report.json[i].Name + "</td>");
tr.append("<td>" + report.json[i].Service + "</td>");
tr.append("<td>" + report.json[i].Cost + "</td>");
$('table').append(tr);
}
});
But is not working, simply because i'm don't exactly know what I'm doing :)
Can someone help me?
Thanks!
$(function() { //equivalent to $(document).ready(...
$.getJSON(url,function(data) {
var report=data.report;
// your code here
});
});
Read about getJSON and ajax.

Can't get d3 tooltips to display name, only number

I'm trying to set up d3 tooltips for my choropleth map. I have the tooltips working and am able to pull in the data from lotteryMapNum.json that I am using to assign the map colors, but I can't get any text to show up. I'm either getting "undefined" or NaN no matter what I do. I'm thinking that I need to call the data some other way, but I'm not sure how.
var newDict = {};
d3.json("data/myData/lotteryMapNum.json", function(data) {
data.forEach(function(d) { newDict[d.id] = +d.hopeDollars;})
data.forEach(function(d) { newDict[d.COUNTY] = +d.COUNTY;});
});
d3.json("data/myData/simpleGA.json", function(json) {
counties.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("class", function(d) { return quantize(newDict[d.id]);})
.attr("d", path)
.call(d3.helper.tooltip()
//.attr({class: function(d, i) { return d + ' ' + i + ' A'; }})
.text(function(d){ return 'value: '+newDict[d.id]+newDict[d.COUNTY]; })
)
.on('mouseover', function(d){ d3.select(this).style({fill: 'green', stroke: 'red'}); })
.on('mouseout', function(d){ d3.select(this).style({fill: '', stroke: ''}); });
});
lotteryMapNum.json
[
{"COUNTY":"APPLING",
"hopeDollars":12921240,
"id":"0"}
]
simpleGA.json
{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "id": 0, "properties": { "NAMELSAD10": "Appling County"}, "geometry": { "type": "Polygon", "coordinates": [ [ [ -83.04292, 30.947296 ], [ -83.05332, 30.94753 ],] ] } }
]
}
pretty simple fix i think. try getting rid of the + in front of d.COUNTY and then just making the value of each id key an array:
d3.json("data/myData/lotteryMapNum.json", function(data) {
data.forEach(function(d) { newDict[d.id] = [+d.hopeDollars, d.COUNTY];});
then just access the desires tooltip text in the same way:
.text(function(d){ return 'value: '+ newDict[d.id][0] + newDict[d.id][1]; })
after a quick look, I see two potential problems...
1) It doesn't look like there is any property 'd.COUNTY' in json.features... 'd' in the text() function is referencing the data on the dom element, which comes directly from simpleGA.json ('id' is present, but 'COUNTY' is not.)
Instead, you're probably wanting to reference:
d.properties['NAMELSAD10']
2) The two requests are being loaded in parallel, but one response depends on the other. It is possible that the completion code for simpleGA.json is executing before the lotteryMapNum.json request is complete... in which case the elements of 'newDict' may still be undefined.
A possible solution for this would be to chain the two requests based on the dependency:
var newDict = {};
d3.json("data/myData/lotteryMapNum.json", function(data) {
data.forEach(function(d) { newDict[d.id] = +d.hopeDollars;})
data.forEach(function(d) { newDict[d.COUNTY] = +d.COUNTY;});
d3.json("data/myData/simpleGA.json", function(json) {
counties.selectAll("path")
.data(json.features)
.enter().append("svg:path")
.attr("class", function(d) { return quantize(newDict[d.id]);})
.attr("d", path)
.call(d3.helper.tooltip()
//.attr({class: function(d, i) { return d + ' ' + i + ' A'; }})
.text(function(d){ return 'value: '+newDict[d.id]+newDict[d.COUNTY]; })
)
.on('mouseover', function(d){ d3.select(this).style({fill: 'green', stroke: 'red'}); })
.on('mouseout', function(d){ d3.select(this).style({fill: '', stroke: ''}); });
});
});
If you need more help, post a link to the two .json files and I can better troubleshoot with a jsfiddle.
EDIT: jsfiddle is giving me a lot of woes with large filesizes... but here's basically what I meant with a database-like join... also was working with a list instead of a geojson map:
// load json1
d3.json("lotterMapNum.json", function(lotterMapNum) {
// load json2
d3.json("simpleGA.json", function(simpleGA) {
for (var i = 0; i < simpleGA.features.length; i++) {
newDict[simpleGA.features[i].id] = simpleGA.features[i];
}
for (var j = 0; j < lotteryMapNum.length; j++) {
if (typeof newDict[lotteryMapNum[j].id] === 'undefined') {
newDict[lotteryMapNum[j].id] = {};
}
newDict[lotteryMapNum[j].id].hopeDollars = lotteryMapNum[j].hopeDollars;
newDict[lotteryMapNum[j].id].COUNTY = lotteryMapNum[j].COUNTY;
}
var counties = d3.select('#counties')
.data(newDict)
.enter()
.append('li')
.text(function(d){return d.id + ': ' + d.COUNTY + ', $' + d.hopeDollars;});
});
});

Graph API - FB - Getting crazy already. :s - Getting profile pictures

I can get the profile pictures from this:
data": [
{
"id": "11111111111_22222222222",
"from": {
"name": "Some Name",
"category": "Non-profit organization",
"id": "11222131212211"
},
I'm doing like so:
$.each(json.data,function(i,fb){
html += "<img id=\"image"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
}
No problems.
However, later on the graph I have:
"id": "11111111111_2222222222",
"to": {
"data": [
{
"name": "Some Name",
"category": "Non-profit organization",
"id": "11222131212211"
And I need to grab this id but I've tried:
alert(fb.to.data.id); got nothing.
If I do: alert(fb.to) I got "undefined".
Has anyone had this sort of problems or similar. As you may notice I'm not at all versatle onto programing matters, however, I will do my best to solve this issue.
1) How can I display the profile image on the second case?
2) How can I say: use the fb.from.id only when the graph has that.
About 2), please note that if I comment the line:
//html += "<img id=\"image"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
no images will be show and all post information (except the profile picture) is displayed on the viewport.
If I deal only with the first part of this graph (the one with "from:") I get the picture for that post.
SO, the issue must be, indeed, on the second graph part. The one with the "to:" that I can't grab the ID.
I've tried, as well, to avoid rendering the image on the second case but, at least run the first one. No luck at all.
if (fb.from.id != undefined) {
//do something;
}
The second part of the graph still returns an error.
With all this mess, that I can re-arrange, can I please ask your help. :S
**
Update:
**
The js code:
function fbFetch(){
var url = "https://graph.facebook.com/125120007543580/feed&callback=?&limit=2";
var i = 0;
//Use jQuery getJSON method to fetch the data from the url and then create our unordered list with the relevant data.
$.getJSON(url,function(json){
var html = "<div id=\"faceWall\">";
//loop through and within data array's retrieve the message variable.
$.each(json.data,function(i,fb){
var idTotal = fb.id;
var ids = idTotal.split("_");
var href = "http://www.facebook.com/"+ids[0]+"/posts/"+ids[1];
var msg = fb.message;
//adicionado
if (msg == undefined) {
msg = 'Cick here to see the post title';
} else if (msg.length > 150) {
msg = msg.substr(0,200)+"...";
}
//ISSUE HERE. IF I COMMENT THIS LINE ALL GOES WELL BUT NO PROFILE PICTURES ARE DISPLAYED.
html += "<img id=\"imagem"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
html += "<div id=\"textoFaceWall\">";
html += "<p id=\"msg"+i+"\">";
//adicionado fb.name em vez de fb.from.name:
if (fb.name == undefined) {
html += "" + fb.from.name + " - " + msg + "</p>";
} else {
html += "" + fb.name + " - " + msg + "</p>";
}
html += "<p class=\"dataPostWall\" id=\"data"+i+"\">"+ dataFinal + "</p> ";
html += "</p>";
html += "</div>";
html += "<img class=\"linhaHomePageCanais\" src=\""+baseUrl+"/lib/img/linhaWall.png\" alt=\"linha wall\"/>";
});
html += "</div>";
$("#coluna2").append(html);
});
};
fbFetch();
And part of the graph:
({
"data": [
{
"id": "125120007543580_150880001634837",
"from": {
"name": "Some Name",
"category": "Non-profit organization",
"id": "125120007543580"
},
{
"id": "125120007543580_111122368963254",
"to": {
"data": [
{
"name": "Some Name",
"category": "Non-profit organization",
"id": "125120007543580"
}
]
},
I need to display the profile from fb.to.data.id,
I now notice, however, that data has [ instead of {, and that could mean that, in order to access id, I need to use another syntax perhaps?
Since the to parameters can holds more that one user, it's an array of objects. So you need to loop over that too:
if(fb.to) {
$.each(fb.to.data, function(j,to_user) {
// now you access it to_user.id
});
}
If you only want to show the first profile picture then use fb.to.data[0].id.
EDIT:
Okay, based on your comments and updated, here is your code with a working approach:
function fbFetch(){
var url = "https://graph.facebook.com/125120007543580/feed&callback=?&limit=2";
var i = 0;
//Use jQuery getJSON method to fetch the data from the url and then create our unordered list with the relevant data.
$.getJSON(url,function(json){
var html = "<div id=\"faceWall\">";
//loop through and within data array's retrieve the message variable.
$.each(json.data,function(i,fb){
var idTotal = fb.id;
var ids = idTotal.split("_");
var href = "http://www.facebook.com/"+ids[0]+"/posts/"+ids[1];
var msg = fb.message;
//adicionado
if (msg == undefined) {
msg = 'Cick here to see the post title';
} else if (msg.length > 150) {
msg = msg.substr(0,200)+"...";
}
//ISSUE HERE. IF I COMMENT THIS LINE ALL GOES WELL BUT NO PROFILE PICTURES ARE DISPLAYED.
if(fb.from)
html += "<img id=\"imagem"+i+"\" src=\"http://graph.facebook.com/" + fb.from.id + "/picture\"/>";
if(fb.to) {
$.each(fb.to.data, function(j,to_user) {
html += "<img id=\"imagem"+i+"-"+j+"\" src=\"http://graph.facebook.com/" + to_user.id + "/picture\"/>";
});
}
html += "<div id=\"textoFaceWall\">";
html += "<p id=\"msg"+i+"\">";
//adicionado fb.name em vez de fb.from.name:
if (fb.name == undefined) {
html += "" + fb.from.name + " - " + msg + "</p>";
} else {
html += "" + fb.name + " - " + msg + "</p>";
}
html += "<p class=\"dataPostWall\" id=\"data"+i+"\">"+ dataFinal + "</p> ";
html += "</p>";
html += "</div>";
html += "<img class=\"linhaHomePageCanais\" src=\""+baseUrl+"/lib/img/linhaWall.png\" alt=\"linha wall\"/>";
});
html += "</div>";
$("#coluna2").append(html);
});
};
fbFetch();
You may try this for PHP
$request_url = 'http://graph.facebook.com/redbull/picture?redirect=false';
$requests = file_get_contents($request_url);
$fb_response = json_decode($requests);
$imagen[]=$fb_response->data->url;
There you get the URL of the picture from the URL item in the JSON Graph api call.