Как я могу хранить несколько наборов входных значений в JS?

Рассмотрим следующие пары входных данных

<input type="text" class="item_name" value="iphone">
<input type="text" class="item_qty" value="10">

<input type="text" class="item_name" value="macbook">
<input type="text" class="item_qty" value="5">

Количество пар входных данных на странице является динамическим, а не фиксированным.

Я хочу перебрать все пары и сохранить значения в виде пар, которые позже будут выводиться, например, в таблицу.

Я пытался сделать это с помощью jQuery each(), но я не могу понять это полностью.

  var detail = [];
  //var detail = {};

   $('input').each(function(index) {
      detail[index] = $(this).val();
      //detail.index = $(this).val();
   });

  console.log(detail);

Это выводит

["iphone", "10", "macbook", "5"]

И это не то, что мне нужно.

Я привык к PHP, так каков правильный подход в JS/jQuery для хранения пар входных данных в виде многомерного ассоциативного массива/объекта?


person Ashley Brown    schedule 13.02.2017    source источник
comment
Это на самом деле не связано с вопросом, но в ваших элементах input отсутствует атрибут name.   -  person 4castle    schedule 13.02.2017
comment
@4castle Они не принадлежат форме, поэтому я не вижу причин их использовать.   -  person Ashley Brown    schedule 13.02.2017


Ответы (5)


Вы можете перебирать элементы с классом item_name и создавать массив объектов, каждый из которых имеет свойство name и qty.

Вы можете легко создать этот массив, используя jQuery .map():

var details = $('.item_name').map(function() {
  return {
    name: $(this).val(),
    qty: $(this).next('.item_qty').val()
  };
}).get();

console.log(details);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="item_name" value="iphone">
<input type="text" class="item_qty" value="10">

<input type="text" class="item_name" value="macbook">
<input type="text" class="item_qty" value="5">

person 4castle    schedule 13.02.2017
comment
И это то, что я собирался опубликовать, если бы не наткнулся на ваш ответ! - person ibrahim mahrir; 13.02.2017

Эквивалентом ассоциативного массива в javascript является объект (оба действуют как словарь).

Проблема заключается в том, что ваш html описывает ключ и значение как входные данные в плоском списке, поэтому, когда вы перечисляете их с помощью JQuery .each(), вы возвращаете их все в один список.

[key, value, key, value]

то, что вы, скорее всего, хотите, это объект вроде:

var obj = {
  key: value,
  key: value
}

Затем вы можете получить, например, свойство «macbook»

obj.macbook or obj['macbook']

Вы можете добиться этого, либо перебирая список по два за раз и добавляя их к объекту, либо реструктурируя свой html, чтобы иметь входы как ключа, так и значения внутри другого элемента, например.

<div class="item">
 <input type="text" class="item_name" value="iphone">
 <input type="text" class="item_qty" value="10">
</div>
<div class="item">
 <input type="text" class="item_name" value="macbook">
 <input type="text" class="item_qty" value="5">
</div>

Затем вы можете сделать что-то вроде этого:

var items = {}
$('.item').each(function(){
 var key = $(this).find('.item_name').val()
 var value = $(this).find('.item_qty').val()
 items[key] = value;
})
person dpix    schedule 13.02.2017

var val = $("input.item_name").map(function(){
obj = {}

obj[$(this).val()] = $(this).next("input.item_qty").val();

return obj;
}).get()

console.log(val)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="item_name" value="iphone">
<input type="text" class="item_qty" value="10">

<input type="text" class="item_name" value="macbook">
<input type="text" class="item_qty" value="5">

Используйте .map()

person guradio    schedule 13.02.2017
comment
С такой структурой, возможно, было бы более разумно выводить только один объект со многими ключами, а не массив объектов, каждый из которых имеет один ключ. - person 4castle; 13.02.2017
comment
Неплохо подмечено. Каковы плюсы и минусы каждого @4castle? - person Ashley Brown; 13.02.2017
comment
Массивы @ProEvilz допускают дублирование элементов, в то время как объекты требуют, чтобы каждый ключ был уникальным в объекте. Массивы намного проще использовать, потому что есть много встроенных служебные функции для управления и повторения их содержимого. - person 4castle; 13.02.2017

Вы можете использовать рекурсию, Array.prototype.slice() для нарезки двух элементов <input> при каждом вызове функции, заполнения объекта парами ключей и значений до тех пор, пока не будет достигнуто <input> элементов .length

var [obj, n] = [{}, 2];
var inputs = $("input[type=text]");
var res = (function re(i) {
  if (i + n <= inputs.length) {
    var [key, prop] = Array.from(inputs).slice(i, i + n).map(({value}) => value)
    obj[key] = prop;
    i += n;
    return re(i)  
  } else {
    return obj
  }
})(0);
console.log(res)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="item_name" value="iphone">
<input type="text" class="item_qty" value="10">

<input type="text" class="item_name" value="macbook">
<input type="text" class="item_qty" value="5">

person guest271314    schedule 13.02.2017
comment
Многие люди, использующие jQuery, делают это из-за его совместимости с браузерами. В этом ответе используются несколько функций из ES6, который имеет более низкую совместимость с браузером и должен быть перенесен с чем-то вроде Babel для работы. в старых браузерах. - person 4castle; 13.02.2017
comment
@4castle Ответ должен проиллюстрировать возможный шаблон, который можно использовать для возврата ожидаемого результата. Вы предлагаете отредактировать ответ, чтобы удалить деструктурирующие задания? Когда возникают проблемы с совместимостью браузера, первым впечатлением будет предложение обновить браузер. - person guest271314; 13.02.2017
comment
Я думаю, что использование функций ES6 в ответах — отличная практика, потому что она учит людей новым функциям. Я просто думаю, что важно оставить примечание о том, как заставить его работать со старыми браузерами. - person 4castle; 13.02.2017
comment
@ProEvils Обратите внимание, что задания деструктурирования в ответе можно заменить на var obj = {}; var n = 2; на Array.from() на var arr = Array.prototype.slice.call(inputs, i, i + n).map(function(o) {return o.value}), var key = arr[0]; var prop = arr[1] - person guest271314; 13.02.2017

Вы можете попробовать быстрое и «грязное» решение:

Ссылка: для каждого типа ввода получить значение с помощью javascript

Вы были на правильном пути с .getElementById, но вместо этого хотите .getElementsByName.

var els = document.getElementsByName("filter[]");

for (var i = 0; i < els.length; i++)
  alert(els[i].value);
<input id="filter_15" type="checkbox" name="filter[]" value="15">
<input id="filter_16" type="checkbox" name="filter[]" value="16">
<input id="filter_17" type="checkbox" name="filter[]" value="17">

Или выполните следующее: jQuery .each() с элементами ввода

Чтобы извлечь номер:

var arrNumber = new Array();
$('input[type=number]').each(function(){
    arrNumber.push($(this).val());
})

Чтобы извлечь текст:

var arrText= new Array();
$('input[type=text]').each(function(){
    arrText.push($(this).val());
})

Редактировать: .map реализация

var arrText= $('input[type=text]').map(function(){
    return this.value;
}).get();
person Tran Manh Quy    schedule 13.02.2017
comment
упс! Я копирую ваш текст, но он не работает в моем комментарии! - person Tran Manh Quy; 13.02.2017
comment
Я специально не ищу способ их вывода, а способ сохранить их в массиве или в виде объекта, из которого я могу потом вывести. Часть detail.name была просто примером того, как я хотел бы написать ее, чтобы дать больше ясности в отношении типа необходимого цикла. - person Ashley Brown; 13.02.2017
comment
Я думаю, вам нужно создать объект для хранения значения. Таким образом, вы можете получить его из массива и использовать obj.attribute.. - person Tran Manh Quy; 13.02.2017