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);
Related
How to feed template to HTML from Javascript? Sounds confusing? I'll try my best to explain after put all the codes in here...
I have index.html here:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Inject Template</title>
</head>
<body>
<div id="app">
<div v-html="injectHTML" v-if="injecting"></div>
<div id="chart">
<ol>
<li id="card-wrapper">
<div id="card">
<employee-card :info="emp.chart[1]"></employee-card>
</div>
</li>
</ol>
</div>
</div>
<!-- Vue.js Component: Employee Card Template -->
<script type="text/x-template" id="employee-card-template">
<div class="employee-wrapper" v-if="info" :id="info.id">
<a class="node" :href="'#'+info.id">
<div class="empinfo">
<p class="name">{{info.name}}</p>
<p class="office">{{info.office}}</p>
<p class="title">{{info.title}}</p>
</div>
</a>
</div>
</script>
<script src="lib/vue/dist/vue.js"></script>
<script src="js/app.js"></script>
</body>
</html>
and here is app.js
const app = new Vue({
el: "#app",
data: {
emp: [], //collect employee information from JSON
injectHTML: '',
injecting: false,
key: 0
},
watch: {
key: function () {
app.$forceUpdate();
app.injecting = true;
}
},
created: function () {
this.loadEmpJson();
setTimeout(() => { this.inject(); }, 500);
},
methods: {
loadEmpJson: function () {
const xhr_oho = new XMLHttpRequest();
xhr_oho.open('GET', 'data/employee.json', true);
xhr_oho.responseType = 'text';
xhr_oho.send();
xhr_oho.onreadystatechange = function () {
console.log(`xhr_oho.readyState: ${xhr_oho.readyState}`)
console.log(`xhr_oho.status: ${xhr_oho.status}`)
console.log(`xhr_oho.statusText: ${xhr_oho.statusText}`)
}
xhr_oho.onload = function () {
app.emp = JSON.parse(xhr_oho.responseText);
}
},
inject: function () {
this.injectHTML =
`<div id="chart">
<ol>
<li id="card-wrapper">
<div id="card">
<employee-card :info="emp.chart[0]"></employee-card>
</div>
</li>
</ol>
</div>`
setTimeout(() => { this.key++; }, 500);
}
}
});
Vue.component('employee-card', {
template: '#employee-card-template',
props: {
info: { type: Object, default: () => ({}) }
}
})
lastly, the excerpt employee.json
{
"description": "ABC Company Organizational Chart",
"chart": [
{
"name": "Jimmy Moore",
"office": "Front Office",
"title": "CEO/Owner"
},
{
"name": "Betty Kahoolawe",
"office": "Front Office",
"title": "President"
},
{
"name": "David Merrill",
"office": "Front Office",
"title": "Vice President",
"assistants": [
{
"name": "Amanda Cochran",
"office": "Front Office",
"title": "Executive Assistant"
},
{
"name": "Savannah Clewiston",
"office": "Front Office",
"title": "Budget Officer"
}
]
}
]
}
I would like to be able to feed multi marker template (employee-card) dynamically from app.js. Reason for this, I will have a recursive collecting data from JSON file and elaborate the employee-wrapper template depending on data from JSON. Grouping by the employees such as office, division, component, and branch. Also grouping by the employees under each supervisor where it can be expand and collapse those employees under the supervisor.
But the point I need to be able to feed the from app.js
You can see the output:
1.
1. Betty Kahoolawe
Front Office
President
which should be:
1. Jimmy Moore
Front Office
CEO/Owner
2. Betty Kahoolawe
Front Office
President
Your help is greatly appreciated! Thank you.
I have created a simple form using alpacajs, as per the documentation provided by alpacajs.org we can use properties such as optionsSource, schemaSource, viewSource, dataSource for loading the external json files into our application. But what i need is i need to use only one json file for all these. I mean instead of using all these 3 different properties can i use only one parameter for loading the single json file which comes from the backend. please check my code below..
<html>
<head>
<meta charset="UTF-8">
<title>My Little Alpaca Form</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"> </script>
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<script src="//code.cloudcms.com/alpaca/1.5.22/bootstrap/alpaca.min.js"></script>
<!-- typeahead.js https://github.com/twitter/typeahead.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.5/bloodhound.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.5/typeahead.bundle.min.js"></script>
<link href="//code.cloudcms.com/alpaca/1.5.22/bootstrap/alpaca.min.css" rel="stylesheet" />
<link type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body>
<div id="form1"></div>
<script type="text/javascript">
$(document).ready(function() {
$("#form1").alpaca({
"dataSource": "/fulfiller/connector-custom-data.json",
"schemaSource": "/fulfiller/connector-custom-schema.json",
"optionsSource": "/fulfiller/connector-custom-options.json",
"viewSource": "/fulfiller/connector-custom-view.json",
"view": {
"parent": "bootstrap-edit",
"layout": {
"template": "threeColumnGridLayout",
"bindings": {
"requestedfor": "column-1",
"location": "column-2",
"shortdescription": "column-3",
"description": "column-3",
}
},
"templates": {
"threeColumnGridLayout": '<div class="row">' + '{{#if options.label}}<h2>{{options.label}}</h2><span></span>{{/if}}' + '{{#if options.helper}}<p>{{options.helper}}</p>{{/if}}' + '<div id="column-1" class="col-md-6"> </div>' + '<div id="column-2" class="col-md-6"> </div>' + '<div id="column-3" class="col-md-12"> </div>' + '<div class="clear"></div>' + '</div>'
}
},
"options": {
"fields": {
"requestedfor": {
"type": "text",
"id": "requestedfor",
"label": "*Requested For",
"typeahead": {
"config": {},
"datasets": {
"type": "remote",
"displayKey": "value",
"templates": {},
"source": "http://www.alpacajs.org/data/tokenfield-ajax1.json"
}
}
},
"location": {
"type": "text",
"label": "*Location"
},
"shortdescription": {
"type": "text",
"label": "Short Description"
},
"description": {
"type": "textarea",
"rows": 5,
"cols": 40,
"label": "Description"
}
},
"form": {
"attributes": {
"action": "#",
"method": "post"
},
"buttons": {
"submit": {
"value": "Submit",
"class": "btn btn-default"
}
}
}
}
});
});
</script>
</body>
</html>
So here in the above code i have used these urls for loading json data..
"dataSource": "/fulfiller/connector-custom-data.json"
"schemaSource": "/fulfiller/connector-custom-schema.json"
"optionsSource": "/fulfiller/connector-custom-options.json"
"viewSource": "/fulfiller/connector-custom-view.json"
So instead of using these 3 different properties can i use only one property like "oneSingleJSONSource": "oneJSONRemoteFile.json"
Can anybody provide inputs?
For Alpaca to be inialized it must have a DOM element + a config object that contains the schema, options and other properties that Alpaca already knew in its core code, so in your case this is possible if you try to modify the alpaca core code... If your objective is only to optimize resource loading you can use only one json file that contains all the configuration and input them in the alpaca initialization $(dom).alpaca(_json_data_from_loaded_file). And if you want to have only schema, options and view settings in on file you should divide the data loaded to 3 objects, 1 for schema, 1 for options and the last one for view settings.
Tell me if you want more details on achieving this.
I'll be glad to help.
data = {"items": [
{
"title": "sample 1",
"author": "author 1"
},
{
"title": "sdample 2",
"author": "author 2"
}
]};
This is my json file.
Now I want to read this local json file in my js to print the values of json in HTML page
I dont want to use any httpsRequest.
NOTE: I am not using any web server
Below is my JS file
function data(languageClass){
var news = document.getElementsByClassName(languageClass)[0];
var item = json.items;// where json is local json copy which i want
console.log( "hiiii" + item);
for(var i = 0; i < item.length; i++) {
var h5 = document.createElement("h5");
h5.innerHTML = item[i].title;
news.appendChild(h5);
var p = document.createElement("p");
p.innerHTML = item[i].author;
news.appendChild(p);
}
}
below is my HTML file :
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="D:/Shubhankar/web/quess.json"></script>
<script type="text/javascript"
src="../web/Question.js"></script>
<title>Java Interview Question</title>
<link rel="icon" type="image/png" href="../img/icon.png">
</head>
<body onload='data("interviewQuestions")'>
<div class="interviewQuestions"></div>
</body>
</html>
data = {"items": [
{
"title": "sample 1",
"author": "author 1"
},
{
"title": "sdample 2",
"author": "author 2"
}
]};
This is not a valid JSON.
Without web server or XHR request, you cannot load your data. One way to get this data in your app is to have a JS file with JSON content in it.
Sample:
var data={"items": [
{
"title": "sample 1",
"author": "author 1"
},
{
"title": "sdample 2",
"author": "author 2"
}
]
}
Now call this JS file using script tag.
<script src="path/to/jsonfile.js"></script>
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
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<title>MongoDB Display</title>
<script>
$(document).ready(function(){
var Obj = $.getJSON("http://localhost:3000", function(){
alert("Success");
$(Obj.rows).each(function(index, element){
$(#tableID).append('<tr><td>' + element[1] + '</td><td><table><tr><td>'+ Obj.rows.scripts.element[0]
+ '</td>' + "/" + '<td>' + Obj.rows.scripts.element[1] + '</td></tr></table></td></tr>');
})
});
});
</script>
</head>
<body>
<div id="wrapper">
<h1>H 1</h1>
<table id="tableID" border = "1">
<th>
<td>PAGE</td>
<td>SCRIPTS</td>
</th>
</table>
</div>
</body>
</html>
In short;
I have a MongoDB ready to be displayed at localhost:3000. Server is running and I can display the data on the browser with localhost:3000 But when i try to run the above code on the browser, all i can get the js Alert("Success") and the hard coded part of the table. PAGE and SCRIPTS...
the data is:
{
"offset": 0,
"rows": [
{
"_id": {},
"url": "http://www.qweq.com\r",
"totalLines": 3084,
"scripts": [
{
"line": 111,
"tag": "\"asdas/etc/designs/qwe/assets/head-5.30.31.min.js\""
},{
"line": 3065,
"tag": "\"asdas/etc/designs/qwe/assets/common-5.30.31.min.js\""
},{
"line": 3067,
"tag": "\"asda/etc/designs/qwe/assets/category-5.30.31.min.js\""
}
]
},{
"_id": {},
"url": "http://www.qweqsd.com/qwdq23/qweq/qweqw/\r",
"totalLines": 3042,
"scripts": [
{
"line": 113,
"tag": "\"asda/etc/designs/asd/assets/head-5.30.31.min.js\""
},{
"line": 3023,
"tag": "\"asdasd/etc/designs/asd/assets/common-5.30.31.min.js\""
},{
"line": 3025,
"tag": "\"asdad/etc/designs/qwe/assets/category-5.30.31.min.js\""
}
]
},
How can I make this Json data to be display in a dynamic table?
Thank you.
This version is kind of working :) Maybe you'll find inspiration.
$(rows).each(function(index,element){
console.log(index); console.log(element);
$('#tableID').append('<tr><td>' + index + '</td><td>'+ element['url']
+ '</td>' + "/" + '<td>' + JSON.stringify(element['scripts']) + '</td></tr></table>');
});
http://jsfiddle.net/fw4f5L72/1/
It looks like you're missing quotes around the table name. Instead, you should have something like $('#tableID').
Additionally, you'll want your function call to include the data that it's returning to you. For example:
$.getJSON("http://localhost:3000", function(data){
alert("Success");
console.log(data);
});
Then, data will include the JSON object, and you can manipulate it however you please.