I have a JSON file with the following structure:
[
{
year: "2016",
gallery: [
{
folder_heading: "FOLDER 1",
folder_images: [
{
title: "TITLE 1",
filename: "IMG_9225.jpg",
url: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225.jpg",
alt: "",
caption: "",
width: 1781,
height: 2560,
sizes: {
gallery_thumbnail: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225-300x431.jpg",
gallery_thumbnail-width: 300,
gallery_thumbnail-height: 431
}
},
{
title: "TITLE 2",
filename: "IMG_9225.jpg",
url: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225.jpg",
alt: "",
caption: "",
width: 1781,
height: 2560,
sizes: {
gallery_thumbnail: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225-300x431.jpg",
gallery_thumbnail-width: 300,
gallery_thumbnail-height: 431
}
},
]
]
},
I did maintain to get year numbers and populate them to the list with jQuery's each function. But I would need to maintain this structure and print it in this way:
<!-- YEARS -->
<ul>
<li>2016</li>
<li>2015</li>
........
</ul>
<!-- GALLERY CONTENT WRAPPER -->
<section>
<!-- 2016 -->
<div>
<ul>
<li>FOLDER 1</li>
<li>FOLDER 2</li>
<li>FOLDER 3</li>
.........
</ul>
<!-- FOLDER 1 Images -->
<div>
<img />
<img />
<img />
<img />
.......
<div>
<!-- FOLDER 2 Images -->
<div>
<img />
<img />
<img />
<img />
.......
<div>
.............
</div>
<!-- 2015 -->
<div>
<ul>
<li>FOLDER 1</li>
<li>FOLDER 2</li>
<li>FOLDER 3</li>
.........
</ul>
<!-- FOLDER 1 Images -->
<div>
<img />
<img />
<img />
<img />
.......
<div>
<!-- FOLDER 2 Images -->
<div>
<img />
<img />
<img />
<img />
.......
<div>
.............
</div>
...................
</section
Should I go and try use jQuery with this or go with some other framework. Or is vanilla JS the most efficient way to achieve this. That's probably option based but I would need someone to point me in the right direction how to iterate my JSON array and print it in the HTML.
For this point I have done this with PHP in WordPress, but since there is a lot of images and folders my server takes a long time to process that (might be because I'm using ACF's get_field and get_subfield).
But now I want to try using WP-REST API for this task to get more familiar with it.
How do I achieve this, and which way faster way to query all the images from the database REAST-API + JS or ACF PHP?
UPDATE:
I did manage to get the JSON file and iterate the first list (years list) with the year numbers with this code:
$(document).ready(function() {
$.ajax({
type: "GET",
url: 'url-to-json-file',
dataType: 'json',
error: function() {
alert( 'Unable to load tabs.' );
},
success: function(data) {
$.each(data, function(i, item){
var int = i + 1,
tapahtumaTab = '<h2>' + data[i].tapahtuman_nimi + '</h2>';
$('<li />', {html: tapahtumaTab}).appendTo('#years-list');
})
}
});
});
This example will help you to create dynamic elements. Append the output to a element.
Your JSON Data is not proper, you can not give "-" in the keys. If you want to please use quotes.
var data = [
{
"year": "2016",
"gallery": [
{
folder_heading: "FOLDER 1",
folder_images: [
{
title: "TITLE 1",
filename: "IMG_9225.jpg",
url: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225.jpg",
alt: "",
caption: "",
width: 1781,
height: 2560,
sizes: {
gallery_thumbnail: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225-300x431.jpg",
"gallery_thumbnail-width": 300,
"gallery_thumbnail-height": 431
}
},
{
title: "TITLE 2",
filename: "IMG_9225.jpg",
url: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225.jpg",
alt: "",
caption: "",
width: 1781,
height: 2560,
sizes: {
gallery_thumbnail: "http://www.bioner.fi/assets/uploads/2016/08/IMG_9225-300x431.jpg",
"gallery_thumbnail-width": 300,
"gallery_thumbnail-height": 431
}
},
]
}
]
}
];
var finalString = "<section>";
var yearList = "<ul>";
for(var i in data) {
var yearData = data[i];
yearList += "<li>" + yearData['year'] + "</li>";
var galaryData = data[i]['gallery'];
var folderList = "<ul>";
for(var j in galaryData) {
folderList += "<li>" + galaryData[i]["folder_heading"] + "</li>";
var imageData = galaryData[i]["folder_images"];
var imgDiv = "<div>";
for(var k in imageData ) {
imgDiv += "<img />";
}
imgDiv += "</div>";
}
finalString += folderList + imgDiv;
}
yearList += "</ul>";
finalString += "</section>";
finalString = yearList + finalString;
console.log(finalString);
Standard javascript is more than enough. Json is a Javascript object Notation is what it is. You should be able loop through all json elements with some recursive function like here: LINK
Related
I am pretty new in Javascript and I have problem. Currently I am working on project, that is actually my practice project and I'm trying to make shopping cart page. My problem is with JSON file, I don't know how to render it (show it within HTML in browser), I have local JSON file with some products. Here is my code of main page, app.js(where is my function for JSON file) and JSON file with products
HTML file
<!DOCTYPE html>
<html lang="en">
<head>
<title>Shopping Cart</title>
<meta charset="utf-8" />
<meta name="description" content="cobe" />
<meta name="author" content="cobe" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="../style/style.css" />
</head>
<body>
<main class="main-wrapper">
<div class="items">
<div class="item">
<div class="image">
<img src="" alt="" class="img">Image</img>
</div>
<h2 class="item-name">Name of item</h2>
<h3 class="price">Price</h3>
<button class="button">Add item</button>
</div>
<div id="products" class="list"></div>
</div>
</main>
<script type="text/javascript" src="../products.json"></script>
<script type="text/javascript" src="../app.js"></script>
app.js file
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let response = JSON.parse(xhttp.responseText);
let products = response.products;
let output = '';
for (let i = 0; i < products.length; i++) {
output += '<li>' + products[i].name + '</li>';
}
document.getElementById('products').innerHTML = output;
}
};
xhttp.open("GET", "products.json", true);
xhttp.send();
and JSON file which is called products.json
{
"products": [
{
"id": 1,
"name": "Eggs",
"image": "https://d17zv3ray5yxvp.cloudfront.net/variants/W1ymDizfe679XsfX9uP8A5bU/7b27a910a7194c812eacf34700e38dcab3abed02f30837d1dad313c5651bb5fa",
"price": {
"amount": 7.99,
"currency": "Kn",
"measureUnit": "Kom"
}
},
{
"id": 2,
"image": "https://d17zv3ray5yxvp.cloudfront.net/variants/b1qEMnNGbwiwV5cWysofPoqz/7b27a910a7194c812eacf34700e38dcab3abed02f30837d1dad313c5651bb5fa",
"name": "Milk",
"price": {
"amount": 4.99,
"currency": "Kn",
"measureUnit": "Kom"
}
},
{
"id": 3,
"image": "https://d17zv3ray5yxvp.cloudfront.net/variants/1avpwnxKAEqEpTf1k3VCbBbg/7b27a910a7194c812eacf34700e38dcab3abed02f30837d1dad313c5651bb5fa",
"name": "Cheese",
"price": {
"amount": 44.99,
"currency": "Kn",
"measureUnit": "Kg"
}
}
]
}
So my question is what should I write in HTML file so I could get let's say name of product from JSON file into my div which is declared in HTML file for name or am I missing some more JS functions? Currently my page is blank because I couldn't resolve how to get everything from JSON file.
HTML files are in views folder, app.js and products.json are outside of views folder.
Thanks!
Try using a function to generate the template and set the innerHTML property.
You can use this populateProducts function once you have got the response JSON from the API. This will generate the template and will update the DOM.
var myData = {
"products": [
{
"id": 1,
"name": "Eggs",
"image": "https://d17zv3ray5yxvp.cloudfront.net/variants/W1ymDizfe679XsfX9uP8A5bU/7b27a910a7194c812eacf34700e38dcab3abed02f30837d1dad313c5651bb5fa",
"price": {
"amount": 7.99,
"currency": "Kn",
"measureUnit": "Kom"
}
},
{
"id": 2,
"image": "https://d17zv3ray5yxvp.cloudfront.net/variants/b1qEMnNGbwiwV5cWysofPoqz/7b27a910a7194c812eacf34700e38dcab3abed02f30837d1dad313c5651bb5fa",
"name": "Milk",
"price": {
"amount": 4.99,
"currency": "Kn",
"measureUnit": "Kom"
}
},
{
"id": 3,
"image": "https://d17zv3ray5yxvp.cloudfront.net/variants/1avpwnxKAEqEpTf1k3VCbBbg/7b27a910a7194c812eacf34700e38dcab3abed02f30837d1dad313c5651bb5fa",
"name": "Cheese",
"price": {
"amount": 44.99,
"currency": "Kn",
"measureUnit": "Kg"
}
}
]
};
function populateProducts() {
var template = '';
for(let index = 0; index < myData.products.length; index++) {
template +=
"<div>Name: " + myData.products[index].name + "</div>" +
"<div>Image: <img class='my-image' src='" + myData.products[index].image + "' /></div>"+
"<div>Amount: " + myData.products[index].price.amount + "</div>" +
"<div>Currency: " + myData.products[index].price.currency + "</div>" +
"<div>MeasureUnit: " + myData.products[index].price.measureUnit + "</div>";
}
document.getElementById('item-wrapper').innerHTML = template;
}
populateProducts();
.my-image {
max-width: 50px;
}
<main class="main-wrapper">
<div id="item-wrapper"></div>
</main>
If you're able to use a templating system such as Handlebars.js, you could convert the repeated part of your HTML (the item div) into a template and then populate it with the data. Adapting the 'Getting Started' example from the Handlebars page, the template would look something like:
<script id="item-template" type="text/x-handlebars-template">
{{#each products}}
<div class="item">
<div class="image">
<img src="{{image}}" alt="" class="img">Image</img>
</div>
<h2 class="item-name">{{name}}</h2>
<h3 class="price">{{price.amount}}</h3>
<button class="button">Add item</button>
</div>
{{/each}}
</script>
Then in the script you would register the template:
const source = document.getElementById("item-template").innerHTML;
const template = Handlebars.compile(source);
...and then inside your HTTP request, you can pass the data to the template and it'll return HTML which you can add to the DOM as you wish:
const html = template(context);
I have a simple ul and li tags which contains state and capitals, here I need to get all the data from json dynamically and to append into main div of class "details",Here I just hardcoded but actually it should come from json given below in the same way.Here is the code below
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="details">
<ul>
<li>state</li>
<li>
<ul>state1</ul>
<ul>state2</ul>
</li>
<li>capital</li>
<li>
<ul>capital1</ul>
<ul>capital2</ul>
</li>
</ul>
</div>
jquery
$(document).ready(function () {
$.ajax({
type: "GET",
url: "sample.json",
success: function(result)
{
console.log(result);
}
});
});
json
{
"state": [{
"name": "state1"
},
{
"name": "state2"
}
],
"capital": [{
"name": "capital1"
},
{
"name": "capital2"
}
]
}
Word of warning: your proposed markup isn't valid (Error: Text not allowed in element ul in this context.). Even so, it sounds like it's the appropriate output for this task.
I'll assume your Ajax request is working and returns a valid JSON structure as the result variable.
Having handled set up, here's the code to generate your structure:
const result = {
"state": [
{"name": "state1"},
{"name": "state2"}
],
"capital": [
{"name": "capital1"},
{"name": "capital2"}
]
};
const root = document.createElement("ul");
document.querySelector(".details").appendChild(root);
for (const key in result) {
const title = document.createElement("li");
title.innerText = key;
root.appendChild(title);
const list = document.createElement("li");
root.appendChild(list);
for (const o of result[key]) {
const ul = document.createElement("ul");
ul.innerText = o.name;
list.appendChild(ul);
}
}
<div class="details"></div>
I am using Knockout.js as a way to dynamically update a view from a JSON response. The JSON looks like the following:
var data = {
"Properties": {
"Engine Capacity": "1499cc",
"Doors": 3,
"Extras": [
"LED lights",
"4WD"
],
"Model": "123a"
}
};
I have figured out a way in JavaScript to construct my <li> elements:
for (var field in data['Properties']) {
var value = data['Properties'][field];
var out = '<li>' + field + ': ' + value + '</li>';
console.log(out);
// <li>Engine Capacity: 1499cc</li>
// <li>Doors: 3</li>
}
I know this isn't an ideal way as constructing HTML in JavaScript isn't best practice. There is a way to print out the value in Knockout but with hardcoded values:
<ul data-bind="foreach:$root.Properties">
<li data-bind="text:$data:Doors"></li>
<li data-bind="text:$data.Model"></li>
But I was wondering whether it could be possible to get Knockout.js to look like what I'm returning in the JavaScript code?
Here's how you can do it:
var data = {
"Properties": {
"Engine Capacity": "1499cc",
"Doors": 3,
"Extras": [
"LED lights",
"4WD"
],
"Model": "123a"
}
};
var viewModel = {
data: ko.mapping.fromJS({"Properties": data.Properties})
};
ko.applyBindings(viewModel);
<ul data-bind="foreach: data.Properties">
<li>
<b data-bind="foreachprop: props"> :
<span data-bind="value"> </span>
</b>
</li>
</ul>
More reference:
How to use knockout to iterate over an object (not array)
Mapping: foreach binding work only the first time
I'm looking to filter a list of objects in a JSON array when an HTML checkbox is clicked. I know about the JavaScript array.sort() method but how do I eliminate items based on checkbox clicks? Do I need an event listener?
My JSON looks as so:
{ "lots" : [
{
"name" : "Parking Lot Name",
"price" : 2,
"cash" : true,
"credit" : false,
"address" : "1234 W Main Ave",
"center" : {
"lat" : 67.659414,
"lng" : -137.414730
}... etc.
So if I've got a form that includes checkboxes for eliminating parking lots based on payment type, how should I go about implementing that? I've read about a jQuery array.grep() function, is that it?
My page is being built using a JS loop like this:
makeList(){
var self = this;
self.jsonFile = $.ajax({
type: 'GET',
url: 'assets/data/default.json',
dataType: 'json',
success: function(response) {
console.log(response);
}
});
self.jsonFile.done(function(data){
//Sort low to high by default
data.lots.sort(function(a, b){
return(a.price > b.price)
});
for (var i = 0; i < data.lots.length; i++) {
document.getElementById('jsonList').innerHTML +=
'<li>
<div id="text">
<p class="price">
$' + data.lots[i].price + '.00
</p>
<p class="info">' +
data.lots[i].address +
'</p>
</div>
<form method="get">
<button type="submit" formaction="https://www.google.com/maps/dir/Current+Location/' +
data.lots[i].address +
'">Directions
</button>
<button type="submit" formaction="detail-view.html">Details
</button>
</form>
</li>';
}
});
}
You can eliminate like this:
You have to bind a onchange function to checkboxes then use following way to that function
data = [{
"name": "name",
"location1": "no",
"description": "description of services"
},
{
"name": "name2",
"location1": "yes",
"description": "description of services2"
},
{
"name": "name3",
"location1": "no",
"description": "description of services3"
}
];
b = $.grep(data, function(el, i) {
return el.location1.toLowerCase() === "yes"
});
You can get the lots where the payment type is say "cash" using:
var cashLots = data.lots.filter(function(lot){return lot.cash});
as an arrow function:
var cashLots = data.lots.filter(lot => lot.cash);
Im kinda new to Angular/ JSON Objects and i'm trying to get something from a nested object.
That is not so hard, but the problem is that the JSON object has an that changes on the fly.
Below an example of 1 object from a complete list of JSON objects. As you can see this part of a larger object.
What i want is the task.assignment.name for each task in the ng-repeat, but i cant get to the assignment.name because of the integer that's between the assignment and name.
Look at my object:
{
"project-45": {
"label": "Bar",
"url": "http://someurl.com/api",
"assignments": {
"5147": {
"id": 5147,
"type": "Task",
"project_id": 45,
"assignee_id": 9,
"label_id": 27,
"category_id": 0,
"milestone_id": 0,
"name": "assignmentname",
"body": "<p>body.</p>",
"created_on": "2015-06-17 13:40:31",
"age": 6,
"created_by_id": 66,
"created_by_name": "Jelle",
"created_by_email": "jelle#example.com",
"due_on": "2015-06-19",
"priority": 0,
"task_id": 81,
"project": "Bar"
}
}
}
}
project-75": {
"label": "Another",
"url": "http://mijn.example.com/api",
"assignments": {
"5153":
...
This is my controller:
var main = angular.module("main", []);
main.controller("mainCntrl", function($scope, $http){
var apiUrl = "http://my.example.com/api.php?&format=json&";
var apiKey = "&auth_api_token=somekey";
var onUserComplete = function(response){
$scope.user = response.data;
console.log("User Data loaded");
}
var onTasksComplete = function(response){
$scope.tasks = response.data;
console.log("Tasks loaded");
}
$http.get(apiUrl + "path=my-tasks" + apiKey).then(onTasksComplete);
$http.get(apiUrl + "path=people/1/users/9" + apiKey).then(onUserComplete);
}
);
and finally the index.html file with the ng-reapter
<div class=" block full border">
<h3>Active tasks</h3>
<ul ng-repeat="task in tasks">
<li>
<ul>
<li>{{$index+1}}</li>
<li>Project: {{task.label}}</li>
<li>task name: {{task.assignments.name}}</li> <!-- Doesnt work -->
<li>task description: {{task.assignments.body}}</li> <!-- Doesnt work -->
</ul>
</li>
</ul>
</div>
Thanks!
<div class=" block full border">
<h3>Active tasks</h3>
<ul ng-repeat="task in tasks">
<li>
<ul ng-repeat="assignment in task.assignments">
<li>{{$index+1}}</li>
<li>Project: {{assignment.label}}</li>
<li>task name: {{assignment.name}}</li> <!-- Doesnt work -->
<li>task description: {{assignment.body}}</li> <!-- Doesnt work -->
</ul>
</li>
</ul>
</div>