Как я могу получить данные формы с помощью 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').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;
$("#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>