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

есть ли простой, однострочный способ получить данные формы, как это было бы, если бы он должен был быть представлен в классическом 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>

Out:

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

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

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

25 ответов


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

демо


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

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

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

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

посмотри это демо jsfiddle


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

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

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

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

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


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
});

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

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

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

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

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


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

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

вот очень простой и короткий soluton, который даже не требует 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;

$('#myform').serialize();

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

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


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

плагин 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();

вот рабочая реализация только 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>

edit:

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


Если вы используете 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"
}

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

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

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

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

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

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

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;
}

можно использовать эта функция для иметь объект или 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;
        }

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

formObj[input.name] = input.value;

потому что таким образом, если у вас есть список multiselect - его значения будут перезаписаны последним, так как он передается как: "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);
}

Я написал библиотеку, чтобы решить данную проблему: 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
    }
  ]
}

здесь демо С вашу форму.


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

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;
    }, {});
}

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

<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 !');

                }

     });

}))

$(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;
}, {});

это исправит проблему: не удалось работать с multiselects.


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

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;
}

вот хорошая функция vanilla 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)
}

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

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))
}

<form id="my-form">
    <div>
        <label for="name">Name:</label>
        <input type="text" id="name" name="user_name">
    </div>
    <div>
        <label for="mail">E-mail:</label>
        <input type="email" id="mail" name="user_mail">
    </div>
    <div>
        <label for="msg">Message:</label>
        <textarea id="msg" name="user_message"></textarea>
    </div>
    <div>
        <label for="gender">Gender:</label>
        <select name="gender" id="gender">
            <option value="male">Male</option>
            <option value="female">Female</option>
        </select>
    </div>
    <div>
        <label for="terms">Accept terms:</label>
        <input type="checkbox" id="terms" name="terms">
    </div>
    <div class="button">
        <button type="submit">Send your message</button>
    </div>
</form>

<script>
    document.getElementById('my-form')
            .addEventListener('submit', e => {
              e.preventDefault()
              let fields = e.target.querySelectorAll('input,textarea,select')
              let cbs = e.target.querySelectorAll('input[type=checkbox]')
              let values = {}
              fields.forEach(e => {
                values[e.name] = e.value
              })
              cbs.forEach(e => {
                values[e.name] = e.checked
              })
              console.log(values)
        })
</script>