如何使用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>

输出:

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

像这样的东西太简单了,因为它没有(正确地)包括文本区域,选择,单选按钮和复选框:

$("#form input").each(function () {
data[theFieldName] = theFieldValue;
});
1188902 次浏览
$("#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>
提交按钮页面将发送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 !');


}


});


}))

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

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

  • 我们正在正确地处理表单提交,而不是按下按钮。有些人喜欢按回车键。有些人使用替代输入设备,如语音输入或其他辅助设备。处理表单提交,并为每个人正确地解决它。

  • 我们正在挖掘提交的实际表单的表单数据。如果稍后更改表单选择器,则不必更改所有字段的选择器。此外,您可能有几个具有相同输入名称的表单。不需要使用过多的id来消除歧义,只需根据提交的表单跟踪输入。这还允许您对多个表单(如果适合您的情况)使用单个事件处理程序。

  • FormData接口相当新,但是浏览器很支持它。这是构建数据集合以获得表单中内容的真实值的好方法。如果没有它,你将不得不遍历所有元素(例如form.elements),并找出检查了什么,没有检查什么,值是什么等等。如果您需要老式的浏览器支持,完全可以,但是FormData接口更简单。

  • 我在这里使用ES6…无论如何都不是必须的,所以如果你需要旧的浏览器支持,就把它改回与ES5兼容。

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

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>

< a href = " https://codepen。io/ antlove /pen/ZEEJjyX" rel="nofollow noreferrer"> code depen .

对于那些更喜欢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),函数将返回类似于下面的Object:

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

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

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

适用于:

  • name =“input"
  • name =“形式[名字]“;(创建对象)
  • []“name =“复选框;(用数组创建对象)
  • name =“形式(复选框)[]“;(创建一个数组)
  • 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>