0

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/

asked Nov 30, 2015 at 13:49
8
  • 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 ? Commented Nov 30, 2015 at 13:53
  • @phtrivier by _reduce, can I append objects as I want? Can you give a dummy example? Commented Nov 30, 2015 at 13:58
  • 1
    Can you create a FIDDLE for the problem ? Commented Nov 30, 2015 at 14:00
  • @Mayank added fiddle link Commented Nov 30, 2015 at 14:08
  • nvm ... misunderstood Commented Nov 30, 2015 at 14:13

3 Answers 3

1

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"
 }
}

DEMO

answered Nov 30, 2015 at 14:28
1

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!

answered Nov 30, 2015 at 14:30
0

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>

answered Nov 30, 2015 at 14:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.