Задать вопрос
Dier_Sergio_Great
@Dier_Sergio_Great
Увлеченный человек

Как конвертировать массив полей FORM/формы в массив полей объекта JS?

<form id=data ... >
<input name=list[label][]  value=Машина>
<input name=list[label][]  value=Дом>
<input name=list[cost][]  value=123>
<input name=list[cost][]  value=321>
</form>

закидываю форму в FormData Объект и получаю имена полей не как массив, а как строки.
fd = new FormData(document.getElementById(data));
console.log(fd);

0: "list[label][]" → "Машина"​​
1: "list[cost][]" → "123"​​
2: "list[label][]" → "Дом"​​
3: "list[cost][]" → "321"​​

Мы видим что каждое второе значение имеет одинаковый ключ.
let data = {}
fd.forEach((value, key) => data[key] = value);
console.log(data );

То получаем всего 2 значения в объекте DATA
data {
0: "list[label][]" → "Дом"
1: "list[cost][]" → "321"
}

Как сделать чтобы объект data содержал все значения полей с нумерованными ключами?
как это получается по аналогии на PHP $_GET[list][label][0] и $_GET[list][label][1]т.е. по нумерованному ключу массива можно получить значения а не в виде строки.
  • Вопрос задан
  • 168 просмотров
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Skillbox
    JavaScript
    3 месяца
    Далее
  • Яндекс Практикум
    Фронтенд-разработчик расширенный
    13 месяцев
    Далее
  • Академия Eduson
    Fullstack-разработчик на JavaScript
    11 месяцев
    Далее
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
const formData = {
  get: form =>
    Array.prototype.reduce.call(form.elements, (acc, n) => {
      const [ keys, k, isCheckbox, isRadio ] = formData._parseElement(n);
      const values = keys.reduce((p, c, i, a) => {
        return p[c] ??= (-~i !== a.length || k ? {} : []);
      }, acc);

      if (!isCheckbox || k || n.checked) {
        values[k || values.length] ??=
          (isCheckbox &&          k) ? n.checked :
          (isRadio    && !n.checked) ?      null :
                                         n.value;
      }

      return acc;
    }, {}),

  set: (form, data) =>
    Array.prototype.forEach.call(form.elements, function(n) {
      const [ keys, k, isCheckbox, isRadio ] = formData._parseElement(n);
      const values = keys.reduce((p, c) => p?.[c], data);
      const key = (isCheckbox || k) ? k : `${this[n.name] = -~(this[n.name] ?? -1)}`;

      if (values instanceof Object && (!key || Object.hasOwn(values, key))) {
        const v = key ? values[key] : values;

        n[(isCheckbox || isRadio) ? 'checked' : 'value'] =
                     isRadio ? v ===      n.value  :
          (isCheckbox && !k) ? v.includes(n.value) :
                               v;
      }
    }, {}),

  _parseElement(el) {
    const keys = Array.from(el.name.matchAll(/\w+|\[(\w*)\]/g), n => n[1] ?? n[0]);
    return [ keys, keys.pop(), el.type === 'checkbox', el.type === 'radio' ];
  },
};

https://jsfiddle.net/htxb56v8/
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы