I have 2 input div and each div has multiple inputs. I would like to build an object from an array. I looped from the input element to get each value, then I'm trying to save the index of input div in the object that I have built as I want to group them in an object as designed in HTML., but I'm not getting all the values saved in the data variable. Any idea what am I doing wrong?
Here's the HTML markup and JS:-
var data = [];
$('.button').click(function() {
$('.input input').each(function(i) {
var index = $(this).parent().parent().prevAll().length;
var obj = {};
obj.text = $(this).val();
obj.radio = $(this).val();
data.push({
index: index,
obj: obj
});
});
var inputs = [];
$.each(data, function() {
inputs[this.index] = this.obj;
});
console.log(inputs);
});
.input {
margin-bottom: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="input">
<strong>Test 1</strong>
<div class="text">
<input type="text" value="test" />
</div>
<div class="radio">
<input type="radio" id="input-1-yes" name="input-1" value="Input 1: Yes" checked>
<label for="input-1-yes">Input 1: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-1-no" name="input-1" value="Input 1: No">
<label for="input-2-no">Input 2: No</label>
</div>
</div>
<div class="input">
<strong>Test 2</strong>
<div class="text">
<input type="text" value="test 2" />
</div>
<div class="radio">
<input type="radio" id="input-1-yes" name="input-2" value="Input 3: Yes">
<label for="input-3-yes">Input 3: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-4-no" name="input-2" value="Input 4: No" checked>
<label for="input-4-no">Input 4: No</label>
</div>
<div class="radio">
<input type="radio" id="input-5-yes" name="input-3" value="Input 5: Yes">
<label for="input-5-yes">Input 5: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-6-no" name="input-3" value="Input 6: No" checked>
<label for="input-6-no">Input 6: No</label>
</div>
</div>
</div>
<div class="debug-template">
<div></div>
</div>
<div class="debug-container">
</div>
<div class="button">
<button>Build Object</button>
</div>
Expected output:-
{
0: {
text: 'test',
radio: {
'0': 'Input 1: Yes'
}
},
1: {
text: 'test 2',
radio: {
'0': 'Input 4: No',
'1': 'Input 6: No'
}
}
}
2 Answers 2
So, based on your desired output, I needed to make some modifications on your code logic...
Insted of looping directly all <input>, loop through the div.input then creates the object and get its id. After that, loop through each input element that is inside the div, check if it is a text or a radio type, if radio, check if it is checked then push or not to the obj radio object.
see below code please.
-> EDIT <-
Once you said that the desired output needs to be an outer object instead of an array, and the object.radio should be another object, then I modified code as below:
var data = {};
$('.button').click(function() {
$('.input').each(function(i) {
let index = $(this).index();
var obj = {};
var radioCount = 0
obj.text = "";
obj.radio = {};
$(this).find("input").each((idx, elem) => {
if (elem.type == "text"){
obj.text = elem.value;
}else if (elem.type == "radio" && elem.checked == true){
obj.radio[radioCount] = (elem.value);
radioCount++;
}
});
data[i] = obj;
});
console.log(data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="input">
<div class="text">
<input type="text" value="test" />
</div>
<div class="radio">
<input type="radio" id="input-1-yes" name="input-1" value="Input 1: Yes" checked/>
<label for="input-1-yes">Input 1: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-1-no" name="input-1" value="Input 1: No"/>
<label for="input-2-no">Input 2: No</label>
</div>
</div>
<div class="input">
<div class="text">
<input type="text" value="test 2" />
</div>
<div class="radio">
<input type="radio" id="input-1-yes" name="input-2" value="Input 3: Yes"/>
<label for="input-3-yes">Input 3: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-4-no" name="input-2" value="Input 4: No" checked/>
<label for="input-4-no">Input 4: No</label>
</div>
<div class="radio">
<input type="radio" id="input-5-yes" name="input-3" value="Input 5: Yes"/>
<label for="input-5-yes">Input 5: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-6-no" name="input-3" value="Input 6: No" checked/>
<label for="input-6-no">Input 6: No</label>
</div>
</div>
</div>
<div class="debug-template">
<div></div>
</div>
<div class="debug-container">
</div>
<div class="button">
<button>Build Object</button>
</div>
7 Comments
object that have a text property that is a string and a radio property that is an object containing each check radio? Right?You can achieve it via jQuery map() method like:
$('.button').click(function() {
const data = $('.input').map(function(idex, elem) {
return {
text: $(elem).find('[type="text"]').val(),
radio: $(elem).find('[type="radio"]:checked').map(function(i, el){
return $(el).next('label').text();
}).get()
}
}).get();
const mainData = {};
data.map(function(value, index){
mainData[index] = value;
});
console.log(mainData);
});
$('.button').click(function() {
const data = $('.input').map(function(idex, elem) {
return {
text: $(elem).find('[type="text"]').val(),
radio: $(elem).find('[type="radio"]:checked').map(function(i, el){
return $(el).next('label').text();
}).get()
}
}).get();
const mainData = {};
data.map(function(value, index){
mainData[index] = value;
});
console.log(mainData);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="input">
<strong>Test 1</strong>
<div class="text">
<input type="text" value="test" />
</div>
<div class="radio">
<input type="radio" id="input-1-yes" name="input-1" value="Input 1: Yes" checked>
<label for="input-1-yes">Input 1: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-1-no" name="input-1" value="Input 1: No">
<label for="input-2-no">Input 2: No</label>
</div>
</div>
<div class="input">
<strong>Test 2</strong>
<div class="text">
<input type="text" value="test 2" />
</div>
<div class="radio">
<input type="radio" id="input-1-yes" name="input-2" value="Input 3: Yes">
<label for="input-3-yes">Input 3: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-4-no" name="input-2" value="Input 4: No" checked>
<label for="input-4-no">Input 4: No</label>
</div>
<div class="radio">
<input type="radio" id="input-5-yes" name="input-3" value="Input 5: Yes">
<label for="input-5-yes">Input 5: Yes</label>
</div>
<div class="radio">
<input type="radio" id="input-6-no" name="input-3" value="Input 6: No" checked>
<label for="input-6-no">Input 6: No</label>
</div>
</div>
</div>
<div class="button">
<button>Build Object</button>
</div>
thisinstead ofthis.objto the array?var index = $(this).parent().parent().prevAll().length;. Look at values it produces. What exactly is your intent with that?indexeach time you'll see that 3 times it outputs 0 and 5 times it outputs 1. So then when you come to populate theinputsarray, you keep overwriting the same indexes with different values. Hence you only ever get two items output. Also your "text" and "radio" properties get populated with the same thing. It would really help if you could show us what you want as the correct output. Just saying "I want to make an object" doesn't give us enough detail to go on, we need to know what the object should contain