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