JavaScript: Modifying DOM and populating it with JSON data [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
first time asking for help so if I need to present myself in a specific section please point it out!
As said in the title, i've got a JSON data base, and need to populate a website with it's content. It's the first time a try doing something like this (still learning JS).
Here is an image of the expected result. If you prefer, this is the expected output in HTML:
<div class="cardsection">
<div class="card">
<div class= "photoandname">
<div class="profilphoto">
</div>
<h2 class="name"> </h2>
</div>
<div class="informations">
<h3 class="location"> </h3>
<p class="caption"> </p>
<p class="price"> </p>
</div>
<div class="tags">
<button class="tagButton"> </button>
<button class="tagButton"> </button>
</div>
</div>
</div>
The problems I have are :
For the Tag section, each card doesn't have the same number of tags. I understand that i need a nested loop, to access the nested array in the JSON data. I tried somethings out but didn't fully manage nor understand how that works so could one of you guys help me out and explain or show me?
Also i keep having an error for the "for" section of my Items loop ( Cannot read property 'length' of undefined) wich I don't get as the property is defined just above (var items = json.items;)
I'm not 100% sure my code is correct. Coded as I did, is it going to properly create each card with it's children ? ( without the identic classnames between cards mislead the appending? And with the aria-labels properly set?)
HTML code :
<div class="cardsection"> </div>
JS code :
var json = {
"photographers": [
{
"name": "jonna",
"id": 125,
"city": "paris",
"country": "UK",
"tags": ["portrait", "events", "travel", "animals"],
"tagline": "Doing my best",
"price": 400,
"portrait": "MimiKeel.jpg"
}
]};
var cardsection = document.getElementsByClassName("cardsection")[0];
var items = json.items;
for(var i = 0; i < items.length; i++) {
var cards = document.createElement("div");
cards.classList.add('card');
cards.setAttribute("aria-label", "Photographe card");
cardsection.appendChild(cards);
var photoandname = document.createElement("div");
photoandname.classList.add('photoandname');
photoandname.setAttribute("aria-label", "Profil photo and name section");
photoandname.innerHTML = items[i].portrait;
cards.appendChild(photoandname);
//ariel and alt to check
var profilphoto = document.createElement("img");
profilphoto.src = items[i].portrait;
profilphoto.alt = "Photographer's profil image";
profilphoto.classList.add('profilphoto');
profilphoto.innerHTML
photoandname.appendChild(profilphoto);
var name = document.createElement("h2");
name.classList.add('name');
name.innerHTML = items[i].name;
divphotoname.appendChild(name);
var informations = document.createElement("div");
informations.classList.add('informations');
card.appendChild(informations);
var location = document.createElement("h3");
location.classList.add('location');
location.innerHTML = items[i].city + items[i].country;
informations.appendChild(location);
var caption = document.createElement("p");
caption.classList.add('caption');
caption.innerHTML = items[i].tagline;
informations.appendChild(caption);
var price = document.createElement("p");
price.classList.add('price');
price.innerHTML = items[i].price;
informations.appendChild(price);
var tags = document.createElement("div");
tags.classList.add('tags');
var tagItems = json.items[i].tags;
for(var j = 0; j < tagItems.length; j++) {
var tagButton = document.createElement(button);
tagButton.classList.add('tagButton');
tagButton.id = tagItems[j]; /*ID needs to be the tag itself for a further filter functionality*/
tagButton.innerHTML = tagItems[j]; /*And setting the innerhtml of the button as the tag itself*/
tags.appendChild(tagButton);
}
card.appendChild(tags);
}
Thanks for any help and advice you can give me

https://jsfiddle.net/chille1987/s35qz4wf/
Javascript
const jsonFile = {
"photographers": [
{
"name": "jonna",
"id": 125,
"city": "paris",
"country": "UK",
"tags": ["portrait", "events", "travel", "animals"],
"tagline": "Doing my best",
"price": 400,
"portrait": "MimiKeel.jpg"
}
]
};
var cardsection = document.getElementsByClassName("cardsection")[0];
var items = jsonFile;
console.log(items.photographers.length);
for(var i = 0; i < items.photographers.length; i++) {
var card = document.createElement("div");
card.classList.add('card');
card.setAttribute("aria-label", "Photographe card");
cardsection.appendChild(card);
var photoandname = document.createElement("div");
photoandname.classList.add('photoandname');
photoandname.setAttribute("aria-label", "Profil photo and name section");
photoandname.innerHTML = items.photographers[i].portrait;
card.appendChild(photoandname);
var profilphoto = document.createElement("img");
profilphoto.src = items.photographers[i].portrait;
profilphoto.alt = "Photographer's profil image";
profilphoto.classList.add('profilphoto');
photoandname.appendChild(profilphoto);
var photographerName = document.createElement("H2");
photographerName.classList.add('name');
photographerName.textContent = items.photographers[i].name;
photoandname.appendChild(photographerName);
var informations = document.createElement("div");
informations.classList.add('informations');
card.appendChild(informations);
var caption = document.createElement("p");
caption.classList.add('caption');
caption.textContent = items.photographers[i].tagline;
informations.appendChild(caption);
var price = document.createElement("p");
price.classList.add('price');
price.innerHTML = items.photographers[i].price;
informations.appendChild(price);
var tags = document.createElement("div");
tags.classList.add('tags');
var tagItems = items.photographers[i].tags;
console.log(tagItems)
for(var j = 0; j < tagItems.length; j++) {
var tagButton = document.createElement('button');
tagButton.classList.add('tagButton');
tagButton.id = tagItems[j]; /*ID needs to be the tag itself for a further filter functionality*/
tagButton.textContent = tagItems[j]; /*And setting the innerhtml of the button as the tag itself*/
tags.appendChild(tagButton);
}
card.appendChild(tags);
}

The javascript looks pretty good (except it should be json.photographers, not json.items). But why jump straight into the big heavy model? Try working on
"photographers" : [ { "name" : "jonna" } ]
Start small, make sure your code works, then expand. Baby steps get more things done.

Related

Js: show JSON data in HTML

below i have JSON data for cafe menu and i want to view them in HTMl page as grid view showing image, name and price ... is there a way to do this in JS and HTML?
[
{
"placeImage": "assets/images/straw-1.jpg",
"placeName": " pizza",
"price": 15000
},
{
"placeImage": "assets/images/straw-1.jpg",
"placeName": " Burger",
"price": 15000
},
]
This partly depends on if you're processing that data on the server side or the client side. Either way, you can access the JSON data in your JS script like this:
const cafeData = require('./cafe.json'); // If it is in the same directory as the script
console.log(cafeData);
If you're trying to create a dynamic HTML page with data from a server, then try using a templating language like EJS, which is the simplest to learn for a JavaScript developer. If you're on the client side then you'll need to use the DOM to insert that data into your HTML. For example, if you have an element in a product card like this: <div id="pizzaPriceDisplay">
Then you're JS code might look something like this:
const priceDisplay = document.querySelector('#pizzaPriceDisplay');
pizzaPriceDisplay.innerText = '$' + cafeData[0].price;
Hope I helped and happy coding :)
Sure! Lets asume that your JSON data is stored in a javascript string
const jsonData = "..."; //The JSON string
The first thing to do would be to turn that json data into a javascript object that we can iterate. We can do that like this:
const data = JSON.parse(jsonData);
Cool, now, as far as i can tell you want to turn every item into an HTML element (like a card) and display all of them in a grid. The grid part can be pretty trivial now days using CSS Grid: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout.
So somewhere in your HTML you would want to have an element like this:
...
<div class="grid-container" id="menu-items-container">
<!-- We are going to insert your rendered data here -->
</div>
...
And somewhere in your css you will have something like this
...
.grid-container{
display:grid;
/* ... */
}
...
Now for the fun part. Taking your the contents of that data variable and turning them into html
//This function will take the data of one item
//And return an html element
function renderItem(item){
const base = document.createElement("div");
const img = document.createElement("img");
const title = document.createElement("h1");
const price = document.createElement("h2");
img.src = item.placeImage;
title.textContent = item.placeName;
price.textContent = item.price;
base.appendChild(img);
base.appendChild(title);
base.appendChild(price);
return base;
}
const container = document.querySelector("#menu-items-container");
for (let item of data){
container.appendChild(renderItem(item));
}
And that's about it, you'll probably want to style the inserted elements a little better, which you can do adding a few classes here and there. But you probably get the gist of it.
For the particular data you gave in the example this should produce something similar to this:
<div class="grid-container" id="menu-items-container">
<div>
<img src="assets/images/straw-1.jpg"/>
<h1>pizza</h1>
<h2>15000</h2>
</div>
<div>
<img src="assets/images/straw-1.jpg"/>
<h1>Burger</h1>
<h2>15000</h2>
</div>
</div>
Simply parse the JSON to JS object
let menu = JSON.parse('[{"placeImage": "assets/images/straw-1.jpg", "placeName": "Pizza", "price": 15000},{"placeImage": "assets/images/straw-1.jpg", "placeName": "Burger","price": 15000}]');
Then you can iterate over it using a loop and draw the HTML you want ex: Table
function drawMenu(menu) {
let tableElement = document.createElement("table");
// Draw the headers of the table
let headerTableRowElement = document.createElement("tr");
let imageHeaderElement = document.createElement("th");
imageHeaderElement.innerText = "Image";
headerTableRowElement.appendChild(imageHeaderElement);
let nameHeaderElement = document.createElement("th");
nameHeaderElement.innerText = "Name";
headerTableRowElement.appendChild(nameHeaderElement);
let priceHeaderElement = document.createElement("th");
priceHeaderElement.innerText = "Price";
headerTableRowElement.appendChild(priceHeaderElement);
tableElement.app.appendChild(headerTableRowElement);
// Draw the items in the menu
for (let i = 0; i < menu.length; ++i) {
let item = menu[i];
let menuItemTableRowElement = document.createElement("tr");
let imageElement = document.createElement("td");
let image = document.createElement("img");
image.setAttribute("src", item.placeImage);
imageElement.appendChild(image);
menuItemTableRowElement.appendChild(imageElement);
let nameElement = document.createElement("td");
nameElement.innerHTML = item.placeName;
menuItemTableRowElement.appendChild(nameElement);
let priceElement = document.createElement("td");
priceElement.innerHTML = item.price;
menuItemTableRowElement.appendChild(priceElement);
tableElement.appendChild(menuItemTableRowElement);
}
document.appendChild(tableElement);
}

Displaying JSON information with HTML and JavaScript

I validated my code and syntactically it all seems and looks correct to me. I am console logging my JSON file.
Issue:
I can't access the information from the file. I tried to run the function productInfo on its own. So, I suspect the issue is within there and it's not pulling in the information correctly. But I can't seem to find the exact issue.
Can anyone help with this?
Javascript:
// mapping jsonn file to varibale and starting the request to get information
let requestJson = 'https://brody413.github.io/JS-LAB-8/products.json';
let myRequest = new XMLHttpRequest();
myRequest.open('GET', requestJson);
myRequest.responseType = 'json';
myRequest.send();
// onload event so nothing happens till we have json
myRequest.onload = function () {
let jsonFile = myRequest.response;
console.log(jsonFile);
productInfo(jsonFile);
}
function productInfo(json) {
let sectionElement = document.querySelector('section');
let topDeals = json['topDeals'];
for (let i = 0; i < topDeals; i++) {
// creating elements to hold info
let div = document.createElement('div');
let h2 = document.createElement('h2');
let h3 = document.createElement('h3');
let p1 = document.createElement('p');
let list = document.createElement('ul');
let img = document.createElement('img');
// giving each element the info
h2.textContent = topDeals[i].name;
h3.textContent = topDeals[i].price;
p1.textContent = topDeals[i].description;
let features = topFlavors[i].features;
for (let x = 0; x < ingredients.length; x++) {
let feature = document.createElement('li');
feature.textContent = features[x];
list.appendChild(feature);
}
div.appendChild(h2);
div.appendChild(h3);
div.appendChild(p1);
div.appendChild(list);
sectionElement.appendChild(div);
console.log(div);
}
}
JSON:
{
"companyName": "I Scream Inc.",
"headOffice": "Barrie, Ontario",
"established": 2001,
"active": true,
"topDeals": [{
"name": "Bacon Scented Mustache",
"price": 4.07,
"description": "Now you can smell bacon all day in peace.",
"features": [
"smells like bacon",
"extra manly"
],
"image": "bacon-scented-mustache.jpg"
},
{
"name": "Dill pickle lip balm",
"price": 11.95,
"description": "Take your look to the next level with this amazing & dill-icious lip balm",
"features": [
"dill-icious",
"beautiful green colour"
],
"image": "dill-pickle-lip-balm.jpg"
},
{
"name": "Dancing with cats",
"price": 13.22,
"description": "Learn intrepetive dance with your feline friend!",
"features": [
"all the latest dance moves",
"truly bond with your cat through dance"
],
"image": "dancing-with-cats.jpg"
}
]
}
<html>
<head>
<meta charset="utf-8" />
<title>MOD3 WEEK 8 - JSON</title>
<script src='main.js' async></script>
</head>
<body>
<header>
<h1>I Scream INC</h1>
<p>Product Information is Below</p>
</header>
<main>
<h3>PRODUCTS</h3>
<section>
</section>
</main>
<footer>
<p>Brody McColeman - WEEK 8 - SUMMER 2020</p>
</footer>
</body>
</html>
Few issues in your for statement and also you are not doing querySelector properly.
For querySelector you need to use class or the id selector so it will check the exact class or id you are looking for
I have added and using forEach loop and simplified your code as well
Added comments as well to highlight stuff which needed a fix.
Run snippet below to see it working
let requestJson = 'https://brody413.github.io/JS-LAB-8/products.json';
let myRequest = new XMLHttpRequest();
myRequest.open('GET', requestJson);
myRequest.responseType = 'json';
myRequest.send();
// onload event so nothing happens till we have json
myRequest.onload = function() {
let jsonFile = myRequest.response;
//console.log(jsonFile);
productInfo(jsonFile);
}
function productInfo(json) {
//All data will be appended here
let sectionElement = document.querySelector('.section');
let topDeals = json['topDeals'];
//Foreach Loop for data
topDeals.forEach(function(data) {
// creating elements to hold info
let div = document.createElement('div');
let h2 = document.createElement('h2');
let h3 = document.createElement('h3');
let p1 = document.createElement('p');
let list = document.createElement('ul');
let img = document.createElement('img');
// giving each element the info
h2.textContent = data.name;
h3.textContent = data.price;
p1.textContent = data.description;
//Foreach Loop for featues
data.features.forEach(function(data) {
let feature = document.createElement('li');
feature.textContent = data
list.appendChild(feature);
})
div.appendChild(h2);
div.appendChild(h3);
div.appendChild(p1);
div.appendChild(list);
//Append all the child element to parent .section
sectionElement.appendChild(div);
})
}
<section class="section">
</section>

Printing an Ordered List from a JS file

I have a js file with the following array
var fruits = [ "Apples","Oranges","Pears","Grapes","Pineapples","Mangos" ];
In my HTML file I want to create a container and write an ordered list containing all the fruits in the array to the container I just created, however I'm having serious trouble and I can't find much online help. I'm a beginner, this is what I have
<div class = "container1">
</div>
<h3>Fruits</h3>
<html>
<head>
<script src="Web Programming/Assignments/Assignment #3/assignment3/list.js"></script>
</head>
<body>
<div container1= "fruits"></div>
</body>
You should give the element an id, your custom html attribute would work as a selector, but the typical way would be the id. Then you can simple create some elements in a loop, giving them the element's text content:
var fruits = [ "Apples","Oranges","Pears","Grapes","Pineapples","Mangos" ];
var el = document.getElementById('fruits');
var ol = document.createElement('ol');
el.appendChild(ol);
fruits.forEach(function (fruit) {
var f = document.createElement('li');
f.appendChild(document.createTextNode(fruit));
ol.appendChild(f);
});
<div id="fruits"></div>
Just in case you insist on the container1=... you can select that with
var el = document.querySelector('div[container1="fruits"]');
Firstly include your script in your html file. At the bottom of the body.
Give your container id of container or as you like.
And code will be something like this:
var arrayFruits = ["bananas", "apples", "etc"];
var container = document.getElementById("container");
for (var i = 0; i < arrayFruits.length; i++) {
var list = document.createElement("li");
list.innerHTML = arrayFruits[i];
container.appendChild(list);
}

Create Repeatable HTML Form and Load Info from a JS Array

I have a JS array with info in it. I want to populate some sort of repeatable object such that I can display all the info in the same way (formatted). I assumed I would need to use a HTML form, but now can't figure out how to exactly populate it with the information from my JS array. I want to make this happen on a page load, but for right now I am trying to test it with a button.
<html>
<head>
</head>
<body>
<script>
var myArray = [
{
"title" : "My First Place",
"address": "My First Address",
},
{
"title" : "Treehouse",
"address": "off in the woods",
},
{
"title" : "My New Place",
"address": "Home Sweet Home",
}
];
function addRow() {
var itm = document.getElementById("infoArea");
var cln = itm.cloneNode(true);
for(var i = 0; i < myArray.length; i++){
document.getElementById("repeatafterme").appendChild(cln);
}
}
</script>
<div id="repeatafterme"></div>
<form name="myform" id="infoArea">
<fieldset>
<legend><label id="myFormID"><output name="title"></output><label></legend>
<label><output name="address"></output></label>
</fieldset>
</form>
<INPUT TYPE="button" NAME="myButton" VALUE="Press This" onclick="addRow()">
</body>
</html>
itm.cloneNode(true) must be within the block for and set different id to element new.
To set value of array title and address should access to children for get elements out
function addRow() {
var itm = document.getElementById("infoArea");
for(var i = 0; i < myArray.length; i++){
var cln = itm.cloneNode(true);
cln.id = "id" + i;
var outTitle = cln.childNodes[1].childNodes[1].childNodes[0].childNodes[0];
outTitle.value = myArray[i].title;
var outAddress = cln.childNodes[1].childNodes[3].childNodes[0];
outAddress.value = myArray[i].address;
document.getElementById("repeatafterme").appendChild(cln);
}
}
result: https://jsfiddle.net/cmedina/sL0v07tt/1/

getElementById() .innerHTML/.src

I'm trying to create a simple javascript game for college and am having trouble getting what i want to display on screen.
my script is as follows:
var qArray = new Array();
qArray[0] = {image:"Images/q1.png"};
qArray[1] = {image:"Images/q2.png"};
qArray[2] = {image:"Images/q3.png"};
qArray[3] = {image:"Images/q4.png"};
qArray[4] = {image:"Images/q5.png"};
var count = 0;
var question = qArray.splice(count,1);
when i use this i get "undefined":
document.getElementById("question").innerHTML = question.image;
and when i use this i get nothing:
document.getElementById("question").src = question.image;
my html is just a simple div like so:
<div id = "question" align = "center">
</div>
i need to have the "count" variable because it increments to show the next image for the next question
if anyone could help that would be great
Here is a working Fiddle. qArray.splice() doesn't work because it actually removes that element from the array and returns a new array while you were just looking for a specific index in the array (not to mention you just deleted the element you were looking for)
This works. I used a random imgur image to show that it does indeed load.
<html><head></head><body>
<img src="" id="question"></img>
<script type="text/javascript">
var qArray = new Array();
qArray[0] = {image:"http://i.imgur.com/pGpmq.jpg"};
qArray[1] = {image:"Images/q2.png"};
qArray[2] = {image:"Images/q3.png"};
qArray[3] = {image:"Images/q4.png"};
qArray[4] = {image:"Images/q5.png"};
var count = 0;
var question = qArray[count];
document.getElementById('question').src = question.image;
</script>
</body>
</html>

Categories