是否有一种简单的单行方式来获取表单的数据,就像以经典的仅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;
});

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

除此之外,你可能想看看serialize();


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

demo


使用$('form').serializeArray(),它返回一个数组:

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

另一个选项是$('form').serialize(),它返回一个字符串:

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

看看这个jsfiddle演示


这将把所有表单字段附加到JavaScript对象“res”:

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

使用.serializeArray()获取数组格式的数据,然后将其转换为对象:

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

基于jQuery。serializeArray,返回键值对。

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

你们都不完全正确。你不能写:

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

这里有一个非常简单和简短的解决方案,甚至不需要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;

你也可以使用FormData对象;FormData对象允许您编译一组键/值对,以便使用XMLHttpRequest发送。它主要用于发送表单数据,但也可以独立于表单用于传输键控数据。

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

2014年的最新答案:HTML5 FormData做到了这一点

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

然后,您可以准确地发布formData——它包含表单中使用的所有名称和值。


这个方法应该可以做到。它序列化表单数据,然后将它们转换为对象。还可以处理复选框组。

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

我编写了一个库来解决这个问题: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的encode方法将返回以下对象:

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

下面是表单的演示。


如果您正在使用jQuery,这里有一个小函数可以做您正在寻找的事情。

首先,添加一个ID到你的表单(除非它是页面上唯一的表单,然后你可以只使用'form'作为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"
}

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

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

这里是一个工作的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>

编辑:

如果您正在寻找一个更完整的实现,那么请查看我为其制作的项目的这一部分。我最终会用我想出的完整解决方案来更新这个问题,但也许这对某人会有帮助。


你可以使用这个函数从表单中获取一个对象或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; }


我写了一个函数来处理多个复选框和多个选择。在这些情况下,它返回一个数组。

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

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

我用这个:

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

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

它将修复问题:无法与多选择工作。


显示表单输入元素字段和输入文件提交您的表单没有页面刷新和抓取所有值与文件包括在这里

<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> on Submit button page will send ajax request to your php file. $('#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 !'); } }); }))


这是一个很好的香草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))
}

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

这是一个吹毛求疵的答案,但让我解释为什么这是一个更好的解决方案:

We're properly handling a form submit rather than a button press. Some people like to push enter on fields. Some people use alternative input devices such as speech input or other accessibility devices. Handle the form submit and you correctly solve it for everyone. We're digging into the form data for the actual form that was submitted. If you change your form selector later, you don't have to change the selectors for all the fields. Furthermore, you might have several forms with the same input names. No need to disambiguate with excessive IDs and what not, just track the inputs based on the form that was submitted. This also enables you to use a single event handler for multiple forms if that is appropriate for your situation. The FormData interface is fairly new, but is well supported by browsers. It's a great way to build that data collection to get the real values of what's in the form. Without it, you're going to have to loop through all the elements (such as with form.elements) and figure out what's checked, what isn't, what the values are, etc. Totally possible if you need old browser support, but the FormData interface is simpler. I'm using ES6 here... not a requirement by any means, so change it back to be ES5 compatible if you need old browser support.


我已经包括答案,也给回所需的对象。

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

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

return model;
}

基于neuront的响应,我创建了一个简单的JQuery方法,在键值对中获取表单数据,但它适用于多选择和name='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>


现在是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());

尽管请注意,这将不适用于重复的键,如您从多选和重复的复选框具有相同的名称。


$( "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


对于那些更喜欢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;
        return true;
    }, _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),函数将返回一个类似于下面的对象:

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

作为奖励,这意味着您不必为了一个序列化函数而安装整个jQuery包。


这是我的香草JS版本(在Chrome上测试)

适用于:

name = "输入" Name ="form[Name]"(创建一个对象) Name ="checkbox[]"(创建一个数组对象) Name ="form[checkbox][]"(创建一个数组) Name ="form[select][Name]"(创建一个只包含所选值的对象)

/**
 * Get the values from a form
 * @param formId ( ID without the # )
 * @returns {object}
 */
function getFormValues( formId )
{
    let postData = {};
    let form = document.forms[formId];
    let formData = new FormData( form );

    for ( const value of formData.entries() )
    {
        let container = postData;
        let key = value[0];
        let arrayKeys = key.match( /\[[\w\-]*\]/g ); // Check for any arrays

        if ( arrayKeys !== null )
        {
            arrayKeys.unshift( key.substr( 0, key.search( /\[/ ) ) );  // prepend the first key to the list
            for ( let i = 0, count = arrayKeys.length, lastRun = count - 1; i < count; i++ )
            {
                let _key = arrayKeys[i];
                _key = _key.replace( "[", '' ).replace( "]", '' ); // Remove the brackets []
                if ( _key === '' )
                {
                    if ( ! Array.isArray( container ) )
                    {
                        container = [];
                    }

                    _key = container.length;
                }

                if ( ! (_key in container) ) // Create an object for the key if it doesn't exist
                {
                    if ( i !== lastRun && arrayKeys[i + 1] === '[]' )
                    {
                        container[_key] = [];
                    }
                    else
                    {
                        container[_key] = {};
                    }
                }

                if ( i !== lastRun ) // Until we're the last item, swap container with it's child
                {
                    container = container[_key];
                }

                key = _key;
            }
        }
        container[key] = value[1]; // finally assign the value
    }

    return postData;
}

最简单的方法是2022年。

document.querySelector('form').addEventListener('submit', (e) => {
  const data = Object.fromEntries(new FormData(e.target).entries());
  console.log(data)
});

输出

{ name: 'Stackoverflow' }

我有点惊讶,因为下面没有人提到解决方案。

通过document.forms.namedItem函数获取表单数据

var form = document.forms.namedItem("fileinfo");

form.addEventListener('submit', function(ev) {
   var oData = new FormData(form);
}

HT的

<form name="fileinfo">
  <label>Your email address:</label>
  <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
  <label>Custom file label:</label>
  <input type="text" name="filelabel" size="12" maxlength="32" /><br />
  <label>File to stash:</label>
  <input type="file" name="file" required />
  <input type="submit" value="Stash the file!" />
</form>
<div></div>