Ответ 1
$('form').serialize() //this produces: "foo=1&bar=xxx&this=hi"
Существует ли простой однострочный способ получения данных формы, как это было бы, если бы они были представлены классическим способом только для 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').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
Обновленный ответ за 2014 год: HTML5 FormData делает это
var formData = new FormData(document.querySelector('form'))
Затем вы можете отправить форму формы точно так, как она есть, - она содержит все имена и значения, используемые в форме.
На основе jQuery.serializeArray
возвращает пары ключ-значение.
var data = $('#form').serializeArray().reduce(function(obj, item) {
obj[item.name] = item.value;
return obj;
}, {});
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
});
Это нерешительный ответ, но позвольте мне объяснить, почему это лучшее решение:
Мы правильно обрабатываем форму submit, а не кнопку. Некоторым людям нравится нажимать на поля. Некоторые люди используют альтернативные устройства ввода, такие как речевой ввод или другие устройства доступности. Обращайтесь с формой 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;
}
Здесь действительно простой и короткий сототон, который даже не требует 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();
Я использую это:
Плагин 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 input, #form select, #form textarea").each(function() {
data[theFieldName] = theFieldValue;
});
кроме этого, вы можете посмотреть serialize();
Вот рабочая реализация только для 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>
Если вы используете 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 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"
}
Это 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());
хотя имейте в виду, что это не будет работать с дублирующимися ключами, как вы получаете из множественных и дубликатов флажков с тем же именем.
Вы также можете использовать объекты FormData; Объект FormData позволяет вам скомпилировать набор пар ключ/значение для отправки с использованием XMLHttpRequest. Он в первую очередь предназначен для использования при отправке данных формы, но может использоваться независимо от форм для передачи ключевых данных.
var formElement = document.getElementById("myform_id");
var formData = new FormData(formElement);
console.log(formData);
Я включил ответ, чтобы также вернуть требуемый объект.
function getFormData(form) {
var rawJson = form.serializeArray();
var model = {};
$.map(rawJson, function (n, i) {
model[n['name']] = n['value'];
});
return model;
}
Это добавит все поля формы к объекту JavaScript "res":
var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
res[obj.name] = $(obj).val();
})
var formData = new FormData($('#form-id'));
params = $('#form-id').serializeArray();
$.each(params, function(i, val) {
formData.append(val.name, val.value);
});
вы можете использовать эту функцию для получения объекта или JSON из формы.
для использования:
var object = formService.getObjectFormFields("#idform");
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, который получает данные формы в парах ключ-значение, но работает для множественного выбора и для входных данных массива с именем = '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 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>
Я написал библиотеку для решения этой самой проблемы: 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).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>
Вы все не совсем правы. Вы не можете писать:
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);
}
Этот метод должен это сделать. Он сериализует данные формы, а затем преобразует их в объект. Также заботится о группах флажков.
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;
}
Вот хорошая функция JS Vanilla, которую я написал, чтобы извлечь данные формы как объект. Он также имеет опции для вставки дополнений в объект и для очистки полей ввода формы.
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))
}