create and append multiple elements with data from JSON - javascript

Let data be a JSON,
what I am trying here is appending multiple elements according to the data from JSON to the div ,
<div class="studentTab" ></div>. How can I achieve this ?
(nb: please consider that we have 2 Languages and 2 Specializations)
for (i = 0; i < 10; i++) {
var html = '<div class="dtls">' +
'' +
'<h4 class="verified">' + data.student[0].firstName + '</h4 >' +
'<ul>' +
'<li>' + data.student[0].location + '</li>' +
'<li>' + data.student[0].mark + ' /hour</li>' +
'<li>' + data.student[0].year+ ' accademic year</li>' +
if (data.student[0].Languages != null)
{
var lang = string.Join(",", data.student[0].Languages.Select(it => it.Name));
<li>lang </li>
}
if (data.student[0].Specializations.length > 1)
{
var rcount = data.student[0][index].Specializations.length - 1;
<li>data.student[0].Specializations[0].Name + rcount more</li>
}
else
{
<li>data.student[0].Specializations[0].Name</li>
}
'</ul>' +
'</div>'
$('#studentTab').append(html);
};

You may use map() for solving such problem. Please make check:
If your 'data' is underfined or not;
Better save your data.student[0] in some variable;
You never know how many objects inside of data you have. Probably some times is underfined due to network errors or more or less objects due to some back-end updates

Related

Array list display online one result from json

I wrote this code and it works:
function getJsonResult(retrieve) {
var result = retrieve.results;
for (var i = 0; i < result.length; i++) {
responseJson.push({ id: result[i].id, title: result[i].title });
var search = '<a id="' + result[i].id + '">' + result[i].title + '</a><br/>';
document.write(search);
}
}
When I tried to display the results in a div, I change the last line with:
$("#divId").html(search);
But it only displays the first result. How can I make the whole list appear?
That happened because you're overriding the search variable in every iteration :
var search = '<a id="' + result[i].id + '">' + result[i].title + '</a><br/>';
You need to declare the search variable outside of the loop then append the string in every iteration like :
function getJsonResult(retrieve) {
var result = retrieve.results;
var search = "";
___________^^^^
for (var i = 0; i < result.length; i++) {
responseJson.push({ id: result[i].id, title: result[i].title });
var search += '<a id="' + result[i].id + '">' + result[i].title + '</a><br/>';
___________^^
document.write(search);
}
}
Then finally you could put your variable content to the div :
$("#divId").html(search);
$('#divId').append(search);
This appends the element included in search to the div element.

How to return a variable from a callback after building variable with .getjson and .each

The Problem
I'm trying to figure out how to return HTML that I've built from a JSON file with jQuery.
I seem to have gotten returnLocations() to wait until getLocations() is finished so that the variable locationsBody is finalized with information gathered from my .each loop. The trouble (I think) is my not being able to return that variable to output it to my HTML page.
The Question
How can I return the variable locationsBody?
Note
(there may be errors in the below code as I trimmed it down as best I could but I think it should illustrate the problem with or without them)
The jQuery
the global variables
var locationsFull = 'un d fined';
var locationsOpener = '' +
'<div class="locations-header">places youve been</div>' +
'<div class="locations-container">' +
'<div class="locations-nav left">left</div>' +
'<div class="locations-nav right">right</div>'
;
var locationsBody = '<div class="locations-inner">'; // opening of container
var locationsCloser = '</div>'; // closing of container
the function
function locationsFunction() {
function getLocations() {
var wait = $.Deferred();
var area = 'Area1';
var counter = 1;
$.getJSON("locations.json", function(data) {
$(data.places).each(function() {
var location = this.location;
var image = this.image;
if (this.area === 'Area1') {
if (counter == 2) {
locationsBody = locationsBody +
'<div class="locations-places">' +
'<img src="images/places/' + image + '">' +
'<div class="locations-places-image">' + location + '</div>' +
'</div></div>'
;
counter = 0; // added closing of container, reset to 0
} else {
locationsBody = locationsBody +
'<div class="locations-places">' +
'<img src="images/places/' + image + '">' +
'<div class="locations-places-image">' + location + '</div>' +
'</div>'
;
counter = counter + 1;
}
}
})
wait.resolve();
})
return wait;
}
function returnLocations() {
locationsFull = locationsOpener + locationsBody + locationsCloser; // works, proven in alert and console.log
//alert(locationsFull); // works
console.log(locationsFull); // works
//return locationsFull; // doesnt work
//return 'anything'; // doesnt work
}
getLocations().then(returnLocations);
}
the call
$(function() {
$('.locations-body').html(locationsFunction());
})
The JSON File
{"places":[
{
"area": "Area1",
"location": "Downtown",
"image": "downtown.jpg"
},
{
"area": "Area1",
"location": "Uptown",
"image": "uptown.jpg"
}
]}
The HTML
<div class="locations-body"></div>
Further Note: Questions similar to this have been asked dozens of times on stackoverflow alone and those questions and answers have hundreds of thousands of reads. I have read through all of the top ones and more over the last 2 days. My problem is my inability to thoroughly understand the answers and apply them to my exact situation as seems to be the problem of the dozens (hundreds/thousands?) of people asking these questions and the hundreds of thousands (millions?) of people that have been searching for solutions to asynchronous problems.
You could just call .html() inside the returnLocations() function if that's viable.
the function
function returnLocations() {
locationsFull = locationsOpener + locationsBody + locationsCloser;
$('.locations-body').html(locationsFull);
}
the call
$(function() {
locationsFunction();
}
Otherwise you'll need to look into callbacks, read this, if you need to do it this way I can update my answer with an example later on.
Have you tried
return wait.promise();
instead of returning the Deferred?
Then calling like this:
var deferredChain = $.Deferred();
deferredChain.then(getLocations).then(returnLocations);
deferredChain.resolve();
I discovered today that simply putting a .done at the end of $.getJSON seems to work just the same and is much easier than using $.Deferred and the associated lines of code to make it work.
function locationsFunction() {
var area = 'Area1';
var counter = 1;
$.getJSON("locations.json", function(data) {
$(data.places).each(function() {
var location = this.location;
var image = this.image;
if (this.area === 'Area1') {
if (counter == 2) {
locationsBody = locationsBody +
'<div class="locations-places">' +
'<img src="images/places/' + image + '">' +
'<div class="locations-places-image">' + location + '</div>' +
'</div></div>'
;
counter = 0; // added closing of container, reset to 0
} else {
locationsBody = locationsBody +
'<div class="locations-places">' +
'<img src="images/places/' + image + '">' +
'<div class="locations-places-image">' + location + '</div>' +
'</div>'
;
counter = counter + 1;
}
}
})
}).done(function() {
locationsFull = locationsOpener + locationsBody + locationsCloser;
$('.locations-body').html(locationsFull);
});
}

JQuery mobile list prepend

trying to prepend my list in jquery mobile but I just can't get the divider to be on top of the most recent item added to the listview.
I've tried prepending the item that's being added but it then switches the divider to the bottom.
function loadScanItems(tx, rs) {
var rowOutput = "";
var $scanItems = $('#scanItems');
$scanItems.empty();
var bubbleCount = 0;
for (var i = 0; i < rs.rows.length; i++) {
bubbleCount = bubbleCount + 1;
//rowOutput += renderScan(rs.rows.item(i));
var row = rs.rows.item(i)
var now = row.added_on;
var date = get_date(now);
rowOutput += '<li data-icon="false"><div class="ui-grid-b"><div class="ui-block-a" style="width:50%"><h3>Su # ' + row.sunum + '</h3><p> Bin # ' + row.binnum + '</p></div><p class="ui-li-aside"><strong>' + date + '</strong></p><div class="ui-block-b" style="width:20%"></div><div class="ui-block-c" style="width:25%"><br><p>User: ' + row.userid + '</p></div></div></li>';
// rowOutput += '<li>' + row.sunum + row.binnum+ "<a href='javascript:void(0);' onclick='webdb.deleteScan(" + row.ID + ");'>Delete</a></li>";
}
$scanItems.append('<li data-role="list-divider">Scanned Items <span class="ui-li-count">' + bubbleCount + '</span></li>').listview('refresh');
$scanItems.append(rowOutput).listview('refresh');
}
The code is above with it correctly formatted with the divider on top but the list items being appended to the bottom instead of prepended to the top.
Thanks!
The problem is that your are building a string with all the scan items. That string already has an order so whether you prepend or append makes no difference. Try this simple change.
Change:
rowOutput += '<li data-icon="false">...</li>';
to:
rowOutput = '<li data-icon="false">...</li>' + rowOutput;
This will put your rowOutput string in the correct order before appending to the listview.
Here is a working DEMO

Creating an array object within an array object

I have an array object that needs another array object added to it. So i have details of the object that need the rows in a table to be added to that object as an array. I have tried a few suggestions on stackoverflow , but none seems to be working, and i am not sure this has something to do with the fact that the table is created by js.
// Adding Cosignment number
$('#parcel-overview').append(
// Add main tables which will display the added packages
'<table border="1">' +
'<thead><tr><th>Packages</th><th>Weight</th> <th>Vol Weight</th><th>Charge Weight</th> <th>Price</th></tr></thead><tbody id="parcels-added-overview"></tbody> ' +
'</table>'
);
for (var i = 0; i < packageNum; i++) {
var ii = (i + 1).toString();
// Working out volemetric weight
wei = $('#added-parcels #weighting-' + ii + ' input').val();
len = $('#added-parcels #lengthing-' + ii + ' input').val();
wid = $('#added-parcels #widthing-' + ii + ' input').val();
hei = $('#added-parcels #heighting-' + ii + ' input').val();
//Calculating Volumetric weight
tot = ((len * wid * hei) / 5000).toFixed(1);
pri = (tot * 23).toFixed(2);
chr = (tot * 12).toFixed(2);
$('#parcels-added-overview').append(
'<tr>' +
'<td class="par-id">' + (i + 1).toString() + '</td>' +
'<td class="par-weight">' + wei.toString() + ' kg\'s</td>' +
'<td class="par-vol-weight">' + tot.toString() + ' kg\'s</td>' +
'<td class="par-charge-weight">R ' + chr.toString() + '</td>' +
'<td class="par-price">R ' + pri.toString() + ' </td>' +
'</tr>'
);
}
I then want to add the values of that table that have been added dynamically to an object array that is then added to the primary object array.
var parcelObj = new Object();
$.each($('#parcels-added-overview tr'),function (index) {
parcelObj.parcelId = $(this).children('.par-id').text();
parcelObj.totalWeight = $(this).children('.par-weight').text();
parcelObj.volWeight = $(this).children('.par-vol-weight').text();
parcelObj.chargeWeight = $(this).children('.par-charge-weight').text();
parcelObj.overallPrice = $(this).children('.par-price').text();
parcelsArr.push(parcelObj);
});
consignmentObj.parcels = parcelsArr;
consignmentsArr.push(consignmentObj);
I might be a n00b , but this code (although i think its fairly verbose ) should work.
Does the $(this).children not identify directly on each() row that it is iterating over?
When i add console.log(consignmentsArr); i get the array within the object as it should be but the values for the parcel object are just repeating the last row of the table.
1: Object
deliName: ""
deliStreet: ""
docType: "Document"
insurance: "None"
parcels: Array[2]
0: Object
chargeValue:"R34.43"
overallPrice:"R43.54"
parcelId:"2"
totalWeight:"65 kg's"
volWeight:"63 kg's"
1: Object
chargeValue:"R34.43"
overallPrice:"R43.54"
parcelId:"2"
totalWeight:"65 kg's"
volWeight:"63 kg's"
Why can I not get the first row values to be added to parcels[0]?
Thanks
Try to declare parcelObj object inside the function.
$.each($('#parcels-added-overview tr'),function (index) {
var parcelObj = new Object();
parcelObj.parcelId = $(this).children('.par-id').text();
parcelObj.totalWeight = $(this).children('.par-weight').text();
parcelObj.volWeight = $(this).children('.par-vol-weight').text();
parcelObj.chargeWeight = $(this).children('.par-charge-weight').text();
parcelObj.overallPrice = $(this).children('.par-price').text();
parcelsArr.push(parcelObj);
});
consignmentObj.parcels = parcelsArr;
consignmentsArr.push(consignmentObj);

JavaScript variable empty without previous alert messge

I'm using the following function to create a list of links from a JSON-File and put them into a span element (jquery has been initialized)
$(document).ready(function() {
function createjson(category) {
var content = "";
i = 0;
$.getJSON(category + ".txt", function(data){
while(data[i] != null) {
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
i++;
}
});
document.getElementById("list_" + category).innerHTML = content;
}
createjson("cat1");
});
However, if I use it like this, the span element remains empty. It is only when I replace
document.getElementById("list_" + category).innerHTML = content;
with
alert("test");
document.getElementById("list_" + category).innerHTML = content;
that I get the desired output. How can I get it without printing out an alert message beforehand?
That is becuase .getJSON() is an asynchronous method. Your code will try to update the DOM with content, before the server had time to respond to the request. Therefor no content is inserted.
With the alert, you stop the execution long enough for the server to respond, therefor it works when you add the alert.
The correct way to do it would be to move your content update into the success-callback instead, which is always run after the server has responded:
$.getJSON(category + ".txt", function(data){
while(data[i] != null) {
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
i++;
}
$("#list_" + category).html(content);
});
I replaced your document.getElementById("list_" + category).innerHTML = content; with the somewhat shorter jQuery equivalent $("#list_" + category).html(content); in the above example as well.
It's not the alert which is fixing this, the alert is basically blocking the UI for long enough for the AJAX request to complete.
$.getJSON is an asyncronous method. This means that the result of the function call is not always available immediately, you'll need to move your code which sets the list element HTML inside the $.getJSON callback:
$.getJSON(category + ".txt", function (data) {
while(data[i] != null) { ... }
document.getElementById("list_" + category).innerHTML = content;
});
Put the html append in callback, also reset the i when call back starts.
$(document).ready(function() {
function createjson(category) {
$.getJSON(category + ".txt", function(data)
{
var content = "";
for(i=0; i<data.length; i++)
{
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
}
document.getElementById("list_" + category).innerHTML = content;
});
}
createjson("cat1");
});
Use this !== to compare with not equal to NULL
while(data[i] !== null) {
content = content + '<li class="liste"><a target="_blank" class="liste" href="' + data[i].url + '">' + data[i].name + '</a></li>';
i++;
}

Categories