Как я могу получить данные формы с помощью JavaScript / jQuery?


404

Существует ли простой однострочный способ получения данных формы, как это было бы, если бы они были представлены классическим способом только для HTML?

Например:

<form>
    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />
    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
</form>

Вывод:

{
    "foo": "1",
    "bar": "xxx",
    "this": "hi"
}

Нечто подобное слишком простое, поскольку оно не включает (правильно) текстовые области, селекторы, переключатели и флажки:

$("#form input").each(function () {
    data[theFieldName] = theFieldValue;
});

3
Еще один вопрос, похожий на этот: stackoverflow.com/questions/169506/…
Марсело Родовалью

Ответы:


431
$('form').serialize() //this produces: "foo=1&bar=xxx&this=hi"

демонстрация


15
Закрыть, но, возможно, что-то, что возвращает массив с парами ключ-значение вместо одной строки?
Барт ван Хейкелом

80
Nvm, нашел это в комментариях для функции serialize (). Это называется serializeArray. Он возвращает массив массивов (которые содержат запись «имя» и «значение»), но это должно быть достаточно легко для преобразования.
Барт ван Хейкелом

22
И использование библиотеки подчеркивания может быть преобразовано с помощью:_.object($("#myform").serializeArray().map(function(v) {return [v.name, v.value];} ))
MhdSyrwan

8
@BartvanHeukelom Я знаю, что это 4 года спустя, но .serializeArray () вернет массив.
Евангелист API TJ WealthEngine

6
Убедитесь, что каждый входной тег содержит атрибут name, иначе он ничего не вернет.
Евгений Кулабухов

507

Использование $('form').serializeArray(), которое возвращает массив :

[
  {"name":"foo","value":"1"},
  {"name":"bar","value":"xxx"},
  {"name":"this","value":"hi"}
]

Другой вариант $('form').serialize(), который возвращает строку :

"foo=1&bar=xxx&this=hi"

Посмотрите на это демо jsfiddle


91
serializeArrayбыло бы намного полезнее, если бы он возвращал объект с парами ключ-значение
GetFree

8
Я согласен, что объект будет идеальным. Однако есть проблема - ключ может иметь несколько значений. Вы бы вернули ключ - «массив значений» или ключ - «первое значение» или что-то еще? Я думаю, что ребята из jQuery не выбрали ничего из вышеперечисленного :)
Пол

Помните о проблеме с несколькими значениями (как упоминалось выше @Paul), флажки и несколько входов с name="multiple[]"не работают. Решение для метода POST такое же, просто используйте $ ('form'). Serialize (). Кроме того, метод POST не имеет ограничения в 2000 символов, как GET в большинстве браузеров, поэтому может использоваться даже для довольно больших данных.
Артру

Также имейте в виду, что для записи значения из любого ввода формы у ввода должен быть nameатрибут.
Крис - младший

@ GetFree, почему бы просто не использовать функцию карты jQuery? function getFormData (form) {var rawJson = form.serializeArray (); var model = {}; $ .map (rawJson, function (n, i) {model [n ['name']] = n ['value'];}); возвращаемая модель; }
Том Макдоно

196

Обновленный ответ за 2014 год: HTML5 FormData делает это

var formData = new FormData(document.querySelector('form'))

Затем вы можете опубликовать formData точно так, как он есть - он содержит все имена и значения, используемые в форме.


13
Плюс один , как FormData хорошо и полезно, но стоит отметить , что если вы хотите , чтобы прочитать данные внутри FormData это не совсем так просто (см stackoverflow.com/questions/7752188/... )
StackExchange Что щеколда

1
Помните, что FormData является частью расширенных функций XMLHttpRequest (ранее известный как XMLHttpRequest Level 2), поэтому вы должны полагаться на полизаполнение для Internet Explorer <10. caniuse.com/#feat=xhr2
Pier-Luc Gendreau

3
@yochannah, не так. Конечно, нельзя просто получить доступ и редактировать данные, как обычный объект, но получить данные по-прежнему тривиально. Проверьте entries()метод [страница MDN ].
Сеть и поток

@Web и Flow спасибо за указание на это! Мне нравится, когда браузеры добавляют новые и полезные функции :) времена, они меняются.
StackExchange, что, черт возьми,

Я пытаюсь использовать FormData для отправки объекта в мой скрипт на Flask-python, но он не выглядит как обычный объект запроса, который я могу распаковать. Может кто-то указать на объяснение каких-либо специальных шагов для обработки на стороне сервера? Вот где мне кажется пустым.
Маниша

181

На основании jQuery.serializeArrayвозвращает пары ключ-значение.

var data = $('#form').serializeArray().reduce(function(obj, item) {
    obj[item.name] = item.value;
    return obj;
}, {});

12
Пары ключ-значение здесь, ребята, все, иди сюда! Это золото !!! Спасибо! Если мне нужно значение элемента с именем «retailer», я делаю это console.log ($ ('# form'). SerializeArray (). Redu (функция (obj, item) {obj [item.name] = item. value; return obj;}, {}) ['retailer']);
Евгений Афанасьев

Вчера я создал метод JQuery, основанный на этом ответе, но работающий с множественными выборками и входными массивами (с именем 'example []'). Вы можете найти это в моем ответе ниже. В любом случае, хороший подход, нейрон, спасибо! :)
manuman94

Этот из них больше всего мне подходил из всех ответов!
В.Петрович

Это ИМХО - лучший ответ!
Рахул

74
document.querySelector('form').addEventListener('submit', (e) => {
  const formData = new FormData(e.target);
  // Now you can use formData.get('foo'), for example.
  // Don't forget e.preventDefault() if you want to stop normal form .submission
});

Это глупый ответ, но позвольте мне объяснить, почему это лучшее решение:

  • Мы правильно обрабатываем отправку формы, а не нажатие кнопки. Некоторые люди любят нажимать ввод на полях. Некоторые люди используют альтернативные устройства ввода, такие как речевой ввод или другие устройства доступа. Обработка формы отправки и вы правильно решите ее для всех.

  • Мы копаем данные формы для фактической формы, которая была отправлена. Если вы измените селектор формы позже, вам не нужно менять селекторы для всех полей. Кроме того, у вас может быть несколько форм с одинаковыми именами ввода. Не нужно устранять неоднозначность с избыточными идентификаторами, а что нет, просто отслеживайте входные данные на основе формы, которая была отправлена. Это также позволяет вам использовать один обработчик событий для нескольких форм, если это подходит для вашей ситуации.

  • Интерфейс FormData довольно новый, но хорошо поддерживается браузерами. Это отличный способ создать этот сбор данных, чтобы получить реальные значения формы. Без этого вам придется пройтись по всем элементам (например, с помощью form.elements) и выяснить, что проверено, а что нет, какие значения и т. Д. Вполне возможно, если вам нужна поддержка старого браузера, но FormData Интерфейс проще.

  • Я использую ES6 здесь ... ни в коем случае не требуется, поэтому измените его обратно на ES5-совместимый, если вам нужна поддержка старого браузера.


Например, объекты FormData не предоставляют свои значения. Чтобы получить простой объект из него, см stackoverflow.com/questions/41431322/...
phil294

2
@Blauhirn Ерунда, конечно, они выставляют ценности. Код в моем ответе работает. Тебе следует это попробовать. Здесь я сделал для вас скрипку: jsfiddle.net/zv9s1xq5 Если вам нужен итератор, используйте formData.entries().
Брэд

Я знаю, что это работает, но свойства не доступны по ключу. Например, formData.foo не определено. Как видно из вашего ответа, .get() необходимо призвать к тому, что я считаю неудобным. Может быть, «не разоблачить» наткнулся на неправильный путь. Итак, чтобы сгенерировать что-то похожее { foo: 'bar' }на submitсобытие, вам нужно выполнить итерации по ним вручную. Отсюда . To get a plain object from it, see [link].
phil294

1
@Blauhirn Ты ошибаешься по этому поводу. XMLHttpRequest поддерживает FormData напрямую. xhr.send(formData);
Брэд

1
@Blauhirn JSON.stringify([...formData]) Или, если вы хотите, чтобы ваши ключи / значения были отдельными ... [...formData].reduce((prev, cur) => { prev[cur[0]] = cur[1]; return prev;}, {})
Брэд,

26

используйте .serializeArray (), чтобы получить данные в формате массива, а затем преобразовать их в объект:

function getFormObj(formId) {
    var formObj = {};
    var inputs = $('#'+formId).serializeArray();
    $.each(inputs, function (i, input) {
        formObj[input.name] = input.value;
    });
    return formObj;
}

Это перезаписывает мои флажки, если у меня есть что-то вроде <input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />. Если оба отмечены, объект содержит только второе значение флажка.
dmathisen

2
Разве это не тот случай, где someListдолжно быть type="radio"?
dylanjameswagner

upvote, потому что принятый ответ не возвращает объект с ключами в виде:name:value
Matt-the-Marxist

24

Вот действительно простой и короткий солутон, который даже не требует Jquery.

var formElements=document.getElementById("myForm").elements;    
var postData={};
for (var i=0; i<formElements.length; i++)
    if (formElements[i].type!="submit")//we dont want to include the submit-buttom
        postData[formElements[i].name]=formElements[i].value;

1
Это не работает с переключателями: последний параметр всегда хранится в postData.
Кайл Фалконер

3
Спасибо, что дали нам ответ не JQuery.
Глен Пирс,

24

Это 2019 год, и есть лучший способ сделать это:

const form = document.querySelector('form');
const data = new URLSearchParams(new FormData(form).entries());

или если вы хотите простой объект вместо

const form = document.querySelector('form');
const data = Object.fromEntries(new FormData(form).entries());

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


Полностью. Хотя, я не получил массив для списка входов , которые все имеют такое же имя , которое означало , что мне пришлось использовать document.getElementsByClassNameи для цикла , но эй, еще лучше , чем требует JQuery и т.д.
alphanumeric0101

1
Этот ответ мой любимый. Но это следует читать, document.querySelectorа не просто querySelector.
Адабру

Примечание: «FormData будет использовать только те поля ввода, которые используют атрибут name» - из MDN
binaryfunt


13
$("#form input, #form select, #form textarea").each(function() {
 data[theFieldName] = theFieldValue;
});

кроме этого, вы можете посмотреть на serialize () ;


13

Я использую это:

Плагин jQuery

(function($){
  $.fn.getFormData = function(){
    var data = {};
    var dataArray = $(this).serializeArray();
    for(var i=0;i<dataArray.length;i++){
      data[dataArray[i].name] = dataArray[i].value;
    }
    return data;
  }
})(jQuery);

HTML-форма

<form id='myform'>
  <input name='myVar1' />
  <input name='myVar2' />
</form>

Получить данные

var myData = $("#myForm").getFormData();

Обратите внимание, что этот плагин не работает для случаев, когда присутствуют несколько записей ввода формы с одним и тем же именем. Последняя запись заменит предыдущую, тогда как ожидаемое поведение будет состоять в том, чтобы получить все значения в видеArray
Milli

1
Просто примечание, что через год я думаю, что это ужасный ответ, и никто не должен его использовать. Как сказано в предыдущем комментарии, такие вещи, как переключатели, не будут работать. Есть лучшие ответы выше, используйте один из них.
Дастин Пуассан

11

Вот рабочая реализация только для JavaScript, которая корректно обрабатывает флажки, переключатели и ползунки (возможно, и другие типы ввода, но я только проверял их).

function setOrPush(target, val) {
    var result = val;
    if (target) {
        result = [target];
        result.push(val);
    }
    return result;
}

function getFormResults(formElement) {
    var formElements = formElement.elements;
    var formParams = {};
    var i = 0;
    var elem = null;
    for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
            case 'submit':
                break;
            case 'radio':
                if (elem.checked) {
                    formParams[elem.name] = elem.value;
                }
                break;
            case 'checkbox':
                if (elem.checked) {
                    formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
                }
                break;
            default:
                formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
    }
    return formParams;
}

Рабочий пример:

    function setOrPush(target, val) {
      var result = val;
      if (target) {
        result = [target];
        result.push(val);
      }
      return result;
    }

    function getFormResults(formElement) {
      var formElements = formElement.elements;
      var formParams = {};
      var i = 0;
      var elem = null;
      for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
          case 'submit':
            break;
          case 'radio':
            if (elem.checked) {
              formParams[elem.name] = elem.value;
            }
            break;
          case 'checkbox':
            if (elem.checked) {
              formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
            }
            break;
          default:
            formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
      }
      return formParams;
    }

    //
    // Boilerplate for running the snippet/form
    //

    function ok() {
      var params = getFormResults(document.getElementById('main_form'));
      document.getElementById('results_wrapper').innerHTML = JSON.stringify(params, null, ' ');
    }

    (function() {
      var main_form = document.getElementById('main_form');
      main_form.addEventListener('submit', function(event) {
        event.preventDefault();
        ok();
      }, false);
    })();
<form id="main_form">
  <div id="questions_wrapper">
    <p>what is a?</p>
    <div>
      <input type="radio" required="" name="q_0" value="a" id="a_0">
      <label for="a_0">a</label>
      <input type="radio" required="" name="q_0" value="b" id="a_1">
      <label for="a_1">b</label>
      <input type="radio" required="" name="q_0" value="c" id="a_2">
      <label for="a_2">c</label>
      <input type="radio" required="" name="q_0" value="d" id="a_3">
      <label for="a_3">d</label>
    </div>
    <div class="question range">
      <label for="a_13">A?</label>
      <input type="range" required="" name="q_3" id="a_13" min="0" max="10" step="1" list="q_3_dl">
      <datalist id="q_3_dl">
        <option value="0"></option>
        <option value="1"></option>
        <option value="2"></option>
        <option value="3"></option>
        <option value="4"></option>
        <option value="5"></option>
        <option value="6"></option>
        <option value="7"></option>
        <option value="8"></option>
        <option value="9"></option>
        <option value="10"></option>
      </datalist>
    </div>
    <p>A and/or B?</p>
    <div>
      <input type="checkbox" name="q_4" value="A" id="a_14">
      <label for="a_14">A</label>
      <input type="checkbox" name="q_4" value="B" id="a_15">
      <label for="a_15">B</label>
    </div>
  </div>
  <button id="btn" type="submit">OK</button>
</form>
<div id="results_wrapper"></div>

редактировать:

Если вы ищете более полную реализацию, взгляните на этот раздел проекта, для которого я сделал это . Я обновлю этот вопрос в конце концов с полным решением, которое я придумал, но, возможно, это будет кому-то полезно.


1
Хорошее решение :) Я нашел одну ошибку, с помощью функции setOrPush. Он не включает проверку, чтобы видеть, является ли цель уже массивом, вызывая создание глубоко вложенного массива в случае нескольких отмеченных флажков с тем же именем.
Вутер ван Дам

@KyleFalconer Отлично! Почему вы не слили корпуса переключателей для радио и флажок - они будут работать правильно (наверное).
Итан

@Ethan Это потому, что флажок может иметь несколько выбранных значений, а радио может когда-либо иметь только одно выбранное значение, поэтому способ сохранения значения изменяется.
Кайл Фалконер

@KyleFalconer Да, я понимаю это. Код для обработки 'checkbox' также заботится о единственно возможном выборе для 'radio' благодаря процедуре 'SetOrPush'.
Итан

@Ethan О, я думаю, я знаю, что ты говоришь. Это может быть сделано в любом случае, но я думаю, что я сделал это просто потому, что я хотел только одно значение, а не массив значений.
Кайл Фалконер

9

Если вы используете jQuery, вот небольшая функция, которая сделает то, что вы ищете.

Сначала добавьте в форму идентификатор (если это не единственная форма на странице, тогда вы можете просто использовать «форму» в качестве запроса DOM)

<form id="some-form">
 <input type="radio" name="foo" value="1" checked="checked" />
 <input type="radio" name="foo" value="0" />
 <input name="bar" value="xxx" />
 <select name="this">
  <option value="hi" selected="selected">Hi</option>
  <option value="ho">Ho</option>
</form>

<script>
//read in a form's data and convert it to a key:value object
function getFormData(dom_query){
    var out = {};
    var s_data = $(dom_query).serializeArray();
    //transform into simple data/value object
    for(var i = 0; i<s_data.length; i++){
        var record = s_data[i];
        out[record.name] = record.value;
    }
    return out;
}

console.log(getFormData('#some-form'));
</script>

Вывод будет выглядеть так:

{
 "foo": "1",
 "bar": "xxx",
 "this": "hi"
}

7

Вы также можете использовать объекты FormData ; Объект FormData позволяет вам скомпилировать набор пар ключ / значение для отправки с использованием XMLHttpRequest. Он в первую очередь предназначен для использования при отправке данных формы, но может использоваться независимо от форм для передачи ключевых данных.

        var formElement = document.getElementById("myform_id");
        var formData = new FormData(formElement);
        console.log(formData);

Спасибо, но что, если у вас нет удостоверения личности? Что если у вас есть форма в виде объекта JQuery? var form = $ (this) .closest ('form'); ? Должен var formElement = document.getElementById (form [0]); работать вместо вашей первой линии? Ну, это не работает, к сожалению. Ты знаешь почему?
Евгений Афанасьев

На самом деле FormData поддерживается не всеми браузерами :( поэтому лучше использовать другой подход
numediaweb

Спасибо. Я использовал последний хром, но он все еще не работал. Так что я пошел с #neuront ответом оттуда.
Евгений Афанасьев

6

Это добавит все поля формы к объекту JavaScript "res":

var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
    res[obj.name] = $(obj).val();
})

Вероятно, потому что этот же ответ уже был опубликован в 2010 году.
nathanvda

Я этого не знал. Для такого короткого ответа это не удивительно. И даже так, где ссылка?
Гамлиела

Шутки в сторону? Вы не верите моему комментарию без ссылки и даже не можете просмотреть список ответов, чтобы увидеть, совпадают ли они? stackoverflow.com/a/2276469/216513
Натанвда

Я думал, что вы имеете в виду ответ на другой вопрос. Я не помню сейчас детали и мои причины; может, потому что это не совсем то же самое
gamliela

1
Идеальный ответ для тех, кто хочет, чтобы он работал для ввода, выберите несколько и textarea. Потому что, используя сериализацию, вы не получите все элементы, выбранные в теге выбора. Но, используя .val (), вы получите именно то, что вы хотите в виде массива. Простой, прямой ответ.
Сайлеш Кота

6

Я включил ответ, чтобы также вернуть требуемый объект.

function getFormData(form) {
var rawJson = form.serializeArray();
var model = {};

$.map(rawJson, function (n, i) {
    model[n['name']] = n['value'];
});

return model;
}

Это не будет обрабатывать массивы вообще; foo[bar][] = 'qux'следует сериализовать в { foo: { bar: [ 'qux' ] } }.
амфетамина

6

Основываясь на ответе нейрона, я создал простой метод JQuery, который получает данные формы в парах ключ-значение, но работает для множественного выбора и для входных данных массива с именем = 'example []'.

Вот как это используется:

var form_data = $("#form").getFormObject();

Вы можете найти пример ниже его определения и как это работает.

// Function start
$.fn.getFormObject = function() {
    var object = $(this).serializeArray().reduce(function(obj, item) {
        var name = item.name.replace("[]", "");
        if ( typeof obj[name] !== "undefined" ) {
            if ( !Array.isArray(obj[name]) ) {
                obj[name] = [ obj[name], item.value ];
            } else {
               obj[name].push(item.value);
            }
        } else {
            obj[name] = item.value;
        }
        return obj;
    }, {});
    return object;
}
// Function ends

// This is how it's used
$("#getObject").click( function() {
  var form_data = $("#form").getFormObject();
  console.log(form_data);
});
/* Only to make view better ;) */
#getObject {
  padding: 10px;
  cursor:pointer;
  background:#0098EE;
  color:white;
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form id="form">
  <input type="text" name="text" value="Hola amigo" /> 
  
  <input type="text" name="text_array[]" value="Array 1" /> 
  <input type="text" name="text_array[]" value="Array 2" /> 
  <input type="text" name="text_array[]" value="Array 3" /> 
  
  <select name="multiselect" multiple>
    <option name="option1" selected> option 1 </option>
    <option name="option2" selected> option 2 </option>
  </select>
  
  <input type="checkbox" name="checkbox" value="checkbox1" checked/>
  <input type="checkbox" name="checkbox" value="checkbox2" checked/>
  
  <input type="radio" name="radio" value="radio1" checked/>
  <input type="radio" name="radio" value="radio2"/>

</form>

<div id="getObject"> Get object (check the console!) </div>


5
var formData = new FormData($('#form-id'));
params   = $('#form-id').serializeArray();

$.each(params, function(i, val) {
    formData.append(val.name, val.value);
});

4
function getFormData($form){
    var unindexed_array = $form.serializeArray();
    var indexed_array = {};

    $.map(unindexed_array, function(n, i){
        if(indexed_array[n['name']] == undefined){
            indexed_array[n['name']] = [n['value']];
        }else{
            indexed_array[n['name']].push(n['value']);
        }
    });

    return indexed_array;
}

4

Вы можете использовать эту функцию для получения объекта или JSON из формы.

для его использования:

var object = formService.getObjectFormFields("#idform");

 function  getObjectFormFields(formSelector)
        {
            /// <summary>Função que retorna objeto com base nas propriedades name dos elementos do formulário.</summary>
            /// <param name="formSelector" type="String">Seletor do formulário</param>

            var form = $(formSelector);

            var result = {};
            var arrayAuxiliar = [];
            form.find(":input:text").each(function (index, element)
            {
                var name = $(element).attr('name');

                var value = $(element).val();
                result[name] = value;
            });

            form.find(":input[type=hidden]").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });


            form.find(":input:checked").each(function (index, element)
            {
                var name;
                var value;
                if ($(this).attr("type") == "radio")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    result[name] = value;
                }
                else if ($(this).attr("type") == "checkbox")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    if (result[name])
                    {
                        if (Array.isArray(result[name]))
                        {
                            result[name].push(value);
                        } else
                        {
                            var aux = result[name];
                            result[name] = [];
                            result[name].push(aux);
                            result[name].push(value);
                        }

                    } else
                    {
                        result[name] = [];
                        result[name].push(value);
                    }
                }

            });

            form.find("select option:selected").each(function (index, element)
            {
                var name = $(element).parent().attr('name');
                var value = $(element).val();
                result[name] = value;

            });

            arrayAuxiliar = [];
            form.find("checkbox:checked").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = arrayAuxiliar.push(value);
            });

            form.find("textarea").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });

            return result;
        }


2
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными в случае изменения связанной страницы. - Из обзора
Wahyu Kristianto

Но эта ссылка имеет функцию помощи своему (я думаю). Но я собираюсь поставить код в следующий раз.
Маркос Коста

3

Я написал библиотеку для решения этой самой проблемы: JSONForms . Он принимает форму, проходит через каждый ввод и создает объект JSON, который вы можете легко прочитать.

Скажем, у вас есть следующая форма:

<form enctype='application/json'>
  <input name='places[0][city]' value='New York City'>
  <input type='number' name='places[0][population]' value='8175133'>
  <input name='places[1][city]' value='Los Angeles'>
  <input type='number' name='places[1][population]' value='3792621'>
  <input name='places[2][city]' value='Chicago'>
  <input type='number' name='places[2][population]' value='2695598'>
</form>

Передача формы в метод кодирования JSONForms возвращает вам следующий объект:

{
  "places": [
    {
      "city": "New York City",
      "population": 8175133
    },
    {
      "city": "Los Angeles",
      "population": 3792621
    },
    {
      "city": "Chicago",
      "population": 2695598
    }
  ]
}

Вот демонстрация с вашей формой.


Выглядит и работает хорошо, спасибо. Только одна вещь, минимизированная версия вызывает файл карты, должна быть необязательной.
adi518

2

$( "form" ).bind( "submit", function(e) {
    e.preventDefault();
    
    console.log(  $(this).serializeObject() );    

    //console.log(  $(this).serialize() );
    //console.log(  $(this).serializeArray() );

});


$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();

    $.each( a, function() {
        if ( o[this.name] !== undefined) 
        {
            if ( ! o[this.name].push ) 
            {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        }
        else 
        {
            o[this.name] = this.value || '';
        }
    });

    return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<form>

    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />

    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
    </select>

    <input type="submit" value="Submit" />

</form>

Codepen


2

Для тех из вас, кто предпочел бы, Objectа не сериализованную строку (например, возвращаемую $(form).serialize()и с небольшим улучшением $(form).serializeArray()), не стесняйтесь использовать код ниже:

var Form = {
    _form: null,
    _validate: function(){
        if(!this._form || this._form.tagName.toLowerCase() !== "form") return false;
        if(!this._form.elements.length) return false;
    }, _loopFields: function(callback){
        var elements = this._form.elements;
        for(var i = 0; i < elements.length; i++){
            var element = form.elements[i];
            if(name !== ""){
                callback(this._valueOfField(element));
            }
        }
    }, _valueOfField: function(element){
        var type = element.type;
        var name = element.name.trim();
        var nodeName = element.nodeName.toLowerCase();
        switch(nodeName){
            case "input":
                if(type === "radio" || type === "checkbox"){
                    if(element.checked){
                        return element.value;
                    }
                }
                return element.value;
                break;
            case "select":
                if(type === "select-multiple"){
                    for(var i = 0; i < element.options.length; i++){
                        if(options[i].selected){
                            return element.value;
                        }
                    }
                }
                return element.value;
                break;
            case "button":
                switch(type){
                    case "reset": 
                    case "submit": 
                    case "button":
                        return element.value;
                        break;
                }
                break;
        } 
    }, serialize: function(form){
        var data = {};
        this._form = form;

        if(this._validate()){
            this._loopFields(function(value){
                if(value !== null) data[name] = value;
            });
        }
        return data;
    }
};

Чтобы выполнить его, просто используйте, Form.serialize(form)и функция вернет нечто Objectподобное:

<!-- { username: "username", password: "password" } !-->
<input type="text" value="username">
<input type="password" value="password">

В качестве бонуса это означает, что вам не нужно устанавливать весь пакет jQuery только для одной функции сериализации.


1

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

function getFormData(formId) {
    return $('#' + formId).serializeArray().reduce(function (obj, item) {
        var name = item.name,
            value = item.value;

        if (obj.hasOwnProperty(name)) {
            if (typeof obj[name] == "string") {
                obj[name] = [obj[name]];
                obj[name].push(value);
            } else {
                obj[name].push(value);
            }
        } else {
            obj[name] = value;
        }
        return obj;
    }, {});
}

1

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

<form id="imageUploadForm"   action="" method="post" enctype="multipart/form-data">
<input type="text" class="form-control" id="fname" name='fname' placeholder="First Name" >
<input type="text" class="form-control" name='lname' id="lname" placeholder="Last Name">
<input type="number" name='phoneno'  class="form-control" id="phoneno" placeholder="Phone Number">
<textarea class="form-control" name='address' id="address" rows="5" cols="5" placeholder="Your Address"></textarea>
<input type="file" name="file" id="file" >
<input type="submit" id="sub" value="Registration">					   
</form>
на странице кнопки Отправить отправит запрос ajax в ваш файл php.
$('#imageUploadForm').on('submit',(function(e) 
{
     fname = $('#fname').val();
     lname =  $('#lname').val();
     address =  $('#address').val();
     phoneno =  $('#phoneno').val();
     file =  $('#file').val();
     e.preventDefault();
     var formData = new FormData(this);
     formData.append('file', $('#file')[0]);
     formData.append('fname',$('#fname').val());
     formData.append('lname',$('#lname').val());
     formData.append('phoneno',$('#phoneno').val());
     formData.append('address',$('#address').val());
     $.ajax({
		type:'POST',
                url: "test.php",
                //url: '<?php echo base_url().'edit_profile/edit_profile2';?>',

                data:formData,
                cache:false,
                contentType: false,
                processData: false,
                success:function(data)
                {
                     alert('Data with file are submitted !');

                }

     });

}))


Зачем нужны новые FormData здесь?
Саху V Кумар

1
@VishalKumarSahu Я загружаю файл, поэтому для этого я использую formData.
Мохсин Шукат

1
$(form).serializeArray().reduce(function (obj, item) {
      if (obj[item.name]) {
           if ($.isArray(obj[item.name])) {
               obj[item.name].push(item.value);
           } else {
                var previousValue = obj[item.name];
                obj[item.name] = [previousValue, item.value];
           }
      } else {
           obj[item.name] = item.value;
      }

     return obj;
}, {});

Это решит проблему: не мог работать с множественным выбором.


0

Вы все не совсем правы. Вы не можете написать:

formObj[input.name] = input.value;

Потому что таким образом, если у вас есть список множественного выбора - его значения будут перезаписаны последним, поскольку он передается как: «param1»: «value1», «param1»: «value2».

Итак, правильный подход это:

if (formData[input.name] === undefined) {
    formData[input.name] = input.value;
}
else {
    var inputFieldArray = $.merge([], $.isArray(formData[input.name]) ? formData[input.name] : [formData[input.name]]);
    $.merge(inputFieldArray, [input.value]);
    formData[input.name] = $.merge([], inputFieldArray);
}

0

Этот метод должен сделать это. Он сериализует данные формы, а затем преобразует их в объект. Также заботится о группах флажков.

function getFormObj(formId) {
  var formParams = {};
  $('#' + formId)
    .serializeArray()
    .forEach(function(item) {
      if (formParams[item.name]) {
        formParams[item.name] = [formParams[item.name]];
        formParams[item.name].push(item.value)
      } else {
        formParams[item.name] = item.value
      }
    });
  return formParams;
}

Работает для флажков, но не для переключателей, где элементы управления имеют общий nameатрибут.
Кайл Фалконер,

0

Вот хорошая ванильная JS-функция, которую я написал для извлечения данных формы в виде объекта. Также есть опции для вставки дополнений в объект и для очистки полей ввода формы.

const extractFormData = ({ form, clear, add }) => {
  return [].slice.call(form.children).filter(node => node.nodeName === 'INPUT')
  .reduce((formData, input) => {
    const value = input.value
    if (clear) { input.value = '' }
    return {
      ...formData,
      [input.name]: value
    }
  }, add)
}

Вот пример его использования с почтовым запросом:

submitGrudge(e) {
  e.preventDefault()

  const form = e.target
  const add = { id: Date.now(), forgiven: false }
  const grudge = extractFormData({ form, add, clear: true })

  // grudge = {
  //  "name": "Example name",
  //  "offense": "Example string",
  //  "date": "2017-02-16",
  //  "id": 1487877281983,
  //  "forgiven": false
  // }

  fetch('http://localhost:3001/api/grudge', {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(grudge)
  })
    .then(response => response.json())
    .then(grudges => this.setState({ grudges }))
    .catch(err => console.log('error: ', err))
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.