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

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.

Related

datatable ajax xml display with master-detail relationship

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.

Why my dataTables does not appear using $.each inside function?

I have nested array json object (Layer 1, Layer 2 and Layer 3). My problem is dataTables does not appear. Any related CDN has been imported. The table just only display <thead> section. I have referred many websites, but it did not solve my problem.
Earlier I was using standard table to display the values inside Layer 3 json using <tbody>, <tr> and <td>, do the result is successful. But now I removed all that and try to use dataTable as I need its' features.
I successfully displayed value id for Layer 1 and Layer 2. But for my case below, it is unsuccessfully to display Layer 3 information (l3_id, l3_name, etc..) in dataTables.
JSON
{
"status": "Success",
"data": [{
"project_id": "1",
"project_name": "project name",
"l1_task": [{
"l1_id": "1",
"l1_name": "Layer 1",
"l2_task": [{
"l2_id": "1",
"l2_name": "Layer 2",
"l3_task": [{
"l3_id": "1",
"l3_name": "Layer 3.1"
},
{
"l3_id": "2",
"l3_name": "Layer 3.2"
}
]
}]
}]
}]
}
JS
$(document).ready(function() {
loadtable();
$('#Layer3Table').DataTable({
ajax: {
url: "exampleData/activity.json"
},
columns: [{
data: "l1_task.0.l2_task.0.l3_task.0.l3_id"
},
{
data: "l1_task.0.l2_task.0.l3_task.0.l3_name"
}
],
});
function loadtable() {
var project = '';
$.ajax({
url: url_project_detail,
crossDomain: true,
type: 'POST',
dataType: 'json',
data: "data",
success: function(response) {
if (response.status == "Success") {
// Layer 1 array object
$.each(response.data[0].l1_task, function(key, value) {
project +=
"<div>" +
"<div>";
// Layer 2 array object
$.each(value.l2_task, function(key, value) {
project +=
"<div>" +
"<div>" +
// Layer 3 array object
"<div class='table-responsive'>" +
"<table id='Layer3Table' class='table table-striped' style='width:100%'>" +
"<thead>" +
"<tr>" +
"<th class='text-center'>ID</th>" +
"<th class='text-center'>Activity Name</th>" +
"</tr>" +
"</thead>" +
"</table>" +
"</div>";
}); // for Layer 2
project += "</div>" + "</div>";
}); // for Layer 1
$("#projectDetail2").append(project);
} else {}
},
error: function(e) {}
});
}
});
I just got the solution by removing this dataTables.
$('#Layer3Table').DataTable({
ajax: {
url: "exampleData/activity.json"
},
columns: [{
data: "l1_task.0.l2_task.0.l3_task.0.l3_id"
},
{
data: "l1_task.0.l2_task.0.l3_task.0.l3_name"
}
],
});
and initiate dataTables at this section
}); // for Layer 1
$("#projectDetail2").append(project);
$('#Layer3Table').DataTable();
} else {}
UPDATE
Nice job on figuring this one out on your own, OP. I will include the solution in my answer as well.
You were appending the table after calling datatables so it makes sense you would need to put the call to datatables after appending the table with the data in it. I should have caught that, nice job!
Your success function does not loop through l3_task. Try this ..
success: function(response) {
if (response.status == "Success") {
// Layer 1 array object
$.each(response.data[0].l1_task, function(key, value) {
project +=
"<div>" +
"<div>";
// Layer 2 array object
$.each(value.l2_task, function(key1, value1) {
project +=
"<div>" +
"<div>" +
// Layer 3 array object
"<div class='table-responsive'>" +
"<table id='Layer3Table' class='table table-striped' style='width:100%'>" +
"<thead>" +
"<tr>" +
"<th class='text-center'>ID</th>" +
"<th class='text-center'>Activity Name</th>" +
"</tr>" +
"</thead>";
$.each(value1.l3_task, function(k, v) {
project +=
"<tr>" +
"<td>" + v.l3_id + "</td>" +
"<td>" + v.l3_name + "</td>" +
"</tr>";
});
project +=
"</table>" +
"</div>";
}); // for Layer 2
project += "</div></div></div></div>";
}); // for Layer 1
$("#projectDetail2").append(project);
$('#Layer3Table').DataTable();
} else {}
},

checkboxes and number fields set by jquery appear for a split second, then suddenly disappear

I created a simple html file that makes ajax requests to get data from a database table.
Some columns are not updated through ajax. They are manually given inputs in this page. As every ajax call refreshes the page data, I wrote storeVars() and putVars() to store the input values before refreshing and to set the stored values after refreshing respectively. But this doesn't work :(
JavaScript:
function createList() {
$.ajax({
type: "POST",
url: "fetch_registered_list.php?event_id=1",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$('#table_data tr').not(':first').remove();
if (data != '' || data != undefined || data != null) {
var html = '';
$.each(data, function(i, item) {
html += "<tr><td>" + data[i].sno + "</td>" + "<td>" + data[i].name + "</td>" + "<td>" + data[i].email + "</td>" + "<td>" + data[i].phone + "</td>" + "<td><input class='check' name='" + i +
"' type='checkbox'/></td>" + "<td><input class='score' name='" + data[i].email + "' type='number'/></td></tr>"
})
$('#table_data tr').first().after(html);
}
}
});
}
$(document).ready(function() {
createList();
setInterval(function() {
storeVars();
createList();
putVars();
}, 5000);
});
var checkboxes = new Array();
var scores = new Array();
function storeVars() {
$('#table_data tbody tr:not(:first-child) td:nth-child(5)').each(function() {
checkboxes.push($(this).find('.check').is(':checked'));
});
$('#table_data tbody tr:not(:first-child) td:nth-child(6)').each(function() {
scores.push($(this).find('.score').val());
});
}
function putVars() {
$('#table_data tbody tr:not(:first-child) td:nth-child(5)').each(function() {
$(this).find('.check').prop('checked', true);
});
$('#table_data tbody tr:not(:first-child) td:nth-child(6)').each(function() {
$(this).find('.score').val('44');
});
}
HTML:
<body>
<div id="wrapper">
<div id="heading">
<h1>Event One</h1>
</div>
<form method="post">
<table id="table_data">
<tr>
<td><strong>S.no.</strong></td>
<td><strong>Name</strong></td>
<td><strong>Email</strong></td>
<td><strong>Phone</strong></td>
<td><strong>Participated</strong></td>
<td><strong>Score</strong></td>
</tr>
</table>
<footer>
<input id="button" type="button" name="submit" value="Announce Winners" />
</footer>
</form>
</div>
</body>
First, you must reset your arrays at each new storage, or you'll have arrays with exponentional new entries. Secondly your putVars() function is incorrect, it must check the values of each arrays in order to recreate the correct data in the corresponding input.
So update your document ready function to declare your two arrays.
$(document).ready(function() {
var checkboxes,
scores;
createList();
setInterval(function() {
storeVars();
createList();
putVars();
}, 5000);
});
Then reset your two arrays every storage.
function storeVars() {
checkboxes = new Array();
scores = new Array();
$('#table_data tbody tr:not(:first-child) td:nth-child(5)').each(function() {
checkboxes.push($(this).find('.check').is(':checked'));
});
$('#table_data tbody tr:not(:first-child) td:nth-child(6)').each(function() {
scores.push($(this).find('.score').val());
});
}
Finally update your putVars() function like this.
function putVars() {
$('#table_data tbody tr:not(:first-child) td:nth-child(5)').each(function(index) {
if(checkboxes[index] == true) {
$(this).find('.check').prop('checked', true);
}
else {
$(this).find('.check').prop('checked', false);
}
});
$('#table_data tbody tr:not(:first-child) td:nth-child(6)').each(function(index) {
$(this).find('.score').val(scores[index]);
});
}
working fiddle

TypeError: response[i] is undefined in jQuery autogenerate table rows

I have the following jquery funcion that's supposed to get a value from a text field:
My Php Code
function asset_status() {
$query = $this->db->query("SELECT count(job_card_no) as job_card_no,number,asset.type,asset.status,asset.id as asset_id FROM asset inner join assgnd_rsces on assgnd_rsces.name = asset.id inner join job_card on job_card.id = assgnd_rsces.job_card_id");
$result = $query->result_array();
echo json_encode($result);
}
ajax request
asset_status_list = '';
$.ajax({
type: "GET",
url: "<?php echo base_url(); ?>operations/asset_status",
dataType: "JSON",
success: function (response) {
console.log(response); // it gives following
//job_card_no "2" number "1" status "Active" type "Toilet"
for (i = 0; i < response.length; i++) {
asset_status_list = '<tr><td >' + response[i].job_card_no + '</td><td >' + response[i].number + '</td><td>' + response[i].type + '</td><td ><input type="hidden" name="view_more_id" class="view_more_id' + response[i].id + '" id="view_more_id" value="' + response[i].id + '"/><button id="view_more_link" class="view_more_link' + response[i].id + '"><i class="glyphicon glyphicon-zoom-in "></i>View More</button></td></tr>';
$('#asset_status_tr').append(asset_status_list);
$("#asset_status_tr").on("click", ".view_more_link" + response[i].id, function () {
var asset_id = $(".view_more_id"+response[i].id).val();
alert(asset_id);
});
}
$('#asset_table_status').DataTable({});
},
error: function (response) {
}
});
However when I try it using the above function, I get the following error on click of the button.
TypeError: response[i] is undefined
var asset_id = $(".view_more_id"+response[i].id).val();
How do I solve the above error ?
Yes, you are not getting 'json' from file that's why its length is 0 and its shown you 'undefined'.Please make sure that.

Not being able to filter json data by just name

I have a file called data.json and a file called Search.html. The xbox360 json file contains:
[{
"Name": "Assassin's Creed: Rogue",
"Image": "Images/360ACR.jpg",
"Platform": "XBOX 360"
}, {
"Name": "Battlefield 3",
"Image": "Images/360BF3.jpg",
"Platform": "XBOX 360"
}]
The Search html file contains:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('#search').keyup(function() {
var searchField = $('#search').val();
var regex = new RegExp(searchField, "i");
var output = '<div class="row">';
var count = 1;
$.getJSON('data.json', function(data) {
$.each(data, function(key, val) {
if ((val.Name.search(regex) != -1) || (val.Platform.search(regex) != -1)) {
output += '<div class="col-md-6 well">';
output += '<div class="col-md-3"><img class="img-responsive" src="' + val.Image + '" alt="' + val.Name + '" /></div>';
output += '<div class="col-md-7">';
output += '<h5>' + val.Name + '</h5>';
output += '<p>' + val.Platform + '</p>'
output += '</div>';
output += '</div>';
if (count % 2 == 0) {
output += '</div><div class="row">'
}
count++;
}
});
output += '</div>';
$('#results').html(output);
});
});
});
</script>
</head>
<body>
<form>
<div class="form">
<input type="text" class="" id="search" placeholder="Search">
<input type="button" id="search" value="Search" />
</div>
</form>
<div id="results"></div>
</body>
</html>
The problem with this code is that when the user types a or any letter into the textbox it brings up all the data from the JSON file. I just want it to filter it by name. So if I type Assassins Creed it just brings up that game only.
I know this question is tedious with the amount of code I have put in. It would be nice for someone to help me. I appreciate it if you can. I am trying by the way.
Try using a filter:
var res = data.filter(function(obj){
return obj.Name.indexOf(input) >= 0;
});
The array of objects you want will be in res.
Replace input with the string you want to check for.
See this JSFiddle: https://jsfiddle.net/4b5gffmu/

Categories

Resources