Как преобразовать данные формы во вложенный объект?

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

К примеру, есть форма:

<form>
    <label>
        <input type="text" name="GROUP1[NAME]">
    </label>
    <label>
        <input type="text" name="GROUP2[EMAIL]">
    </label>
    <label>
        <input type="text" name="GROUP2[PHONE]">
    </label>
    <label>
        <input type="text" name="GROUP2[CITY]">
    </label>
    <label>
        <textarea type="text" name="GROUP1[TEXT]"></textarea>
    </label>
</form>

Хочу получить на выходе:

{
    GROUP1 {
        NAME: 'значение',
        TEXT: 'значение'
    },
    GROUP2 {
        EMAIL: 'значение',
        PHONE: 'значение',
        CITY: 'значение'
    },
}

Не url кодированную строку, не FormData, не плоский список, а просто объект, который я могу бы получить скажем из массива $_POST на сервере.
  • Вопрос задан
  • 391 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
const data = Array.prototype.reduce.call(
  document.querySelector('form').elements,
  (acc, n) => {
    const keys = n.name.match(/\w+/g);
    const key = keys.pop();
    keys.reduce((p, c) => p[c] ??= {}, acc)[key] = n.value;
    return acc;
  },
  {}
);

UPD. Вынесено из комментариев:

Для
<input type="text" name="iuowye[rrr][]" value="1">
<input type="text" name="iuowye[rrr][]" value="2">
<input type="text" name="iuowye[rrr][]" value="3">

работать не будет.

const data = Array
  .from(document.querySelectorAll('form [name]'))
  .reduce((acc, { name, value }) => {
    const keys = name.match(/\w+|\[\w*\]/g).map(n => n.replace(/^\[|\]$/g, ''));
    const key = keys.pop();
    const isArr = !key;
    const values = keys.reduce((p, c, i, a) => {
      return p[c] ??= (i === a.length - 1 && isArr ? [] : {});
    }, acc);
    values[isArr ? values.length : key] = value;
    return acc;
  }, {});
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
yarkov
@yarkov Куратор тега JavaScript
Помог ответ? Отметь решением.
Если просто, то вот так:
const form = document.querySelector('form');
const data = new FormData(form);

for (let entry of data) {
	console.log(entry);
}
Ответ написан
zkrvndm
@zkrvndm
Архитектор решений
Если на сайте есть jQuery то ваша проблема решается в одну строку:
https://api.jquery.com/serializeArray/

Функция serializeArray делает из формы объект:
$('form').serializeArray(); // Вытащит данные из формы в виде объекта
Ответ написан
Ваш ответ на вопрос

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

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