alternating between even and odd elements in json with JS - javascript

I'm trying to generate a .html div containers using .json file that looks like below.
[
{
"KEYWORD": XXXX,
"DATEx": XXXX,
"TOPIC": XXXX,
"CSPANLINK": XXXX,
"EXCERPTS": XXXX
},
{
"KEYWORD": YYYY,
"DATEx": YYYY,
"TOPIC": YYYY,
"CSPANLINK": YYYY,
"EXCERPTS": YYYY
}]
For odd numbered elements, I want to create div with class = "container left" and for even numbered elements, I want to create div with class = "container right". I used the below code to generate .html:
$.getJSON("XXXXYYYY.json", function (data) {
var html = '';
$.each(data, function (key, value) {
html += '<div class="container left">';
html += '<div class="content">';
html += '<h2>' + value.DATEx + '</h2>'
html += '<p>' + value.EXCERPTS + '</p>';
html += '</div>';
html += '</div>';
});
$('div.timeline').html(html);
});
So in a nutshell, I would like to alternate between these two codes, depending on the index of each element.
html += '<div class="container left">';
and
html += '<div class="container right">';
What kind of javascript conditional statement should I use to do this?

The parameter you pass in the $.each is the array and the function callback with index and value
$.each([ 52, 97 ], function( index, value ) {
alert( index + ": " + value );
});
So in your case you can check even odd for your index and add the class accordingly.
Something like this
$.getJSON("XXXXYYYY.json", function (data) {
var html = '';
$.each(data, function (index, value) {
html += index%2===0 ? '<div class="container right">' : '<div class="container left">';
html += '<div class="content">';
html += '<h2>' + value.DATEx + '</h2>'
html += '<p>' + value.EXCERPTS + '</p>';
html += '</div>';
html += '</div>';
});
$('div.timeline').html(html);
});

looks like its an duplication of:
Is this an even or odd element?
Therefor the following Code should work for you.
$('div').each(function(i, el) {
// As a side note, this === el.
if (i % 2 === 0) { /* we are even */ }
else { /* we are odd */ }
});

Related

i want to seperate a function into a multiple function jquery/ajax

I have a JavaScript file that has an Ajax function which calls a JSON file from an online server to extract it's data and interpret it in to a generated table... I want to separate the generate link, generate date, identify the car plate type/country into multiple functions that can be called by the ajax function.
// table of the server's data from JSON file
$(document).ready(function() {
$.ajax({
url: "http://127.0.0.1:3737/anpr?nb=0",
type: "GET",
dataType: "json",
success: function(data) {
var detection_data = '';
// generating the table to interpret the json data
$.each(data, function(key, value) {
detection_data += '<div class="table-row">';
detection_data += '<div class="serial">' + value.id + '</div>';
// identifie the car plate type/country fron json data
var plateType = value.plateType
if (plateType == "1") {
detection_data += '<div class="country">Tunisie TN</div>';
} else if (plateType == "2") {
detection_data += '<div class="country">Tunisie RS</div>';
} else if (plateType == "3") {
detection_data += '<div class="country">Tunisie GOV</div>';
} else if (plateType == "4") {
detection_data += '<div class="country">Lybie</div>';
} else if (plateType == "5") {
detection_data += '<div class="country">Algerie</div>';
} else {
detection_data += '<div class="country">Autre</div>';
}
detection_data += '<div class="visit">' + value.plateNumber + '</div>';
// generate date from json data
detection_data += '<div class="percentage">' + value.date.substr(8, 2) +
'/' + value.date.substr(5, 2) + '/' + value.date.substr(0, 4) +
' ' + value.date.substr(11, 2) + ':' + value.date.substr(14, 2) + ':' + value.date.substr(17, 2) + '</div>';
// generate link
detection_data += '<div>' + '<a class="img-pop-up" href="http://127.0.0.1:3737/anpr/snapshot?year=' + value.date.substr(0, 4) +
'&month=' + value.date.substr(5, 2) + '&day=' + value.date.substr(8, 2) +
'&&hour=' + value.date.substr(11, 2) + '&minute=' + value.date.substr(14, 2) + '&second=' + value.date.substr(17, 2) +
'&plate=' + value.plateNumber.split(" ").join("_") + '&platetype=' + value.plateType + '">link to picture</a>' + '</div>';
detection_data += '</div>';
});
$('#detection_table').append(detection_data);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I tried to make your code more modular and readable. Here's what I could come up with. I am posting only relevant sections of your code to be concise.
NOTE: This is just a recommendation,I have not tested the below code.
var detection_data = '';
// generating the table to interpret the json data
$.each(data, function(key, value) {
detection_data += '<div class="table-row">';
detection_data += getPlateIDHTML(value.id);
// identifie the car plate type/country fron json data
detection_data += getPlateTypeCountryHTML(value.plateType);
// Plate number
detection_data += getPlateNumberHTML(value.plateNumber);
// generate date from json data
detection_data += getDetectionDateHtml(value.date);
// generate link
detection_data += getSnapshotLink(value.date, value.plateNumber, value.plateType);
detection_data += '</div>';
});
$('#detection_table').append(detection_data);
Below are my functions
String.prototype.format = function () {
var a = this, b;
for (b in arguments) {
a = a.replace(/%[a-z]/, arguments[b]);
}
return a; // Make chainable
};
function parseStringAsJSDate(date_as_string) {
return new Date(date_as_string);
}
function getPlateIDHTML(id) {
var plate_id_html = '<div class="serial">%s</div>';
return plate_id_html.format(id);
}
function getPlateNumberHTML(plateNumber) {
var plate_number_html = '<div class="visit">%s</div>';
return plate_number_html.format(plateNumber);
}
function getPlateTypeCountryHTML(plateType) {
var plateTypeCountry = {
"1": "Tunisie TN",
"2": "Tunisie RS",
"3": "Tunisie GOV",
"4": "Lybie",
"5": "Algerie",
};
var plate_type_country_html = '<div class="country">%s</div>';
if(plateType in plateTypeCountry) {
return detection_data_html.format(plateTypeCountry[plateType]);
} else {
return detection_data_html.format("Autre");
}
}
function getDetectionDateHtml(captured_date_as_string) {
var date_of_capture_html = '<div class="percentage">%s/%s/%s %s:%s:%s</div>';
var captured_date = parseStringAsJSDate(captured_date_as_string);
return date_of_capture_html.format(captured_date.getDate(), captured_date.getMonth()+1, captured_date.getFullYear(), captured_date.getHours(), captured_date.getMinutes(), captured_date.getSeconds());
}
function getSnapshotLink(captured_date_as_string, plateNumber, plateType) {
var snapshot_link = "http://127.0.0.1:3737/anpr/snapshot?year=%s&month=%s&year=%s&day=%s&hour=%s&minute=%s&second=%s&plate=%s&platetype=%s";
var snapshot_link_html = '<div><a class="img-pop-up" href="%s">Link to picture</a></div>';
var captured_date = parseStringAsJSDate(captured_date_as_string);
var snapshot_link = snapshot_link.format(captured_date.getDate(), captured_date.getMonth()+1, captured_date.getFullYear(), captured_date.getHours(), captured_date.getMinutes(), captured_date.getSeconds(), plateNumber.split(" ").join("_"), plateType);
return snapshot_link_html.format(snapshot_link);
}
Below is a brief explanation of each function
String.prototype.format: This is an equivalent of the old-school printf in C. I find variable-substitutions of the sort '<div class="serial">'+ id +'</div>' inter-mingling HTML with JavaScript very difficult to read. And therefore this.
parseStringAsJSDate: I assume that your API is under your control. I recommend you to modify the date format to ISO8601 so that it can be parsed by JavaScript as a Date. Your substr function again affects readability.
getPlateIDHTML & getPlateNumberHTML: Simple functions that just use the format function to embed the passed variables into the HTMLs to show ID and plate number.
getPlateTypeCountryHTML: I used a Python object here to reduce the number of ifs and else ifs.
getDetectionDateHtml & getSnapshotLink: I have tried to parse the date as a JavaScript date and this eliminates the substrs. Moreover, the use of format simplifies these functions further.
Let me know your suggestions on this. Suggestions/Criticism from Stack's gurus are more than welcome :)
UPDATE
Please check my updated format function. I sourced it from this excellent answer. Apologies, the earlier one was just copy-pasted, I should have tried it. Please just the format function to the one that's indicated and let me know

Ajax Jquery / JavaScript create HTML Elements when data is greater than 0 (zero)

I have a HTML element that I am populating with divs & data with JSON returned from a PHP script. The data is constantly updating so I am using Eventsouce (sse).
<div class="row state-overview" id="statusCount"> </div>
let fsource;
function getStatus() {
if (typeof(EventSource) !== "undefined") {
try {
fsource.removeEventListener("status", stream, false);
} catch (ex) {
}
fsource = new EventSource("-PHP FILE-");
fsource.addEventListener("status", stream, false);
} else {
console.log("Oh no");
}
}
function stream(e) {
let data = JSON.parse(e.data);
let html = '';
$.each(data, function (key, value) {
html += '<div class="col-lg-2 panel ' + key + ' ">';
html += '<p>' + key + '</p>';
html += '<label>' + value + '</label>';
html += '</div>';
});
$('#statusCount').html(html);
}
getStatus();
This works perfectly, however, I am trying to hide / not show elements where the value = 0.
A sample of the JSON looks like so:
event: status
data: {"Online": 2, "Stopped": 3, "Alarm": 0, "Offline": 0}
Unfortunately I can't change the PHP to manipulate what data gets returned,
so any JavaScript or Jquery Solutions would be great - cheers!
What about a simple condition:
$.each(data, function (key, value) {
// if value IS more than zero, add some html
if(value>0){
html += '<div class="col-lg-2 panel ' + key + ' ">';
html += '<p>' + key + '</p>';
html += '<label>' + value + '</label>';
html += '</div>';
}
});

print array of object in javascript and print in html tags

i am using storelocater.js for multiple location in google map and show the information according to the location with image. i can show only one image but i want to show multiple images inside the information panel. link this
Here is my code
var panelDiv = document.getElementById('panel');
storeLocator.Panel.NO_STORES_IN_VIEW_HTML_ = '<li class="no-stores">The nearest outlet:</li>';
var Store = storeLocator.Store;
Store.prototype.generateFieldsHTML_ = function(fields) {
var html = '';
html += '<div class="store-data">';
if(this.props_['title']){
html += '<div class="title"><div class="img-list clearfix">' +
for (var i = 0; i <= this.props_[images].length; i++) {
console.log(this.props_[images[i]]);
// <img src=' + this.props_['images'] + '>
}
+ '</div></div>'
}
html += '</div>';
return html;
}
var data = new storeLocator.StaticDataFeed;
data.setStores([
new storeLocator.Store('store02', new google.maps.LatLng(27.67663,85.31093), null, {images: ["img/thapathalil.jpg","img/thapathalil.jpg","img/thapathalil.jpg"]})
]);
and it shows:
Uncaught SyntaxError: Unexpected token for...
how can i solve this?? how can i fetch location inside of "images"
THANKS in advance
Actually you got Uncaught SyntaxError: Unexpected token for... because you used the for..loop in the string concatenation statement, directly after the + sign.
Change this code :
html += '<div class="title"><div class="img-list clearfix">' +
for (var i = 0; i <= this.props_[images].length; i++) {
console.log(this.props_[images[i]]);
// <img src=' + this.props_['images'] + '>
}
+ '</div></div>'
To the following:
html += '<div class="title"><div class="img-list clearfix">';
for (var i = 0; i <= this.props_['images'].length; i++) {
console.log(this.props_['images'][i]);
html += '<img src=' + this.props_['images'][i] + '>';
}
html += '</div></div>'
Note:
You should separate the concatenation of strings to the html
variable and the for loop logic, using html += instead of just using concatenation with + sign on multiple lines.
Make sure to wrap the properties names between two '' while accessing your objects, like in this.props_[images] where it should be this.props_['images'] and in this.props_[images[i]] where it should be this.props_['images'][i].
And the first 2 lines of your html variable decalaration and the concatenation, var html = ''; html += '<div class="store-data">'; can be shortened to just var html = '<div class="store-data">';.
I think there is a typo. Change this:
console.log(this.props_[images[i]])
to
console.log(this.props_['images'][i])
And you should use
i < this.props_['images'].length
So try this:
for (var i = 0; i < this.props_['images'].length; i++) {
console.log(this.props_['images'][i]);
}

Numeric-defined varliable becomes as NaN while trying to print json array

I'm trying to use the following code in order to split Json array into 3-columns Bootstrap rows
I'm trying that by increasing a numeric variable to 3, adding a new row div and set it back to 1.
actually, the variable return as "NaN" at the first attemt to increase it
please your help, or any other idea to splir json to 3-col rows.
the code:
<script>
$( document ).ready(function() {
var coli;
console.log( 'ready!'+coli );
$.getJSON("games.json", function(data) {
var html = '';
var coli=1;
$.each(data, function(key,value){
if (coli==3) {
html += '<div class="row">';
console.log( "3!" );
}
html += '<div class="col-md-4 img-portfolio">';
html += '<a href="portfolio-item.html">';
html += '<img class="img-responsive img-hover" src="'+value.teaser+'" alt="">';
html += '</a>';
html += '<h3>';
html += ''+value.title+'' ;
html += '</h3>';
html += '<p>'+coli+value.description+'</p>';
html += '</div> ';
if (coli==3) {
html += '</div>';
var coli=1;
console.log( "1!" );
}
coli++;
console.log( 'ready!'+coli );
});
$('#yourContainerId').html(html);
});
});
</script>
Thanks
try replace
if (coli==3) {
html += '</div>';
var coli=1;
console.log( "1!" );
}
with
if (coli==3) {
html += '</div>';
coli=1;
console.log( "1!" );
}
You are declaring your variable coli new in the if-statement. That is what you should not do.

access nested json data from ajax call

I am interfacing with an API which returns JSON data to me. As the results are not stored in a file, but rather server memory, I am having a hard time figuring out how to access the data and write it to my html webpage. Here's what my $.ajax call looks like:
$.ajax({
type: "post",
url:"https://www.xxx/v1/trips/search? key=xxxx",
data:JSON.stringify({request : requestTrav1Dest1}),
dataType:"json",
success:successFunction,
headers:{"Content-Type":"application/json"}
});
Here's what the JSON I get back from the server looks like:
{
"kind": "#tripsSearch",
"trips": {
"kind": "#tripOptions",
"tripOption": [
{
"saleTotal": "USD294.10",
"id": "DMfSXrkVQGKTVQsDD5l60N004",
},
"saleTotal": "USD333.10",
"id": "DMfSXrkVQGKTVQsDD5l60N002",
},
{
"saleTotal": "USD225.94",
"id": "DMfSXrkVQGKTVQsDD5l60N005",
}
]
}
}
What I really need is the saleTotal for each tripOption.
I broke out the function that runs if the query is a success here:
function successFunction(servResponse){
$('#content').load('resultsPage.html #content');
var newContent = '';
for(var i = 0; i < servResponse.trips.tripOption[i].length; i++){
newContent += '<div class="results">';
newContent += '<p>' + "Option " + (i+1) + '<br>';
newContent += servResponse.trips.tripOption[0].saleTotal + '<br>';
newContent += '</div>';
}
document.getElementById('content').innerhtml = newContent;
}
Unfortunately, this does not write out anything to the webpage. So far I can only view the raw JSON results in the Chrome Developer's Toolbar Console.
Can someone please help identify what I need to do differently?
Thanks in advance!
Assuming you have an element on the page with the ID of content, it should work fine, you just have a little typo
document.getElementById('content').innerhtml = newContent;
capitlize the 'HTML',
document.getElementById('content').innerHTML = newContent;
$('#content').load('resultsPage.html #content'); looks incorrect, the 1st parameter should just be a URL. Try commenting it out, for now, since you're changing it's content with the other line.
Also, the 4th line should be:
for(var i = 0; i < servResponse.trips.tripOption.length; i++){
You have:
... tripOption[i].length ...
The function below should:
Create one div with the class="results"
Place several p elements inside this div, each containing a 2-line entry
Display all this inside the element with an id of "content"
Is this what you want? The CSS that you are currently applying to .results may need to be applied to .results p instead.
function successFunction(servResponse){
var tripOption = servResponse.trips.tripOption;
var newContent = '<div class="results">';
for(var i = 0; i < tripOption.length; i++){
newContent += '<p>' + "Option " + (i+1) + '<br>';
newContent += tripOption[i].saleTotal + '<p>';
}
newContent += '</div>';
document.getElementById('content').innerHTML = newContent;
}
jsFiddle
var servResponse = {
"kind": "#tripsSearch",
"trips": {
"kind": "#tripOptions",
"tripOption": [
{
"saleTotal": "USD294.10",
"id": "DMfSXrkVQGKTVQsDD5l60N004",
},{
"saleTotal": "USD333.10",
"id": "DMfSXrkVQGKTVQsDD5l60N002",
},
{
"saleTotal": "USD225.94",
"id": "DMfSXrkVQGKTVQsDD5l60N005",
}
]
}
};
function successFunction(servResponse) {
var newContent = '';
servResponse.trips.tripOption.forEach(function(el,index){
newContent += '<div class="results">';
newContent += '<p>' + "Option " + (index+1) + '<br>';
newContent += el.saleTotal + '<br>';
newContent += '</div>';
console.log(el.saleTotal);
});
document.getElementById('content').innerHTML = newContent;
}
successFunction(servResponse);
Using pure javascript forEach loop
Example Link : http://jsfiddle.net/c1wzsqaf/1/

Categories