How can I create a specific JSON object from some HTML?
Example
This is very well formatted HTML page (rendered from markdown). I want to create a JSON representation of the sections on the page.
So each "h2" is a title. Each h3, h4, or h5, that follows it is a subtitle
Given this HTML:
<h2>Charts</h2>
<ul>...</ul>
<h5>Third Party</h5>
<ul>...</ul>
<h5>Reusable Chart Frameworks</h5>
<ul>...</ul>
<h2>Maps</h2>
<h5><a href="#third-party-1">Third Party</h5>
...
Return this JSON:
[
{
"title": {
"text": "Charts",
"href": "#charts"
}
"subtitles": [
{
"text": "Third Party",
"href": "#third-party"
},
{
"text": "Reusable Chart Frameworks",
"href": "#reusable-chart-frameworks"
}
]
},
{
"title": {
"text": "Maps",
"href": "#maps"
},
"subtitles": ]
"text": "Third Party",
"href": "#third-party-1"
]
},
...
]
Solutions I've considered
Seems like something jQuery could help a lot with. If the items were nested it would be very easy to do $('h2').each(...) and just loop through each section, appending it to my JSON object. However there is no nesting here, just siblings. Any ideas?
One other solution is to map it:
var mappedJSON = $('h2').map(function() {
var $selfA = $(this).children('a');
var subtiles = $(this).nextUntil('h2').filter(':header').children('a').map(function() {
return {
"text": $(this).text(),
"href": $(this).attr('href')
}
}).get();
return {
"title": {
"text": $selfA.text(),
"href": $selfA.attr('href')
},
"subtitles": subtiles
};
}).get();
console.log(mappedJSON);
$('<pre/>').appendTo($('body').empty()).text(JSON.stringify(mappedJSON, null, "\t"));
pre {
tab-size: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h2>Charts</h2>
<ul>...</ul>
<h5>Third Party</h5>
<ul>...</ul>
<h5>Reusable Chart Frameworks</h5>
<ul>...</ul>
<h2>Maps</h2>
<h5><a href="#third-party-1">Third Party</h5>
Here's a solution that just relies on jQuery's .nextUntil() function.
var sections = [];
var eTitles = $('article').find('h2');
$(eTitles).each(function(){
var section = {
"title": {
"text": $(this).text(),
"href": $(this).find('a').attr('href')
},
"subtitles": []
}
var eSubtitles = $(this).nextUntil('h2').filter('h3, h4, h5');
$(eSubtitles).each(function(){
var subtitle = {
"text": $(this).text(),
"href": $(this).find('a').attr('href')
}
section.subtitles.push(subtitle);
});
sections.push(section);
});
Related
I´ve got an array in this format:
var items = [{
"link": {
"0": "http://www.example.com/"
},
"title": {
"0": "example"
}
}, {
"link": {
"0": "http://www.example2.com"
},
"title": {
"0": "example2"
}
}]
I can´t figure out how to loop through it and display its values in HTML.
Im using jquery and have tried using an each-loop:
$.each( items, function(i, item) {
console.log(item); // Uncaught TypeError: Cannot use 'in' operator to search for '6271' in
})
Help appreciated. Thanks!
EDIT:
Your code works in the example i posted above. I will accept asasp.
I noticed however that the real json im trying to loop is not always properly formatted which leads to a crash:
var items = [{
"link": {
"0": "http://www.example.com/"
},
"title": {
"0": "example"
}
}, {
"link": {
"0": "http://www.example2.com"
},
"title": {
"0": "example2: "
some text here ""
}
}]
When looping this array i get:
Uncaught SyntaxError: Unexpected identifier
Is there a way to maybe skip all "broken" objects?
Here you go with a solution
var items = [{
"link": {
"0": "http://www.example.com/"
},
"title": {
"0": "example"
}
}, {
"link": {
"0": "http://www.example2.com"
},
"title": {
"0": "example2"
}
}];
$.each( items, function(i, item) {
$("body").append(`<span class="title">${item.title["0"]}:</span> <span>${item.link["0"]}</span><br/>`);
});
.title {
font-weight: bold;
font-size: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Each item is an object, to get the link value I've provided in the solution.
Fast and dirty:
for (item of items) {
console.log(item.link[0])
console.log(item.title[0])
}
I want to create HTML elements dynamically using JSON file.
{"myObject": {
"JAVA": {
"id": "JAVAsubj",
"path": "json/data.json"
},
"C#": {
"id": "JAVAsubj",
"path": "json/data1.json"
},
"C++": {
"id": "JAVAsubj",
"path": "json/data2.json"
}
}
}
This is my JSON file. i want to create HTML buttons dynamically. Buttons should be create like JAVA,C#,C++. if i add something next to C++ then that button should get created dynamically
You can try something like this FIDDLE
however, i changed the myObject to an array of json objects as follows:
var jsonObj = {"myObject":
[
{
title: 'JAVA',
id: "JAVAsubj",
path: "json/data.json"
},
{
title: "C#",
id: "JAVAsubj",
path: "json/data1.json"
},
{
title: "C++",
id: "JAVAsubj",
path: "json/data2.json"
}
]
}
var count = Object.keys(jsonObj.myObject).length;
var container= document.getElementById('buttons'); // reference to containing elm
for(var i=0;i<count;i++){
var obj= jsonObj.myObject[i];
var button = "<input type='button' value="+obj.title+"></input>"
container.innerHTML+=button;
}
First thing you need to do that get your JSON into js object :
var myJSON= {"myObject": {
"JAVA": {
"id": "JAVAsubj",
"path": "json/data.json"
},
"C#": {
"id": "JAVAsubj",
"path": "json/data1.json"
},
"C++": {
"id": "JAVAsubj",
"path": "json/data2.json"
}
}
}
now get the value of your object into dictionary like below :
var dctLanguages = myJSON["myObject"];
now to render buttons dynamically, just do this :
var strHTML = '';
for (var key in dctLanguages)
{
var language = dctLanguages[key];
strHTML += '<input type="button" id="'+language.id+'" value="'+key+'"/>';
}
and append this HTML into your container div as follows :
$(strHTML).appendTo("#container");
Hope this will work for you..
const info = [
{
"id": 1,
"img": "a.jpg",
"name": "Avinash Mehta",
"desc": "I am Web Developer"
},
{
"id": 2,
"img": "c.jpg",
"name": "Avinash",
"desc": "I am Web"
},
{
"id": 3,
"img": "b.jpg",
"name": "Mehta",
"desc": "I am Developer"
},
]
const main = document.querySelector(".main");
window.addEventListener("DOMContentLoaded", function(){
let displayInfo = info.map(function(profile){
return` <div class="profile">
<img src="${profile.img}" alt="">
<h2>${profile.name}</h2>
<p>${profile.desc}</p>
</div>`
});
displayInfo = displayInfo.join("");
main.innerHTML = displayInfo
})
This shoule help you
const info = [
{
"id": 1,
"img": "a.jpg",
"name": "Avinash Mehta",
"desc": "I am Web Developer"
},
{
"id": 2,
"img": "c.jpg",
"name": "Avinash",
"desc": "I am Web"
},
{
"id": 3,
"img": "b.jpg",
"name": "Mehta",
"desc": "I am Developer"
},
]
const main = document.querySelector(".main");
window.addEventListener("DOMContentLoaded", function(){
let displayInfo = info.map(function(profile){
return` <div class="profile">
<img src="${profile.img}" alt="">
<h2>${profile.name}</h2>
<p>${profile.desc}</p>
</div>`
});
displayInfo = displayInfo.join("");
main.innerHTML = displayInfo
})
See this link: http://jsfiddle.net/Rousnay/FJzre/ it is working, the JSON data come trough http://json.virtuecenter.com/json-data/blogs/tags?callback=?
but it is not working when i want to get data from http://sunday-theater-club.simpletix.eu/API/ThemeUIHandler.asmx/GetMenuItems?callback=?
Can anyone help me with jsfiddle example. please.
The returned data is not valid to the template, when getting from "http://sunday-theater-club.simpletix.eu/API/ThemeUIHandler.asmx/GetMenuItems?callback=?" you end up with:
[
{
"text": "Home ",
"url": "/Default.aspx"
},
{
"text": "Events ",
"url": "/Event-List/"
},
{
"text": "Test",
"url": "/Pages/8276/Test/"
}
]
and when getting from "http://json.virtuecenter.com/json-data/blogs/tags?callback=?" you have:
{
"blogsTags": [
{
"tag":"GovernorBentley",
"count":1,
"separation_path":"\/blogs\/byTag\/GovernorBentley.html"
},
{
"tag":"Huntsville",
"count":1,
"separation_path":"\/blogs\/byTag\/Huntsville.html"
},
{
"tag":"Voting Responsibility",
"count":1,
"separation_path":"\/blogs\/byTag\/Voting Responsibility.html"
},
{
"tag":"Voting Rights",
"count":1,
"separation_path":"\/blogs\/byTag\/Voting Rights.html"
}
],
"pagination": {
"limit":20,
"total":4,
"page":1,
"pageCount":1
}
}
your template expects a "blogsTags" property.
I have JSON data like this
{
"nodes": [
{
"node": {
"title": "Kieu Oanh",
"Image": "",
"view_node": "view",
"link": "drupal_dev/content/kieu-oanh"
}
},
{
"node": {
"title": "Kieu Oanh",
"Image": "",
"view_node": "view",
"link": "drupal_dev/content/kieu-oanh"
}
},
]
}
Now I want to convert it to
var rel_data = [{
"title": "asa",
"Image": "sasa",
"view_node": "sajsjla"
}, {
"title": "asa",
"Image": "sasa",
"view_node": "sajsjla"
}]
And This is my code to convert data to rel_data
data = data.nodes;
for (d in data) {
rel_data[d].title = data[d].node.title;
rel_data[d].image = data[d].node.Image;
}
for (d in rel_data) {
alert(rel_data[d].title);
}
But it does not seem to work, is there anything wrong in my code?
You're trying to edit objects which aren't there yet.
The first thing you do is access rel_data while there is no rel_data yet. The second thing you do is that you change properties of array elements which do not exist.
Your code should be the following to work:
data = data.nodes;
rel_data = new Array(); // Create rel_data
for(d in data) {
rel_data[d] = new Object(); // Create array element
rel_data[d].title= data[d].node.title;
rel_data[d].image= data[d].node.Image;
}
for(d in rel_data) {
alert(rel_data[d].title);
}
You could also use map instead of a for loop (for generating the new array, you'd want one for the alert())
var rel_Data = data.nodes.map(function(item) {
return {
"title": item.node.title,
"Image": item.node.Image,
"view_node": item.node.view_node
};
});
I am trying to work with Mustache.js that is really helping.
I am stuck on getting array with specific option and value.
My JSON is looking like that:
{
"departments": [
{
"department": [
{
"id": 114,
"deptName": "Department 1",
"category": [
{
"id": 127,
"catName": "Category Name",
"subCategory": []
},
{
"id": 115,
"catName": "Category Name",
"subCategory": []
}
]
}
]
},
{
"department": [
{
"id": 123,
"deptName": "Department 2",
"category": [
{
"id": 126,
"catName": "Category Name",
"subCategory": []
},
{
"id": 124,
"catName": "Category Name",
"subCategory": []
}
]
}
]
}
]
}
To get main department names it is easy as:
JS:
$.ajax({
url: 'link_to_json',
dataType: 'json',
success: function(data) {
var template = $('#pageHomeTpl').html();
var html = Mustache.to_html(template, data);
$('#category-list').html(html);
}
});
HTML:
<ul id="category-list">
<script id="pageHomeTpl" type="text/template">
{{#departments}}
{{#department}}
<li>{{deptName}}</li>
{{/department}}
{{/departments}}
</script>
</ul>
But now I need to somehow get categories ("category:") from department with specific ID, for example "id": 114.
Any help, please.
You can try in these lines, with jQuery map() and grep()
console.log(JSON.stringify(data));
var filtereddata = {"departments" : []};
var filtereddept= {};
filtereddept.department= $.map(data.departments, function(alldept,indx){
return $.grep(alldept.department, function(deptobj,indx){
return deptobj.id==114;
});
});
filtereddata.departments[0]=filtereddept;
console.log(JSON.stringify(filtereddata));
The template to iterate the category of departments:
<script id="pageHomeTpl" type="text/template">
{{#departments}}
{{#department}}
<li>{{deptName}}</li>
{{#category}}
<ul>
<li>{{catName}}</li>
</ul>
{{/category}}
{{/department}}
{{/departments}}
</script>
I don't test it but it seems to be work...
...
success: function(data) {
var template = $('#pageHomeTpl').html();
var item = data.departments
for(key in item){
if(key == 'id' && item[key] == 114 ){
var html = Mustache.to_html(template, item);
}
}
$('#category-list').html(html);
}
...
with FOR .. IN statement you can cycle in your object or array take look at this link
js_loop_for_in