datatable ajax xml display with master-detail relationship - javascript

Through that jQ bootstrap 4 datatable grid (datatable.net) I want for tabular display the following xml file:
<?xml version="1.0" encoding="UTF-8"?>
<persns>
<prsn>
<fname>Smith</fname> <!-- first name-->
<lname>Milton</lname> <!-- last name -->
<age>44</age>
<e-mail>smilt#gmail.com</e-mail>
<phnmbr>3568236712</phnmbr>
<addrss>5th summer st, mntb</addrss>
<city>Portland</city>
</prsn>
<prsn>
<fname>Ken</fname>
<lname>Jackson</lname>
<age>37</age>
<e-mail>ken.jackson#yahoo.com</e-mail>
<phnmbr>2638762076</phnmbr>
<addrss>19th Penfield ave, brtcl</addrss>
<city>Kelowna</city>
</prsn>
<prsn>
<fname>Susan</fname>
<lname>Arkland</lname>
<age>48</age>
<e-mail>s.arklnd#hotmail.com</e-mail>
<phnmbr>50834219704</phnmbr>
<addrss>34th Mansfield st, sgtp</addrss>
<city>Raleigh</city>
</prsn>
<prsn>
<fname>Patsy</fname>
<lname>Brighton</lname>
<age>38</age>
<e-mail>patsy.brghton#gmail.com</e-mail>
<phnmbr>814522096358</phnmbr>
<addrss>12th Peel st, pnslv</addrss>
<city>Philadelphia</city>
</prsn>
<prsn>
<fname>John</fname>
<lname>Torg</lname>
<age>54</age>
<e-mail>john.torg#tzeus.com</e-mail>
<phnmbr>042197327784</phnmbr>
<addrss>27th north st, cnda</addrss>
<city>Penticton</city>
</prsn>
but with master-detail functionality as it is shown over the following fiddle link:
https://jsfiddle.net/nnb97rh9/3/
Only that up to that fiddle there is .json data ! (and I need for .xml display)
The corresponding (almost functional) .js (through the master table I only want to display the following table headers:
fname, lname, age, city while the rest would be hidden; they'll only be displayed as related child table lines) is as follows:
$(function(){
var prstbl = $("#prsns").dataTable(columns: [{"class":'details-control',
"orderable":false, "data":null, "defaultContent":''},
{dtaTbl:"fname"},
{dtaTbl:"lname"},
{dtaTbl:"age"},
{dtaTbl:"city"},
{dtaTbl:"e-mail", "visible":false},
{dtaTbl:"phnmbr", "visible":false},
{dtaTbl:"addrss", "visible":false}
]}),
oTable = $('#prsne').DataTable()
function format(d)
{
return '<table cellpadding="3" cellspacing="0" border="0" style="padding-
left:40px">'
+ '<tr>' + '<td>e-mail addrss</td>'
+ '<td>' + d.email + '</td>' + '</tr>'
+ '<tr>' + '<td>phn nmber</td>'
+ '<td>' + d.phnmbr + '</td>' + '</tr>'
+ '<tr>' + '<td>address</td>'
+ '<td>' + d.addrss + '</td>' + '</tr>'
+ '</table>'
}
$.ajax({type:"GET", url:"persns.xml", dataType:"xml", success:
function(xml)
{
var prsns = $(xml).find("prsn")
prsns.each(function(idx, prs)
{
var prs = $(prs), dtaTbl = []
prs.children().each(function(j,chdnd)
{
dtaTbl.push($(chdnd).text())
})
prstbl.fnAddData(dtaTbl)
})
}
})
$('#prsns tbody').on('click', 'td.details-control', function()
{
var tr = $(this).closest('tr'),
row = oTable.row(tr)
if(row.child.isShown()) // if the row is already expanded,
collapse it
{
row.child.hide()
tr.removeClass('shown')
}
else // if collapsed row, expandit it
{
row.child(format(row.data())).show()
tr.addClass('shown')
}
})
})
The relevant .html part is like this:
<body>
<h5>Master-detail persons display</h5>
<table id="prsns" border="1" class="table display" width="60%">
<thead><tr><th></th><th>frst nme</th><th>name</th><th>age</th>
<th>city</th> <th>e-mail addrss</th></tr></thead>
<tbody></tbody>
</table>
</body>
And there is also a small .css file like this:
td.details-control
{
background:url('https://raw.githubusercontent.com/DataTables/DataTables/1.10.7/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control
{ background:url('https://raw.githubusercontent.com/DataTables/DataTables/1.10.7/examples/resources/details_close.png') no-repeat center center;
}
I repeat, all the displaying I need to be done regarding this .xml file and not .json or only .html !
I know how to do it with .json table.
So you guys please help me with this issue.
Thank you all in advance

There are multiple issues with the code, too much to describe. Below is the corrected code.
Please note I am using jsFiddle mechanism to retrieve XML file, replace with your own.
(function () {
function format(d) {
return '<table cellpadding="3" cellspacing="0" border="0" style="padding-left: 40 px ">' +
'<tr>' + '<td>e-mail addrss</td>' +
'<td>' + d['e-mail'] + '</td>' + '</tr>' +
'<tr>' + '<td>phn nmber</td>' +
'<td>' + d['phnmbr'] + '</td>' + '</tr>' +
'<tr>' + '<td>address</td>' +
'<td>' + d['addrss'] + '</td>' + '</tr>' +
'</table>';
}
var prstbl = $("#prsns").DataTable({
columns: [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
data: "fname"
},
{
data: "lname"
},
{
data: "age"
},
{
data: "city"
},
{
data: "e-mail",
"visible": false
},
{
data: "phnmbr",
"visible": false
},
{
data: "addrss",
"visible": false
}
]
});
$.ajax({
type: "POST",
url: "/echo/xml",
data: {
xml: '<?xml version="1.0" encoding="UTF-8" ?><persns>'
+ '<prsn><fname>Smith</fname><lname>Milton</lname><age>44</age><e-mail>smilt#gmail.com</e-mail><phnmbr>3568236712</phnmbr><addrss>5th summer st, mntb</addrss><city>Portland</city></prsn>'
+ '<prsn><fname>Ken</fname><lname>Jackson</lname><age>37</age><e-mail>ken.jackson#yahoo.com</e-mail><phnmbr>2638762076</phnmbr><addrss>19th Penfield ave, brtcl</addrss><city>Kelowna</city></prsn>'
+ '<prsn><fname>Susan</fname><lname>Arkland</lname><age>48</age><e-mail>s.arklnd#hotmail.com</e-mail><phnmbr>50834219704</phnmbr><addrss>34th Mansfield st, sgtp</addrss><city>Raleigh</city></prsn>'
+ '<prsn><fname>Patsy</fname><lname>Brighton</lname><age>38</age><e-mail>patsy.brghton#gmail.com</e-mail><phnmbr>814522096358</phnmbr><addrss>12th Peel st, pnslv</addrss><city>Philadelphia</city></prsn>'
+ '<prsn><fname>John</fname><lname>Torg</lname><age>54</age><e-mail>john.torg#tzeus.com</e-mail><phnmbr>042197327784</phnmbr><addrss>27th north st, cnda</addrss><city>Penticton</city></prsn>'
+ '</persns>',
},
dataType: 'xml',
success: function (xml) {
var prsns = $(xml).find("prsn");
prsns.each(function (idx, prs) {
var rowData = [];
$(prs).children().each(function (j, chdnd) {
rowData[$(chdnd).get(0).tagName] = $(chdnd).text();
});
prstbl.row.add(rowData);
});
prstbl.draw();
}
});
$('#prsns tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = prstbl.row(tr);
// if the row is already expanded, collapse it
if (row.child.isShown()) {
row.child.hide();
tr.removeClass('shown');
// if collapsed row, expand it
} else {
row.child(format(row.data())).show();
tr.addClass('shown');
}
});
})();
See updated example for code and demonstration.

Related

build unique table with JQuery AJAX

I have a script that builds a table and makes it editable once the user clicks on a cell. The User then leaves a comment and it will update the JSON file as well as the HTML table.
The problem I am having is that if I have two tables with separate JSON files, how can I implement the same script on both of the tables? Would I have to have two separate scripts for each table? How can I do it based off the ID of the table
JSON1:
[{"GLComment":"comment from table 1","EnComment":""},
{"GLComment":"","EnComment":""}]
JSON2:
[{"GLComment":"comment from table 2","EnComment":""},
{"GLComment":"","EnComment":""}]
I have tried doing this to append to my existing table
var tblSomething = document.getElementById("table1");
<table class="table 1">
<thead>
<th id = "white">GL Comment</th>
<th id = "white">En Comment</th>
</thead>
</table>
//table does not get built here only for table 1
<table class="table 2">
<thead>
<th id = "white">GL Comment</th>
<th id = "white">En Comment</th>
</thead>
</table>
<script>
//this only works for table1
$(document).ready(function() {
infoTableJson = {}
buildInfoTable();
});
function buildInfoTable(){
$.ajax({ //allows to updates without refreshing
url: "comment1.json", //first json file
success: function(data){
data = JSON.parse(data)
var tblSomething = '<tbody>';
$.each(data, function(idx, obj){
//Outer .each loop is for traversing the JSON rows
tblSomething += '<tr>';
//Inner .each loop is for traversing JSON columns
$.each(obj, function(key, value){
tblSomething += '<td data-key="' + key + '">' + value + '</td>';
});
//tblSomething += '<td><button class="editrow"></button></td>'
tblSomething += '</tr>';
});
tblSomething += '</tbody>';
$('.table').append(tblSomething)
$('.table td').on('click', function() {
var row = $(this).closest('tr')
var index = row.index();
var comment = row.find('td:nth-child(1)').text().split(',')[0]
var engcomment = row.find('td:nth-child(2)').text().split(',')[0]
var temp1 = row.find('td:nth-child(1)').text().split(',')[0]
var temp2 = row.find('td:nth-child(2)').text().split(',')[0]
var newDialog = $("<div>", {
id: "edit-form"
});
newDialog.append("<label style='display: block;'>GL Comment</label><input style='width: 300px'; type='text' id='commentInput' value='" + comment + "'/>");
newDialog.append("<label style='display: block;'>Eng Comment</label><input style='width: 300px'; type='text' id='engInput' value='" + engcomment + "'/>");
// JQUERY UI DIALOG
newDialog.dialog({
resizable: false,
title: 'Edit',
height: 350,
width: 350,
modal: true,
autoOpen: false,
buttons: [{
text: "Save",
click: function() {
console.log(index);
user = $.cookie('IDSID')
var today = new Date();
var date = (today.getMonth()+1)+'/'+today.getDate() +'/'+ today.getFullYear();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
//FIXME
var comment = newDialog.find('#commentInput').val() + ", <br> <br>" + dateTime + " " + user;
var engcomment = newDialog.find('#engInput').val() + ", <br><br>" + dateTime + " " + user; //it updates both of them no
row.find('td[data-key="GLComment"]').html(comment) //this is what changes the table
row.find('td[data-key="EngComment"]').html(engcomment) //this is what changes the table
// update data
data[index].GLComment = comment;
data[index].EngComment =engcomment;
$.ajax({
type: "POST",
url: "save.asp",
data: {'data' : JSON.stringify(data) , 'path' : 'comments.json'},
success: function(){},
failure: function(errMsg) {
alert(errMsg);
}
});
$(this).dialog("close");
$(this).dialog('destroy').remove()
}
}, {
text: "Cancel",
click: function() {
$(this).dialog("close");
$(this).dialog('destroy').remove()
}
}]
});
//$("body").append(newDialog);
newDialog.dialog("open");
})
},
error: function(jqXHR, textStatus, errorThrown){
alert('Hey, something went wrong because: ' + errorThrown);
}
});
}
</script>
The "key" here is prebuilt table... And that is a good job for the jQuery .clone() method.
$(document).ready(function() {
// call the function and pass the json url
buildInfoTable("comment1.json");
buildInfoTable("comment2.json");
// Just to disable the snippet errors for this demo
// So the ajax aren't done
// No need to run the snippet :D
$.ajax = ()=>{}
});
function buildInfoTable(jsonurl){
$.ajax({
url: jsonurl,
success: function(data){
data = JSON.parse(data)
// Clone the prebuild table
// and remove the prebuild class
var dynamicTable = $(".prebuild").clone().removeClass("prebuild");
// Loop the json to create the table rows
$.each(data, function(idx, obj){
rows = '<tr>';
$.each(obj, function(key, value){
rows += '<td data-key="' + key + '">' + value + '</td>';
});
rows += '</tr>';
});
// Append the rows the the cloned table
dynamicTable.find("tbody").append(rows)
// Append the cloned table to document's body
$("body").append(dynamicTable)
}
})
}
</script>
/* This class hides the prebuid table */
.prebuild{
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- This table is a "template" It never will be used but will be cloned -->
<table class="prebuild">
<thead>
<th id = "white">GL Comment</th>
<th id = "white">En Comment</th>
</thead>
<tbody>
</tbody>
</table>

Issues while displaying JSON data in table

I'm having an issue while displaying json data in an html table. I believe it has to do with the fact that my json's formatted really strange (i can't change it)
Thanks in advance.
{"name":["instance-5","instance-6"],"id"["1178823664323071067","5394281241544297728"],"ip":["35.189.8.115","35.201.16.102"],"status":["RUNNING","RUNNING"]}
<script>
$( document ).ready(function() {
$.ajax({
url: '/api/instance/list',
type: 'get',
dataType: 'json',
error: function(data){
},
success: function(data){
var tr = $('<tr>');
tr.append('<td>' + data.name + '<td>');
tr.append('<td>' + data.id + '<td>');
tr.append('<td>' + data.ip + '<td>');
tr.append('<td>' + data.status + '<td>');
$('#application-table').append(tr);
}
});
});
</script>
<table id="application-table" class="aui">
<thead>
<tr>
<th width="20%">Instance Name</th>
<th width="20%">ID</th>
<th width="20%">IP</th>
<th width="5%">Status</th>
</tr>
</thead>
Your response is formatted such that each property is its own array, presumably meaning that name[0] is related to all the other [0] indexed items in the other arrays.
Therefore to achieve what you require you can loop over the response and put all the values within the properties at the same index within the new row, like this:
var data = {
"name": ["instance-5", "instance-6"],
"id": ["1178823664323071067", "5394281241544297728"],
"ip": ["35.189.8.115", "35.201.16.102"],
"status": ["RUNNING", "RUNNING"]
}
for (var i = 0; i < data.name.length; i++) {
var tr = $('<tr>');
tr.append('<td>' + data.name[i] + '<td>');
tr.append('<td>' + data.id[i] + '<td>');
tr.append('<td>' + data.ip[i] + '<td>');
tr.append('<td>' + data.status[i] + '<td>');
$('#application-table').append(tr);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="application-table"></table>
That said, I'd recommend finding a way to change your response structure to relate row data in each item of a single array, something like this:
var data = [{
"name": "instance-5",
"id": "1178823664323071067",
"ip": "35.189.8.115",
"status": "RUNNING"
}, {
"name": "instance-6",
"id": "1178823664323071067",
"ip": "35.201.16.102",
"status": "RUNNING"
}]
var html = data.map(function(row) {
return `<tr><td>${row.name}</td><td>${row.id}</td><td>${row.ip}</td><td>${row.status}</td></tr>`;
});
$('#application-table').append(html.join(''));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="application-table"></table>

LocalStorage : Row Table not display when page reloaded

Good Morning.
I already store table into localStorage.
but when im reload the page, The Row in the Default Table not displaying.
and if i'm disable initialization it's will be working fine,
but not when i'm Add new table, The Default Table will not displayed when page reloaded :
// Defaul Table
$("#mainTable").dataTable({
"ajax": "https://api.myjson.com/bins/1hes6z",
"columns": [{
"data": "id"
}, {
"data": "name"
}, {
"data": "subtype"
}, {
"data": "approximate_count"
}, {
"data": "time_created"
}],
});
/* CREATE TABLE FITURE */
$('.submitButton').click(function() {
function getTableList() {
var addTable = '<div class="tab-pane" id="folder' + localStorage.Index + '">' +
'<div class="zf-table">' +
'<table id="table' + localStorage.Index + '" class="table table-bordered table-hover myFade dynamicTable">' +
'<thead>' +
'<tr>' +
'<th style="border-color:rgb(221, 221, 221);"> </th>' +
'<th>Audience Name</th>' +
'<th>Type</th>' +
'<th>Size</th>' +
'<th>Date Created</th>' +
'<th>Action</th>' +
'</tr>' +
'</thead><tbody></tbody>' +
'</table>' +
'</div>' +
'</div>';
return addTable;
}
if (true) {
/** INDEX FOR INCREMENT ID **/
if (typeof(Storage) !== "undefined") {
if (localStorage.Index) {
localStorage.Index = Number(localStorage.Index) + 1;
} else {
localStorage.Index = 1;
}
} // if storage
var resultTable = JSON.parse(localStorage.getItem("tableList"));
if (resultTable == null) {
resultTable = [];
}
let newtableHTML = getTableList();
resultTable.push({
table: newtableHTML
});
// save the new resultFolder array
localStorage.setItem("tableList", JSON.stringify(resultTable));
/* append Table baru */
$('.tab-content').append(newtableHTML);
var newTable = $("#table" + localStorage.Index).dataTable();
alert("sucess create table");
} else {
alert("Failed create Table");
}
}); // submitButton func
//on init fill the table-content
$(document).ready(function() {
$("#mainTable").dataTable();
var resultTable = JSON.parse(localStorage.getItem("tableList"));
if (resultTable != null) {
//get the nav reference in DOM
let tableContent = $(".tab-content");
//clear the html contents
tableContent.html('');
for (var i = 0; i < resultTable.length; i++) {
var items = resultTable[i];
$(".tab-content").append(items.table);
}
$(".dynamicTable").dataTable();
} else {
let inititalTable = [];
inititalTable.push({
table: $('div.tab-content').html()
});
localStorage.setItem("tableList", JSON.stringify(inititalTable));
}
});
How to display the row table when page reloaded without deleting initialTable code?
JSFiddle Demo

How to create tables in jQuery for $.each()

I am a beginner programmer that is trying to display data results I get from Etsy API into a table as shown below:
<tr><td>item.images</td><td><tr>item.title</tr><tr>item.price</tr></tr>
However, I am unable to display the results in a table and am having problems applying the solutions to my situation
Here is the set of working codes, and I have commented out my failed attempts.
<script type="text/javascript">
(function($){
$(document).ready(function(){
$('#etsy-search').bind('submit', function() {
api_key = "XXXXXXXXXXXXXXXXXXXXX";
terms = $('#etsy-terms').val();
etsyURL = "https://openapi.etsy.com/v2/listings/active.js?keywords="+
terms+"&limit=3&includes=Images:1&api_key="+api_key;
$('#etsy-images').empty();
$('<p></p>').text('Searching for '+terms).appendTo('#etsy-images');
$.ajax({
url: etsyURL,
dataType: 'jsonp',
success: function(data) {
if (data.ok) {
// Commented out are my failed attempt
//var table = "<table>";
$('#etsy-images').empty();
if (data.count > 0) {
$.each(data.results, function(i,item) {
$("<img/>").attr("src", item.Images[0].url_75x75).appendTo("#etsy-images").wrap(
"<a href='" + item.url + "'></a>"
//table+='<tr><td>'+item.title+'</td><td>'+item.price+'</td></tr>';
//}
);
// table+='</table>';
// $("#etsy-images").html( table );
if (i%4 == 3) {
$('<br/>').appendTo('#etsy-images');
}
});
} else {
$('<p>No results.</p>').appendTo('#etsy-images');
}
} else {
$('#etsy-images').empty();
alert(data.error);
}
}
});
return false;
})
});
})(jQuery);
</script>
<body>
<form id="etsy-search">
<input id="etsy-terms" size="32">
<button>Search!</button>
</form>
<div id="etsy-images"></div>
</body>
Additional info:
1. Currently the results looks like this:
After a successful search, the JSON results looks like this:
[
{
"listing_id": 123,
"state": "active",
"user_id": 123,
"category_id": 123,
"title": "XXX",
"price": "2.99",
"currency_code": "USD"
....
}
]
I eventually used trHTML to format the table:
var trHTML = '';
$('#etsy-table').empty();
$.each(data.results, function(i,item) {
trHTML += '<tr><td>' + '<a href="'
+ item.url +'" target="_blank" style="color: white"><img src="'
+ item.Images[0].url_75x75 + '" border="0"></a></td><td><tr>'
+ item.title + '</tr><tr>'
+ item.price + '</tr><tr><a href="'
+ vimg +'" target="_blank" style="color: white"><img class="autosizeImage"src="'
+ vimg + '" border="0"></a></tr></td></tr>';
})
$('#etsy-table').append(trHTML);
Firts step check the "crossdomain" someones browsers don't allow get data between different domains, you can enabled it with headers to allow than.

datatable append html but got refreshed?

Not sure what is wrong, for me my code has the right logic. But somehow the html didn't stay after 2nd click onward. I expect my custom html would appear after the newly added tr.
my function
function appendRow(name, position, office, age, date,salary) {
var t = $('#example').DataTable();
var node = t.row.add([
name,
position,
office,
age,
date,
salary,
]).draw().node();
var detail_row = '';
detail_row = '<h3>Custom HTML</h3>';
$(node).addClass('result-row');
node = node.outerHTML += detail_row;
$(node).hide().fadeIn('normal');
}
https://jsfiddle.net/282w8yfk/
it is happening in this way because you applied sorting on the name column, so datatable being quite smart it adds the row where it needs to be... so if you want to add that in the last remove sorting option on name column...
and here is a small code change:
$(document).ready(function() {
/* Formatting function for row details - modify as you need */
function format(d) {
console.log(d);
// `d` is the original data object for the row
return '<table cellpadding="4" cellspacing="0" border="0" style="padding-left:50px;">' +
'<tr>' +
'<td>Name:</td>' +
'<td>' + d[0] + '</td>' +
'</tr>' +
'<tr>' +
'<td>Full Name:</td>' +
'<td>' + d[4] + '</td>' +
'</tr>' +
'<tr>' +
'<td>Extra info:</td>' +
'<td>And any further details here (images etc)...</td>' +
'</tr>' +
'</table>';
}
var table = $('#example').DataTable({
"columnDefs": [{
"targets": [4],
"visible": false,
"searchable": false
}]
/* the problem is here, it won't work if I enable sorting*/
});
function appendRow() {
var t = $('#example').DataTable();
var node = t.row.add([
"James Bond",
"Spy", "55", "$9000", "James Bond Larry"
]).draw().node();
console.log(node);
$(node).addClass('result-row').hide().fadeIn('normal');
};
$('#add').click(function() {
appendRow();
});
$('#example tbody').on('click', '.result-row', 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');
}
});
});
reference 1 - sort
reference 2 - row.add

Categories

Resources