17

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

1
  • You should not have multiple inputs with the same name attribute in the same <form>. (Unless for radio buttons) Commented Jan 17, 2018 at 14:49

7 Answers 7

12

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>

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

2 Comments

I think he really meant to get the value, not the placeholder.
@Tushar better if you help me with this stackoverflow.com/q/48353270/3297613
10

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

2 Comments

Should var fd = new FormData(time) be ...('time')?
in this case yes (if you are lazy), Normally you would do var time = document.getElementById('time') but any element with a id that don't have it's name on the global window scope can be accessed from window. Read this QA. It's a bit of risky but for the sake of this simple demo i choosed to use ...('time')
4

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>

1 Comment

Look twice at dataArray
3

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>

Comments

1

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>

Comments

1
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

Comments

0

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/

Comments

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.