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>
Related
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);
}
I get valid HTML code using UrlFetchApp.fetch(url,options). The part I am interested in looks like
<script type="text/javascript">
var map = am4core.create("mapdiv", am4maps.MapChart);
map.geodata = am4geodata_worldLow;
map.projection = new am4maps.projections.Miller();
var polygonSeries = new am4maps.MapPolygonSeries();
polygonSeries.useGeodata = true;
map.series.push(polygonSeries);
// Configure series
var polygonTemplate = polygonSeries.mapPolygons.template;
polygonSeries.data = [{
"id": "AF",
"value0": "2",
"value3": 3.2,
"fill": am4core.color("#0C6175")
}, {
"id": "AL",
"value0": "2",
"value3": 2.5,
"fill": am4core.color("#0C6175")
}, {
"id": "DZ",
"name": "Algeria",
"value0": "1",
"value3": 3.2,
"fill": am4core.color("#68C2C3")
}];
polygonTemplate.propertyFields.fill = "fill";
</script>
Could you suggest how to get the value of polygonSeries.data javascript variable assigned to GAS variable? I cannot think of anything besides parsing the HTML line by line, find polygonSeries.data and then parse till I get }]; I do not think it is the best way though.
Suggestion
You can use this sample regex method script & adjust it based on your needs:
Script:
function getData() {
var htmlcontent = HtmlService.createHtmlOutputFromFile('Index').getContent(); //Sample line to get the content of the Html file
var clean = htmlcontent.replace(/ /g,''); //Clean the code by removing multiple spaces
var regExp = new RegExp("polygonSeries.data=(.*)polygonTemplate", "s");
var data = regExp.exec(clean)[1];
var arr = data.split(/\r?\n/) //split all data by new lines
var newArr = []; //container of all the values
arr.forEach(res => { //Sample lines of code to clean each values to be placed later as array values
if(res.length > 3){
try{
var temp = res.replace(",","").split(":");
newArr.push([temp[0].replace(/"/gm, ''),temp[1].replace(/"/gm, '')])
}catch{
var temp = res.split(":");
newArr.push([temp[0].replace(/"/gm, ''),temp[1].replace(/"/gm, '')])
}
}
});
Logger.log(newArr);
}
Sample Index.html file:
<!DOCTYPE html>
<HTML>
<HEAD>
<TITLE>Your Title Here</TITLE>
<script type="text/javascript">
var map = am4core.create("mapdiv", am4maps.MapChart);
map.geodata = am4geodata_worldLow;
map.projection = new am4maps.projections.Miller();
var polygonSeries = new am4maps.MapPolygonSeries();
polygonSeries.useGeodata = true;
map.series.push(polygonSeries);
// Configure series
var polygonTemplate = polygonSeries.mapPolygons.template;
polygonSeries.data = [{
"id": "AF",
"value0": "2",
"value3": 3.2,
"fill": am4core.color("#0C6175")
}, {
"id": "AL",
"value0": "2",
"value3": 2.5,
"fill": am4core.color("#0C6175")
}, {
"id": "DZ",
"name": "Algeria",
"value0": "1",
"value3": 3.2,
"fill": am4core.color("#68C2C3")
}];
polygonTemplate.propertyFields.fill = "fill";
</script>
</HEAD>
<BODY BGCOLOR="FFFFFF">
<CENTER><IMG SRC="clouds.jpg" ALIGN="BOTTOM"> </CENTER>
<HR>
Link Name
is a link to another nifty site
<H1>This is a Header</H1>
<H2>This is a Medium Header</H2>
Send me mail at <a href="mailto:support#yourcompany.com">
support#yourcompany.com</a>.
<P> This is a new paragraph!
<P> <B>This is a new paragraph!</B>
<BR> <B><I>This is a new sentence without a paragraph break, in bold italics.</I></B>
<HR>
</BODY>
</HTML>
Sample Result:
Based on Irvin's code I implemented this one. I was originally looking for simple solution where I would not have to use any kind of cycle - for nor each or so.
function getData(){
var html = getZZStat()
var clean = html.replace(/=/g,'') // remove = otherwise eval() would not work
var endString = "}]"
var regExp = new RegExp("polygonSeries.data(.*)"+endString, "s");
var data = regExp.exec(clean)[1]+endString
var tmp = data.replace(/\)/g,'').replace(/am4core.color\(/g,'') // remove variable "am4core" so eval() works
var finalData = eval(tmp)
console.log("finalData ",finalData.length)
console.log(finalData[0])
console.log(finalData[finalData.length-1])
console.log(finalData[finalData.length-2])
}
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.
I am trying to use an AJAX call to retrieve data from a movie API on the web. Here is my HTML code:
<html>
<head>
<meta charset=utf-8>
<title>Movie Database</title>
</head>
<body onload = "loadMyData(), loadYear()">
<div id = "main-content">
<h1>Movie Database</h1>
<select id="genre" class="filterButton">
</select>
<select id="releaseDate" class="filterButton">
</select>
<input type="text" value="Enter Release Date YYYY-MM-DD">
<button id="search">SEARCH</button>
</div>
<div id = "content"></div>
<script src = "myScript4.js"></script>
</body>
</html>
Here is my JS file:
/* THIS IS THE JS FILE FOR THE www.themoviedb.org WEBSITE API */
// MY GLOBAL VARIABLES
var title;
var genre;
var releaseYear;
var summary;
var actors;
var languages; // What languges is the movie in?
var status; // Is this movie releases or still in production?
/* ======================= HERE ARE MY EVENT LISTENERS ==================*/
var myList = document.getElementById("getList");
var myYear = document.getElementById("getRelease");
var getGenre = document.getElementById("genre");
var getYear = document.getElementById("releaseDate");
/* ======================= End of my Event Listeners =================== */
/* =========This is the function to display the data in the HTML ======= */
function displayData(results, title, poster_path, overview)
{
var div = document.createElement('div');
div.setAttribute('results', Results);
div.innerHTML = Title + '<br />' + Poster + Overview;
document.body.appendChild(div);
}
/* ============================ End function ========================= */
/* ============This is how the data from the genre is loaded ========== */
function loadMyData() {
var data = "{}";
var xhr = new XMLHttpRequest();
xhr.withCredentials = false;
console.log(xhr);
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
//console.log(this.responseText);
var sourceData = JSON.parse(xhr.responseText);
console.log(sourceData);
displayData(results, title, poster_path, overview);
var source = document.getElementById("genre");
for (var i = 0; i < sourceData.genres.length; i++) {
console.log(i);
optionID = sourceData.genres[i].id;
var optionName = sourceData.genres[i].name;
var option = document.createElement("option");
option.innerHTML = optionName;
option.setAttribute("value", optionID);
option.setAttribute("name", optionName);
source.appendChild(option);
//displayData(results, title, poster_path, overview);
//console.log(optionName);
}
}
});
xhr.open("GET", "https://api.themoviedb.org/3/genre/movie/list?language=en-US&api_key=**************");
xhr.send(data);
}
// loads the year from the Discover part of the API
function loadYear() {
var data = "{}";
var newxhr = new XMLHttpRequest();
newxhr.withCredentials = false;
console.log(newxhr);
newxhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
var sourceData = JSON.parse(newxhr.responseText);
//console.log(sourceData);
var source = document.getElementById("releaseDate");
for (var i = 0; i < sourceData.results.length; i++) {
console.log(i);
optionID = sourceData.results[i].id;
var optionName = sourceData.results[i].release_date;
var option = document.createElement("option");
option.innerHTML = optionName;
option.setAttribute("value", optionID);
option.setAttribute("name", optionName);
source.appendChild(option);
console.log(optionName);
}
}
});
newxhr.open("GET", "https://api.themoviedb.org/3/discover/movie?page=1&include_video=false&include_adult=false&sort_by=popularity.desc&language=en-US&api_key=*****************");
newxhr.send(data);
}
/* --------------------------------------------- On click show the data ------------------------------------------------ */
document.getElementById("search").addEventListener("click", displayData);
LoadMyData() loads the data for the genre. I suppose I should rename it. LoadYear() of course loads the date of the movie.
DisplayData() is supposed to display the data from the JSON file once the user clicks the button.
Can someone please give me an idea as to how to use plain javascript and html to show the JSON data? Right now I get an error telling me this:
myScript4.js:55 Uncaught ReferenceError: results is not defined
at XMLHttpRequest. (myScript4.js:55)
Line 55 is here: displayData(results, title, poster_path, overview);
Any help would be appreciated :) I've also gotten rid of the API Key for security reasons. I know you're not supposed to give them away.
Here is a snippet of the outputted JSON file for the loadYear() function:
{
"page": 1,
"total_results": 328130,
"total_pages": 16407,
"results": [
{
"vote_count": 2039,
"id": 346364,
"video": false,
"vote_average": 7.4,
"title": "It",
"popularity": 745.88068,
"poster_path": "/9E2y5Q7WlCVNEhP5GiVTjhEhx1o.jpg",
"original_language": "en",
"original_title": "It",
"genre_ids": [
12,
18,
27
],
"backdrop_path": "/tcheoA2nPATCm2vvXw2hVQoaEFD.jpg",
"adult": false,
"overview": "In a small town in Maine, seven children known as The Losers Club come face to face with life problems, bullies and a monster that takes the shape of a clown called Pennywise.",
"release_date": "2017-09-05"
},
As you can see "results" is in the JSON file. This is the bit that was undefined in the JavaScript file. How do I define it?
At this part of the code:
var sourceData = JSON.parse(xhr.responseText);
console.log(sourceData);
displayData(results, title, poster_path, overview);
'results' is not yet defined. I don't know where or what you expect 'results' to be, but I'm going to make a guess that it's just an object inside the json of responseText, so you should add this line before your displayData call:
var results = sourceData.results; If results is not a property of sourceData then obviously make var results equal to whatever, in the response, you need it to be.
Javascript is case a sensitive language
so your displayData function seems to have some incorrect variables, should be like this:
function displayData(results, title, poster_path, overview)
{
var div = document.createElement('div');
div.setAttribute('results', results);
div.innerHTML = title + '<br />' + poster_path + overview;
document.body.appendChild(div);
}
I'm trying to display particular json data in a form of Bullets. Each chapter data into <li>, each title into <p> and make those titles as a link. Finally, consider to the index of clicked title display related content in a second <div>. I have already some piece of code below (not working yet).
Html:
<div id="page1">
<ul id="courses"></ul>
</div>
<div id="page2">
<p id="content"></p>
</div>
JS code:
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},
{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},
{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},
{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},
{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var $clist = $('#courses');
for(var i in myData) {
$('<li><h3>' +this.[i].chapter+ '</h3><p>' +this.title+ '</p></li>').appendTo($clist);
}
function dContent() {
var $ccontent = $('#content');
$(this.[i].content).appendTo($ccontent);
}
});
Expected result:
- General
News forum // onclick display 'Text1' in <p id="content">
- CHAPTER 1
1.1 Introduction // onclick display 'Text2' in <p id="content">
1.2 Main Idea // onclick display 'Text3' in <p id="content">
- CHAPTER 2
2.1 Architecture // onclick display 'Text4' in <p id="content">
- CHAPTER 3
3.1 Liter.overview // onclick display 'Text5' in <p id="content">
Any help would be appreciated.
UPDATE: Here is the JSFIDDLE project.
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
var myData = JSON.parse(jsonString);
var dContent = function(event) {
$ccontent.html($(this).data('content'));
}
var $clist = $('#courses');
var $ccontent = $("#content");
var html = '';
var chapterList = [];
$clist.on('click', 'li', dContent);
$.each(myData, function(index, item) {
if ($.inArray(item.chapter, chapterList) === -1) {
chapterList.push(item.chapter);
html += '<li data-content="'+ item.content +'"><h3>' + item.chapter + '</h3><p>' + item.title + '</p></li>';
}
else {
html += '<li data-content="'+ item.content +'"><p>' + item.title + '</p></li>'
}
});
$clist.html(html);
I've written a script to do this, including putting items from the same chapter together. You can see a demo fiddle here.
I used native JavaScript for most of it, with the exception of jQuery for the $(a).on('click', .. and $(document).ready to ensure compatibility. Why is it so long? Because I built the <ul> with DOM methods, instead of a html string. This made it easy to cache and append elements. Finally, the content is added via a generator function. The way I did it means the page will use slightly more memory but you can have any string that is valid in JavaScript displayed in the content section. You may want to style it with whitespace: pre-wrap; to display new lines as expected.
Anyway, here is the code
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},\
{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},\
{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},\
{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},\
{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
// the \ at line ends is to escape the new line in the string literal
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var courses_ul = document.getElementById('courses'), // cache elements
content_elm = document.getElementById('content'),
i, li, h3, p, a, // vars for loop
chapters = {}, chap; // cache chapters
for (i = 0; i < myData.length; ++i) {
chap = myData[i].chapter; // shorthand since we'll use it a few times
// make <p>, <a>
p = document.createElement('p');
a = document.createElement('a'); // could append <a> to <p> here if you want
a.setAttribute('href', '#page2');
a.appendChild(document.createTextNode(myData[i].title));
// set up click
$(a).on('click', (function (content) { // generator - will give scope to
return function () { // this returned event listener.
content_elm.innerHTML = '';
content_elm.appendChild(document.createTextNode(content));
};
}(myData[i].content))); // chose `content` not `i` so no reliance on `myData`
// now check cache if chapter exists -
if (chap in chapters) { // retreive <li> for chapter from cache
li = chapters[chap]; // from cache
// append <p>, <a>
li.appendChild(p).appendChild(a);
} else { // if not in cache
li = document.createElement('li'); // make a new <li>
chapters[chap] = li; // and cache
// make & append <h3>
h3 = document.createElement('h3');
h3.appendChild(document.createTextNode(chap));
li.appendChild(h3);
// append <p>, <a> and to <ul>
courses_ul.appendChild(li).appendChild(p).appendChild(a);
}
}
});
You have an invalid JSON structure. The correct structure is below:
[
{
"chapter": "General",
"title": "News forum",
"content": "Text1"
},
{
"chapter": "CHAPTER 1",
"title": "1.1 Introduction",
"content": "Text2"
},
{
"chapter": "CHAPTER 1",
"title": "1.2 Main Idea",
"content": "Text3"
},
{
"chapter": "CHAPTER 2",
"title": "2.1 Architecture",
"content": "Text4"
},
{
"chapter": "CHAPTER 3",
"title": "3.1 Liter.overview",
"content": "Text5"
}
]
Note that comma here 3.1 Liter.overview","content":"Text5"}, in your JSON structure, it fails here
UPDATED ANSWER WITH CODE
var jsonString = '[{"chapter": "General","title": "News forum","content": "Text1"},{"chapter": "CHAPTER 1","title": "1.1 Introduction","content": "Text2"},{"chapter": "CHAPTER 1","title": "1.2 Main Idea", "content": "Text3"},{"chapter": "CHAPTER 2","title": "2.1 Architecture","content": "Text4"},{"chapter": "CHAPTER 3","title": "3.1 Liter.overview","content": "Text5"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
function dContent() {
$("#content").css("border","2px solid red").css("height","100px");
$("#content").html($(this).data('value'));
}
$("#courses").on('click','li', dContent)
$.each(myData, function(index,item) {
$("#courses").append("<li class='li' data-value="+item.content+">"+item.chapter+" <p>"+item.title+"</p></li>");
})
});
DEMO ON JSFIDDLE
this.[i].chapter should probably be myData[i].chapter. As it is, it's a syntax error.
Then you should rethink whether your other uses of this are correct.
Copying this into your JSFiddle and checking in jQuery as well, will make it work.
var jsonString = '[{"chapter":"General","title":"News forum","content":"Text1"},{"chapter":"CHAPTER 1","title":"1.1 Introduction","content":"Text2"},{"chapter":"CHAPTER 1","title":"1.2 Main Idea","content":"Text3"},{"chapter":"CHAPTER 2","title":"2.1 Architecture","content":"Text4"},{"chapter":"CHAPTER 3","title":"3.1 Liter.overview","content":"Text5"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var $clist = $('#courses');
$.each(myData, function(i,o){
$('<li><h3>' +o.chapter+ '</h3><p>' +
'<a href="#page2" onclick="dContent(\''+o.content+'\')">' +
o.title + '</a></p></li>').appendTo($clist);
});
window.dContent = function(content) {
var $ccontent = $('#content');
$ccontent.append(content);
}
});