I have dynamic divs on a page which would have anassigned class from a bunch of values. For example:
<div class='class1'><span class='spn1'>test</span></div>
<div class='class2'><span class='spn2'>test another</span></div>
<div class='class2'><span class='spn3'>test1</span></div>
<div class='class3'><span class='spn4'>test123</span></div>
<div class='class1'><span class='spn221'>test</span></div>
The class could have any random number appended to it.
Now in my javascript, I am trying to build a dynamic JSON object based on the class of the div and the structure I want is:
{
class1: {
spn1: 'test',
spn221: 'test'
},
class2: {
spn2: 'test another',
spn3: 'test123'
},
class3: {
spn4: 'test223'
}
}
I am able to achieve this in a flat array structure but I want it in the JSON format as I will execute an ajax call based in the classes of div in other function. The flat array I am getting is as(which I don't want)
[{class:class1,span:spn1,text:test},{class:class1,span:spn221,text:test},...]
Link to fiddle: https://jsfiddle.net/8v0uove3/
-
How to you get the "flat array" ? Seems like turning the array into the object would be easy enough (with, eg. _.reduce), is that impossible ?phtrivier– phtrivier2015年11月30日 13:53:29 +00:00Commented Nov 30, 2015 at 13:53
-
@phtrivier by _reduce, can I append objects as I want? Can you give a dummy example?Saksham– Saksham2015年11月30日 13:58:12 +00:00Commented Nov 30, 2015 at 13:58
-
1Can you create a FIDDLE for the problem ?Mayank– Mayank2015年11月30日 14:00:20 +00:00Commented Nov 30, 2015 at 14:00
-
@Mayank added fiddle linkSaksham– Saksham2015年11月30日 14:08:06 +00:00Commented Nov 30, 2015 at 14:08
-
nvm ... misunderstoodtobi– tobi2015年11月30日 14:13:41 +00:00Commented Nov 30, 2015 at 14:13
3 Answers 3
Here's a vanilla JS way of doing it:
// pick up the elements
var divs = document.querySelectorAll('div[class^="class"]');
// use reduce with an initial object
var obj = [].slice.call(divs).reduce(function (p, c) {
var child = c.firstChild;
var key = c.getAttribute('class');
// if the class key doesn't exist in the initial object add it
if (!p[key]) p[key] = {};
// add the new span properties to the object
p[key][child.getAttribute('class')] = child.textContent;
return p;
}, {});
Output
{
"class1": {
"spn1": "test",
"spn221": "test"
},
"class2": {
"spn2": "test another",
"spn3": "test1"
},
"class3": {
"spn4": "test123"
}
}
Here is the complete function
. This is a Pure JavaScript
solution. Please have a look at the code below.
Function
function convertHtmlToJson() { var output = {}, divRef = document.querySelectorAll('div[class^="class"]'), divElem = undefined; for (var i = 0; i < divRef.length; i++) { divElem = divRef[i].getAttribute('class'); // Check if key exists or not if (!output[divElem]) { // output[divElem] === undefined output[divElem] = {} } // Get child element childRef = divRef[i].firstElementChild || divRef.firstChild; var className = document.getElementsByClassName(childRef.getAttribute('class')); for (var j = 0; j < className.length; j++) { output[divElem][className[j].getAttribute('class')] = className[j].textContent; } } return output; }
Function call
// Final JSON var finalJson = convertHtmlToJson(); // Desired JSON output console.log(JSON.stringify(finalJson));
You can look at the Browser Console for the desired JSON
output.
Hope it helps!
I've managed to get a solution, is this your desired result? (Take a look at the console output)
var obj = {};
$('div').each(function() {
// Get children
var children = $(this).children();
// Get current class
var current = $(this).attr('class');
// Check if current class already exists in the class object
// If not create an empty object
if (typeof obj[current] === 'undefined') {
obj[current] = {};
}
// Iterate over div's children
$(children).each(function() {
// Get class value of child element
var childCls = $(this).attr('class');
// Set the value for child object
obj[current][childCls] = $(this).text();
})
});
console.log(obj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='class1'><span class='spn1'>test</span> <span class='spn3'>test</span>
</div>
<div class='class2'><span class='spn2'>test another</span>
</div>
<div class='class2'><span class='spn3'>test1</span>
</div>
<div class='class3'><span class='spn4'>test123</span>
</div>
<div class='class1'><span class='spn221'>test</span>
</div>