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.
Related
Looking for a solution to achieve an HTML table that takes the "title" from the JSON file and puts it in the first column of a 2 column table and the second column has the "description".
The description has to be tier as bullet points as it is an array within an array in the JSON file. The current way it is working is that it is one big block of data in the second column which looks like a giant sentence. I've tried putting each bullet point into its separate key pair but it is not feasible as it is time-consuming. Is there an option for an if statement that iterates over the array within an array? Open for other script alternatives.
var data = [
{
"title": "title1",
"description":["description1","description2"]
},
{
"title": "title2",
"description":["description3","description4"]
}
]
$(document).ready(function(){
var list = '';
$.each(data, function(key, value){
list += '<tr>';
list += '<td>'+value.title+'</td>';
list += '<td>'+value.description+'</td>'
list += '</tr>';
});
$('#table1').append(list);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table" id="table1">
<tr>
<th>Title</th>
<th>Description</th>
</tr>
</table>
Your current method is fine. You just need to add an $.each inside an $.each:
$(document).ready(function () {
$.getJSON("data.json", function (data) {
var list = '';
$.each(data, function (key, value) {
list += '<tr><td>' +
value.title +
'</td><td><ul>';
$.each(value.description, function (key, value) {
list += "<li>" + value + "</li>";
})
list += '</ul></td></tr>';
});
$('#table1').append(list);
});
});
var data = [{
"title": "title1",
"description": ["description1", "description2"]
},
{
"title": "title2",
"description": ["description3", "description4"]
}
]
$(document).ready(function() {
var list = '';
$.each(data, function(key, value) {
list += '<tr><td>' +
value.title +
'</td><td><ul>';
$.each(value.description, function(key, value) {
list += "<li>" + value + "</li>";
})
list += '</ul></td></tr>';
});
$('#table1').append(list);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table" id="table1">
<tr>
<th>Title</th>
<th>Description</th>
</tr>
</table>
EDIT: Improved Version:
JSFiddle
We would be grateful for some guidance, [we are early into coding] and have looked at lots of examples but can cannot get our JSON to import into the table.
At that moment we have the table data in-line however a correctly formatted JSON file is now available and automatically updates and we want to load it into the table on the fly when the page is loaded.
This is an example of what were currently use:
<div>
<p> *** OTHER STUFF HERE ***<p/>
<table id="gable">
<colgroup>
<col class="twenty" />
<col class="fourty" />
<col class="thirtyfive" />
<col class="twentyfive" />
</colgroup>
<tr>
<th onclick="sortTable(0)"><span class="glyphicon glyphicon-sort"></span>  COUNTRY</th>
<th onclick="sortTable(1)"><span class="glyphicon glyphicon-sort"></span>  LOCATION</th>
<th onclick="sortTable(2)"><span class="glyphicon glyphicon-sort"></span>  BALANCE</th>
<th onclick="sortTable(3)"><span class="glyphicon glyphicon-sort"></span>  DATE</th>
</tr>
</table>
</div>
<script>
var data = [
{ "COUNTRY":"UK", "LoC":"London", "BALANCE":"78,573", "DATE":"1/06/2018" },
{ "COUNTRY":"US", "LoC":"New York", "BALANCE":"43,568", "DATE":"18/05/2018" },
{ "COUNTRY":"PL", "LoC":"Kraków", "BALANCE":"12,362", "DATE":"22/06/2018" },
{ "COUNTRY":"AU", "LoC":"Townsville", "BALANCE":"7,569", "DATE":"1/07/2018" },
{ "COUNTRY":" ", "LoC":"BALANCE:", "BALANCE":"142,072", "DATE":" " }
];
var table = document.getElementById('gable');
data.forEach(function(object) {
var tr = document.createElement('tr');
tr.innerHTML = '<td>' + object.COUNTRY + '</td>' +
'<td>' + object.LoC + '</td>' +
'<td>' + object.BALANCE + '</td>' +
'<td>' + object.DATE + '</td>';
table.appendChild(tr);
});
</script>
There are a lot more lines of data, the table has CSS styling and applies the sortTable(n) function to the Headers. It displays perfectly, looks and functions like we want,
We've Googled [lots] and tried various load / populate scripts and attempted to get the example on w3schools working - https://www.w3schools.com/js/js_json_html.asp - alas we're fairly new to this.
Our JSON file /assets/sample.JSON is correctly formatted and meets the requirements.
How do we do a simple import of the JSON to populate the table id="gable"?
Ok, so in this solution I am going to assume that your external json file is called 'example.json'
Your external file should look something like this
example.json:
[
{ "COUNTRY":"UK", "LoC":"London", "BALANCE":"78,573", "DATE":"1/06/2018" },
{ "COUNTRY":"US", "LoC":"New York", "BALANCE":"43,568", "DATE":"18/05/2018" },
{ "COUNTRY":"PL", "LoC":"Kraków", "BALANCE":"12,362", "DATE":"22/06/2018" },
{ "COUNTRY":"AU", "LoC":"Townsville", "BALANCE":"7,569", "DATE":"1/07/2018" },
{ "COUNTRY":" ", "LoC":"BALANCE:", "BALANCE":"142,072", "DATE":" " }
]
The html remains the same all the changes have been made in the script tags. I split the functionality into 2 new functions. The first function (get_json_data) gets the json data from the external json file. The second function (append_json) appends the data to the table.
I have put comments throughout the code to explain what everything is doing. if you have any questions or if something is unclear let me know.
here is the code for the html file:
<div>
<p> *** OTHER STUFF HERE ***<p/>
<table id="gable">
<colgroup>
<col class="twenty" />
<col class="fourty" />
<col class="thirtyfive" />
<col class="twentyfive" />
</colgroup>
<tr>
<th onclick="sortTable(0)"><span class="glyphicon glyphicon-sort"></span>  COUNTRY</th>
<th onclick="sortTable(1)"><span class="glyphicon glyphicon-sort"></span>  LOCATION</th>
<th onclick="sortTable(2)"><span class="glyphicon glyphicon-sort"></span>  BALANCE</th>
<th onclick="sortTable(3)"><span class="glyphicon glyphicon-sort"></span>  DATE</th>
</tr>
</table>
</div>
<script>
//first add an event listener for page load
document.addEventListener( "DOMContentLoaded", get_json_data, false ); // get_json_data is the function name that will fire on page load
//this function is in the event listener and will execute on page load
function get_json_data(){
// Relative URL of external json file
var json_url = 'example.json';
//Build the XMLHttpRequest (aka AJAX Request)
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {//when a good response is given do this
var data = JSON.parse(this.responseText); // convert the response to a json object
append_json(data);// pass the json object to the append_json function
}
}
//set the request destination and type
xmlhttp.open("POST", json_url, true);
//set required headers for the request
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// send the request
xmlhttp.send(); // when the request completes it will execute the code in onreadystatechange section
}
//this function appends the json data to the table 'gable'
function append_json(data){
var table = document.getElementById('gable');
data.forEach(function(object) {
var tr = document.createElement('tr');
tr.innerHTML = '<td>' + object.COUNTRY + '</td>' +
'<td>' + object.LoC + '</td>' +
'<td>' + object.BALANCE + '</td>' +
'<td>' + object.DATE + '</td>';
table.appendChild(tr);
});
}
</script>
you can have a function to create the table independent from your data fields:
function updateTable(tableId, jsonData){
var tableHTML = "<tr>";
for (var headers in jsonData[0]) {
tableHTML += "<th>" + headers + "</th>";
}
tableHTML += "</tr>";
for (var eachItem in jsonData) {
tableHTML += "<tr>";
var dataObj = jsonData[eachItem];
for (var eachValue in dataObj){
tableHTML += "<td>" + dataObj[eachValue] + "</td>";
}
tableHTML += "</tr>";
}
document.getElementById(tableId).innerHTML = tableHTML;
}
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);
}
} );
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.
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.