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);
}
});
Related
I wrote an custom API(node.js app) that gets the info about the blogs from medium.com, right now there is
the author/main pic of the article,
title,
link to the article on medium.com(redundant),
the entire article text, in the JSON output.
Sample API/JSON:
{
"img": [
"https://upload.wikimedia.org/wikipedia/commons/4/42/Blog_%281%29.jpg"
],
"title": [
"The old and the new or not so new: Java vs JavaScript"
],
"link": [
"https://medium.com/#aki9154/the-old-and-the-new-or-not-so-new-java-vs-javascript-760f84e87610?source=rss-887f1b1ddb75------2"
],
"desc": [
"<p>It’s funny how the name JavaScript makes you believe that it is somehow..."
]
}
Then i am polling this API/JSON and spitting out the output in a thumbnail format, basic html for now(no design/CSS).
Where i am stuck is when a user clicks on a thumbnail and i need to make sure that i display the correct article?!
For which i need to display a new page when the thumbnail/article is clicked, i can use #4 from JSON above as an output for that dynamically created new page and put it out nicely)
The issue that i am facing now is how to dynamically produce the correct article when the dynamically created link is clicked?
Right now nothing happens when i click on the thumbnail and that's what this project link displays...
I did some stackoverflow research and read some jQuery docs(event propagation and more...) and was able to make changes to the index.js, below is how it looks like but nothing works, any help will be appreciated...
index.js:
$(function () {
var desc = "";
function newWin() {
var w = window.open();
$(w.document.body).html('<p>'+desc+'</p>');
}
var $content = $('.cards-in-grid');
var url = 'link-for private use now';
$.get(url, function (response) {
var output = '';
console.log(response);
$.each(response, function (k, item) {
title = item.title;
var author = item.img;
desc = item.desc;
output += '<li><img src="'+author+'" alt=""><h2>' + title + '</h2></li>';
$(".cards-in-grid ul").on("click", "li", function(){
newWin;
});
return k;
});
$content.html(output);
});
});
`
$(function () {
var $content = $('.cards-in-grid');
var url = 'link-for private use now';
$.get(url, function (response) {
var output = '';
var list = "li";
$.each(response, function (k, item) {
var listNum = list+k;
var idy = "#"+listNum;
var desc = "";
title = item.title;
var author = item.img;
desc = item.desc;
//GIVE ID to each LI using a variable
output += '<li id="'+listNum+'"><img src="'+author+'" alt=""><h2>' +
title + '</h2></li>';
$content.html(output);
$content.on("click",idy, function(){
var w = window.open();
$(w.document.body).html('<p>'+desc+'</p>');
});
return k;
});
});
});
This worked perfectly, some thinking and pondering and was able to make it work!!
Kindly Upvote the answer, if it helped you! Thanks!
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 switch between the array options when clicking a button by changing the value of a variable. I cannot get it to work. Perhaps this isn't the best way to do it? I'm still learning this and I'm struggling to spot the issue.
Thanks in advance for your help
var json = {
"content": [{
"title": "Test 1",
},
{
"title": "Test 2",
}
]
};
var output = ""; //initialize it outside the loop
var maxAppend = 0;
var foo = json.content[0];
function first() {
foo = json.content[0];
}
function second() {
foo = json.content[1];
}
$.each(json.content[0], function() {
if (maxAppend >= 1) return;
output += '<h2>' + foo.title + '</h2>' +
'<div><button onclick="second()">click</button></div>'
maxAppend++;
});
$('.container').append(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container"></div>
jsFiddle Link
The way you have written your code that will work just for once and click event does not update the text as it has been put in the DOM. Because you have a variable foo and it has the reference to the object.
Yet you need to talk to the DOM to update it's text content. One way i have mentioned. Although you might want to go unobtrusive.
You have to pass this to the function:
onclick="second(this)"
Now in the function:
function second(el){
$(el).parent().prev('h2').text(json.content[1]['title']);
}
You might add a event listener for your dynamic button in jquery with delegated event:
$(document.body).on('click', 'button' second);
function second(){
$(this).parent().prev('h2').text(json.content[1]['title']);
}
var json = {
"content": [{"title": "Test 1",},{"title": "Test 2",}]
};
var output = ""; //initialize it outside the loop
var maxAppend = 0;
var foo = json.content[0];
function first() {
foo = json.content[0];
}
function second(el) {
$(el).parent().prev('h2').text(json.content[1]['title']);
}
$.each(json.content, function() {
output += '<h2>' + foo.title + '</h2>' +
'<div><button onclick="second(this)">click</button></div>'
maxAppend++;
});
$('.container').append(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container"></div>
I am not really sure about what you want to do.
here is an example i make for handle switch value
click here to watch
var Json = {
"content": [{
"title": "Test 1",
},
{
"title": "Test 2",
}]
};
var select = 0;
var text = $("#text");
var handleSwitch = function(){
if (select === 0){
$(text).html(Json.content[1].title);
select = 1;
}else if(select === 1){
$(text).html(Json.content[0].title);
select = 0;
}
}
$('#button').on("click", function(event){
handleSwitch();
});
<div class="container">
<button id="button">click</button>
<p id="text">Test 1</p>
</div>
I have two json files that I load into a page. One contains the name and value of the tag. The other json file contains the html. I've been stumped for a day googling and trying to replace these tags.
For example:
var tags = {
title: "New Title",
author: "John Doe"
};
var html = {
header: "<div id=\"header\"><h1>{{title}}</h1</div>",
content: "<div id=\"content\"><h2>{{author}}</h2></div>"
};
I lifted this somewhere and I can replace my tags if the html is stored in a string, but I'm having problems getting this to work when the html is in an object.
var str = 'The Title is {{title}} and the author is {{author}}. Proof it will replace multiple tags: Again the author is {{author}}.';
var content = str.replace(/\{\{(.*?)\}\}/g, function(i, match) {
return tags[match];
});
I need help iterating through all the values in the html object and replacing them with the correct tag values. Thanks
You can iterate over each property in html object and replace its content
var tags = {
title: "New Title",
author: "John Doe"
};
var html = {
header: "<div id=\"header\"><h1>{{title}}</h1</div>",
content: "<div id=\"content\"><h2>{{author}}</h2></div>"
};
for (var key in html) {
if (html.hasOwnProperty(key)) {
html[key] = html[key].replace(/\{\{(.*?)\}\}/g, function(i, match) {
return tags[match];
});
}
}
content.innerText = JSON.stringify(html, null, 2)
<pre id="content"></pre>
Can some one help me make the following JSON data:
{
"main": {
"label":"Main",
"url":"#main"
},
"project": {
"label":"Project",
"url":"#project"
},
"settings": {
"label":"Settings",
"url":"#settings",
"subnav":[
{
"label":"Privacy",
"url":"#privacy"
},
{
"label":"Security",
"url":"#security"
},
{
"label":"Advanced",
"url":"#advanced"
}
]
}
}
into the following bullets list using JS? Assuming you don't know what the first nodes are call labeled (e.g. "main", "project" <- these will be dynamically generated):
Main (#main)
Project (#project)
Settings (#settings)
Privacy (#privacy)
Security (#security)
Advanced (#advanced)
Thanks
Let's not use HTML string-hacking, shall we? That would break as soon as any of the data had characters like < or & in (or " in attribute values). Use DOM methods and you don't have to worry about character escaping:
function createNav(navs) {
var ul= document.createElement('ul');
for (name in navs) {
var nav= navs[name];
var a= document.createElement('a');
a.href= nav.url;
a.appendChild(document.createTextNode(nav.label));
var li= document.createElement('li');
li.id= 'nav-'+name;
li.appendChild(a)
if ('subnav' in nav)
li.appendChild(createNav(nav.subnav));
ul.appendChild(li);
}
return ul;
}
document.getElementById('navcontainer').appendChild(createNav(jsondata));
Most JS frameworks offer shortcuts to make this a bit less wordy. For example with jQuery:
function createNav(navs) {
var ul= $('<ul>');
for (name in navs) {
var nav= navs[name];
var li= $('<li>', {id: name});
li.append($('<a>', {href: nav.url, text: nav.label}));
if ('subnav' in nav)
li.append(createNav(nav.subnav));
ul.append(li);
}
}
$('#navcontainer').append(createNav(jsondata));
Note that either way, you're using an Object literal which means you get no control over the order the list of navs comes out. You have no guarantee that main will be above project. If you want a defined order, you will have to have the returned JSON data be an array.
My code is on JSfiddle.
As JSON parser I used this one.
The main code is a recursive renderer of the parsed JSON:
function recursive_parse(result) {
var html = '<ul>';
for (var k in result) {
html = html + '<li>' + result[k].label + ' (' + result[k].url + ')';
html = html + recursive_parse(result[k].subnav);
html = html + '</li>';
}
html = html + '</ul>';
return html;
}
var result = json_parse($("div#test1111").html());
var html = recursive_parse(result);
$("div#test2222").html(html);