2

I got the following HTML:

<div class="slot_subclass">
   <div class="form-group">      
        <input type="text" class="form-control slot" name="slot_name">      
   </div>
   <div class="form-group"> 
        <input type="text" class="form-control slot" name="slot_type">
   </div> 
</div> 
<div class="slot_subclass">
   <div class="form-group">      
        <input type="text" class="form-control slot" name="slot_name">      
   </div>
   <div class="form-group"> 
        <input type="text" class="form-control slot" name="slot_type">
   </div> 
</div>
<div class="slot_subclass">
   <div class="form-group">      
        <input type="text" class="form-control slot" name="slot_name">      
   </div>
   <div class="form-group"> 
        <input type="text" class="form-control slot" name="slot_type">
   </div> 
</div>  

The amount of slot_subclass may be unlimited.

I need to parse all these inputs and make an object where the key is the value of first input of slot_subclass (slot_name) and value is the value of the second (slot_type).

I tried the following:

$(".slot").map(function(){
    return $(this).val();
}).get();

but I just get a plain array of values. I may use jQuery for this task. Thank you.

UPD_1 In order to handle for the same keys I chose the following code (if someone interested):

jsonObj = [];
$(".slot_subclass").each(function() { 
    var slot_name = $(this).find("input[name=slot_name]").val();
    var slot_type = $(this).find("input[name=slot_type]").val();
    item = {};
    item[slot_name] =  slot_type;
    jsonObj.push(item);
});
console.log(jsonObj);

Thank you everyone for help.

4
  • Firstly note that there's no such thing as a 'JSON object'. JSON is a notation for serialising data to a string. It's never an object. With regard to your code, map() returns an array. In your example this array will contain values only, not key:value pairs. The issue you have is that you have multiple fields with the same name, which would not be valid in a single object. Commented Aug 9, 2017 at 16:16
  • I need to be the name is tha value of the first input in slot_subclass and value is the value of second input. Ideally no class names or html name attributes would be present Commented Aug 9, 2017 at 16:19
  • I added an answer for you. I had to modify the array format you use, but it's the only way it can work given the duplicate input names Commented Aug 9, 2017 at 16:22
  • @Jack I've modified the misleading wording of your question. As the others have noted, there are no "JSON objects". Avoid using this term, it makes you think about JS and JSON in the wrong way. Commented Aug 9, 2017 at 16:29

6 Answers 6

2

Like this code:

100% working and tested

jsonObj = [];
$(".slot_subclass").each(function() { 
    var slot_name = $(this).("input[name=slot_name]").val();
    var slot_type = $(this).("input[name=slot_type]").val();
    item = {};
    item["slot_name"] = slot_name;
    item["slot_type"] = slot_type;
    jsonObj.push(item);
});
console.log(jsonObj);

Example:

jsonObj = [];
$(".slot_subclass").each(function() {
	var slot_name = $(this).find("input[name=slot_name]").val();
	var slot_type = $(this).find("input[name=slot_type]").val();
	item = {};
	item["slot_name"] = slot_name;
	item["slot_type"] = slot_type;
	jsonObj.push(item);
});
console.log(jsonObj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
   <div class="form-group">      
	<input type="text" class="form-control slot" name="slot_name" value="1">      
   </div>
   <div class="form-group"> 
	<input type="text" class="form-control slot" name="slot_type" value="11">      
   </div> 
</div> 
<div class="slot_subclass">
   <div class="form-group">      
	<input type="text" class="form-control slot" name="slot_name" value="2">        
   </div>
   <div class="form-group"> 
	<input type="text" class="form-control slot" name="slot_type" value="22">    
   </div> 
</div>
<div class="slot_subclass">
   <div class="form-group">      
	<input type="text" class="form-control slot" name="slot_name" value="3">       
   </div>
   <div class="form-group"> 
	<input type="text" class="form-control slot" name="slot_type" value="33">    
   </div> 
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

While this works it's rather brittle. If you change the HTML you will have to update the JS which is less than ideal.
Your code returns an array of objects instead of one object.
1

Firstly note that there's no such thing as a 'JSON object'. JSON is a notation for serialising data to a string. It's never an object.

With regard to your code, map() returns an array. In your example this array will contain values only. Instead you need to change that to return an object that holds the values of the input elements within each .slot_subclass group.

Once you've done that to build the array, you can use JSON.stringify to build your JSON string, something like this:

var arr = $('.slot_subclass').map(function() {
  var obj = {};
  $(this).find('.slot').each(function() {
    obj[this.name] = this.value;
  });
  return obj;
}).get();

console.log(arr);

var json = JSON.stringify(arr);
console.log(json);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_name">
  </div>
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_type">
  </div>
</div>
<div class="slot_subclass">
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_name">
  </div>
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_type">
  </div>
</div>
<div class="slot_subclass">
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_name">
  </div>
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_type">
  </div>
</div>

2 Comments

Your code returns an array of objects with improper keys.
Can you please explain what you mean by 'improper keys'
1

You should use each(), not map()

$('.test').on('click', function() {
	var obj = {}
  
  $(".slot_subclass").each(function() {
    var $slots = $(this).find('.slot');

   	obj[$slots.eq(0).val()] = $slots.eq(1).val()
  })
  
  console.log(obj)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
   <div class="form-group">      
        <input type="text" class="form-control slot" name="slot_name">      
   </div>
   <div class="form-group"> 
        <input type="text" class="form-control slot" name="slot_type">
   </div> 
</div> 
<div class="slot_subclass">
   <div class="form-group">      
        <input type="text" class="form-control slot" name="slot_name">      
   </div>
   <div class="form-group"> 
        <input type="text" class="form-control slot" name="slot_type">
   </div> 
</div>
<div class="slot_subclass">
   <div class="form-group">      
        <input type="text" class="form-control slot" name="slot_name">      
   </div>
   <div class="form-group"> 
        <input type="text" class="form-control slot" name="slot_type">
   </div> 
</div>

<button class="test">Test</button>

1 Comment

How do you handle a situation with the same keys? Is it possible to make an array of objects with each key:value pair in a seprate object?
1

Following is based on :

where key is the value of first input

// set values for demo
setDemoValues()
// get data based on above values
var res = {};
$('.slot_subclass').each(function() {
  var $inputs = $(this).find('.slot');      
  res[$inputs[0].value] = $inputs[1].value;      
})

console.log(res)

function setDemoValues() {
  $('.slot_subclass').each(function(i) {
    $(this).find('.slot').val(function() {
      return this.name + (i + 1);
    })
  });

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slot_subclass">
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_name">
  </div>
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_type">
  </div>
</div>
<div class="slot_subclass">
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_name">
  </div>
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_type">
  </div>
</div>
<div class="slot_subclass">
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_name">
  </div>
  <div class="form-group">
    <input type="text" class="form-control slot" name="slot_type">
  </div>
</div>

3 Comments

Your code also returns an array of objects instead of one object.
it is necessary to handle the situation with the same keys. I suppose the previous variant was correct
no idea what that means or what expected results are
0

You're on a right way but you need to change you algorithm. Let's see $(".slot_subclass") is array of div elements - iterate that array, and got both 'key' and 'value' values :). For each element of $(".slot_subclass") you can get access to first and second nested inputs by something like $(el).find('.slot') and first element of that array is a first input, second is a second input.

Comments

0

So, what you can do is query all of the inputs, set their name as the key and their value as their input.

The problem you can run into, if you just do it as you have it now, is that your values will be overridden since you have multiple inputs with the same name.

You can get around that by adding a unique ID or class to their parent container.

var inputs = document.querySelectorAll("input");
var data = {};
for (var i = 0; i < inputs.length; i++) {
    data[inputs[i].name] = inputs[i].value;
}

console.log(data);

For getting a specific set of inputs, using the unique identifier I mentioned above, all you have to do is change the query selector.

var inputs = document.querySelectorAll("#container input");

EDIT

Having an unknown amount of subclasses you can put them into an array. Following the same JS above, it's just one extra step.

var subclasses = document.querySelectorAll(".slot_subclass");
var data = [];
for (var i = 0; i < subclasses.length; i++) {
    if (!data[i]) data[i] = {};
    var inputs = subclasses[i].querySelectorAll("input");
    for (var o = 0; o < inputs.length; o++) {
        data[i][inputs[o].name] = inputs[o].value;
    }
}

console.log(data);
// outputs like: 
[
    0: {slot_name: "", slot_type: ""}
    1: {slot_name: "", slot_type: ""}
    2: {slot_name: "", slot_type: ""}
]

2 Comments

The issue would be that there are multiple elements with the same name so the resulting object would only have two properties
@RoryMcCrossan I missed that in the original question. Sorry. Updated my answer.

Your Answer

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.