简体   繁体   中英

JavaScript loop over input creates an array of objects

I'm trying to loop over input elements in div, to create an array of objects

<div id="time">
  <input type="text" name="from" placeholder="12:00 AM" />
  <input type="text" name="to" placeholder="12:30 AM" />
  <input type="text" name="from" placeholder="13:00 AM" />
  <input type="text" name="to" placeholder="13:30 AM" />
</div>

I'm trying to create the following array of objects.

 unavailability: [
      { from: '12:00', to: '12:30' },
      { from: '13:00', to: '13:30' }
    ]

Here is what I have tried so far, but result is quite different.

var dataArray = []
$("#time").find('input').each(function() {
  var data = {};

  data[this.name] = this.value
  dataArray.push(data);

});
console.log(dataArray)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="time">
  <input type="text" name="from" placeholder="12:00 AM" />
  <input type="text" name="to" placeholder="12:30 AM" />
  <input type="text" name="from" placeholder="13:00 AM" />
  <input type="text" name="to" placeholder="13:30 AM" />
</div>

JSFiddle

You may iterate over all the elements having name attribute value as from . To get the to value, use next() method of jQuery.

Use .val() method to get the value of item.

 $('#submit').click(function() { var data = []; $('#time input[name="from"]').each(function() { data.push({ from: $(this).val(), to: $(this).next().val() }); }); console.log(data); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> Enter times in the below textboxes <div id="time"> <input type="text" name="from" placeholder="12:00 AM" /> <input type="text" name="to" placeholder="12:30 AM" /> <input type="text" name="from" placeholder="13:00 AM" /> <input type="text" name="to" placeholder="13:30 AM" /> </div> <button id="submit">Submit</button> 

I would have solved it with FormData. It means less DOM navigation and less chance of doing something wrong if you change the markup later. This also means you would have to change your div element to a form element (unless you have it somewhere higher up - in that case you could use that form element in the constructor and keep the div element):

 // Get a formdata instance var fd = new FormData(time) // Get all values var from = fd.getAll('from') var to = fd.getAll('to') // Transform var unavailable = from.map((from, i) => ({ from, to: to[i] })) console.log({unavailable}) 
 <form id="time"> <input type="text" name="from" placeholder="12:00 AM" value="12:00" /> <input type="text" name="to" placeholder="12:30 AM" value="12:30" /> <input type="text" name="from" placeholder="13:00 AM" value="13:00" /> <input type="text" name="to" placeholder="13:30 AM" value="13:30" /> </form> 

BTW, you are mixing 12/24 hours (13:00). It should maybe be written as 1:00 pm(?).

I would also have changed the type to type="time" to avoid mistakes. It gives you a nice time picker and it does normalize the value if the user enters a 12 or 24 hour value. You would also then be able to use step/min/max/required for better validation if you would need it

Instead of iterating over each input, you need to iterate over every alternate input element with name attribute equal to form. Then create the JSON information for the element you are iterating on and immediate next sibling input element.

Also 12.30 am is not the value of the element, its placeholder. You need to replace the value with a placeholder:

$("#time").find('input[name="from"]').each(function() {
    var data = {};
    data[this.name] = this.placeholder;
    var nextInput = $(this).next()[0];
    data[nextInput .name] = nextInput.placeholder;
    dataArray.push(data);
});

Working Demo

The best way to achieve this is to use the jQuery .map() function returning the JSON object along with .get() to create array of JSON objects:

var dataArray = $("#time").find('input[name="from"]').map(function() {
    var nextInput = $(this).next()[0];
    var jo = {};
    jo[this.name]=this.placeholder;jo[nextInput.name] = nextInput.placeholder
    return jo;
}).get();

 var dataArray = $("#time").find('input[name="from"]').map(function() { var nextInput = $(this).next()[0]; var jo = {}; jo[this.name]=this.placeholder;jo[nextInput.name] = nextInput.placeholder return jo; }).get(); console.log(dataArray) 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="time"> <input type="text" name="from" placeholder="12:00 AM" /> <input type="text" name="to" placeholder="12:30 AM" /> <input type="text" name="from" placeholder="13:00 AM" /> <input type="text" name="to" placeholder="13:30 AM" /> </div> 

You can do that in the following way:

 var unavailability = []; $('#time input[name=from]').each(function(i, input){ unavailability.push({ from: $(this).attr('placeholder').split(' ')[0], to: $(this).next().attr('placeholder').split(' ')[0] }); }); console.log(unavailability); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="time"> <input type="text" name="from" placeholder="12:00 AM" /> <input type="text" name="to" placeholder="12:30 AM" /> <input type="text" name="from" placeholder="13:00 AM" /> <input type="text" name="to" placeholder="13:30 AM" /> </div> 

var dataArray = [];
$("#time").find('input[name="from"]').each(function() {
    var data = {};
    data.from = this.value;
    data.to = $(this).next().val();
    dataArray.push(data);
});

console.log(dataArray);

Updated fiddle

Here either you need to use an event handler for change in values of any input or you need to give some initial values to these inputs.

Also you can iterate as shown below to get the desired result.

 var dataArray = []; var data = {}; $("#time").find('input').each(function(i) { if(i%2 === 0){ data={}; data[this.name] = this.value; } else{ data[this.name] = this.value; dataArray.push(data); } }); console.log(dataArray); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="time"> <input type="text" name="from" placeholder="12:00 AM" value="12:00 AM" /> <input type="text" name="to" placeholder="12:30 AM" value="12:30 AM" /> <input type="text" name="from" placeholder="13:00 AM" value="13:00 AM" /> <input type="text" name="to" placeholder="13:30 AM" value="13:30 AM" /> </div> <span id="output"></span> 

In my answer I push new item to array only if this.name === "from" . If this.name === "to" , I add new property to the last pushed item, and finally we have 2 objects in array and 2 properties in each object:

 $("#btn").click(doStuff); function doStuff() { var dataArray = [] var newArrayLength; $("#time").find('input').each(function() { if (this.name === "from") { var data = {}; data[this.name] = this.value newArrayLength = dataArray.push(data); } else if (this.name === "to") { dataArray[newArrayLength - 1][this.name] = this.value; } }); console.log(dataArray); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="time"> <input type="text" name="from" placeholder="12:00 AM" /> <input type="text" name="to" placeholder="12:30 AM" /> <input type="text" name="from" placeholder="13:00 AM" /> <input type="text" name="to" placeholder="13:30 AM" /> </div> <span id="output"></span> <button id="btn">Click</button> 

https://jsfiddle.net/ss725ere/2/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM