如何从HTML表单获取键/值数据集 [英] How to get a key/value data set from a HTML form
问题描述
我只是想从< form>
中寻找获取所有值的方法。
我在网上搜索了一段时间,徘徊在 FormData
,这看起来相当我正在寻找。
然而,它的API是在任何浏览器上都不可用,所以我需要一个替代方案。
在我的具体情况下,我需要的是键/值对的对象。例如:
< form>
< input type =textname =firstnamevalue =John/>
< input type =textname =surnamevalue =doe/>
< input type =emailname =emailvalue =/>
< input type =radioname =gendervalue =male/>
< input type =radioname =gendervalue =female/>
< / form>
对象应该是:
<$ p $ {
firstname:John,
surname:doe,
email:,
性别:
}
编辑:以上只是一个例子,只有< input>
,但也与其他标记(例如< select>
,< textarea>
等等...... even
如果没有关于边界情况应该发生什么的强烈定义,以及需要什么级别的浏览器支持,一个完美的答案。
有很多表单行为很容易被忽略,这就是为什么我建议在库中使用一个维护良好的函数,例如 jQuery的 serializeArray()
:
$('form')。serializeArray();
据我所知,最近有一个很大的推动,即不再需要包括jQuery,所以对于那些对香草JS解决方案感兴趣 serializeArray
就是不会这样做。下一个难题来自确定什么级别的浏览器支持是必需的。 HTMLFormElement.elements
大大简化了序列化的实现,并且在没有它的情况下选择与表单相关的元素是相当痛苦的。
< form id =example> ...< / form>
< input type =textform =examplename =loremvalue =ipsum/>
符合实现需要包含输入
元件。我会假设我可以使用它,并将其作为练习留给读者。
之后就不清楚<应该支持code>< input type =file/> 。我并不热衷于将文件元素不必要地序列化为字符串,所以我假定序列化将是输入的名称和值,即使这个值实际上是无用的。
最后,输入结构为:
{
'输入名称':'value' ,
'textarea name':'value'
}
过于幼稚因为它没有考虑< select multiple>
元素,或者两个输入具有相同名称的情况。我已经假设输入会更好,如下所示:
[
{
name: 'input name',
value:'value'
},
{
名称:'textarea name',
value:'value'
}
]
...然后再次将此变换为不同的结构读者。
给我一个codez!
<$ p ($)$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $
返回null;
//获取表单元素并将其转换为数组
返回slice.call(form.elements)
.filter(function(element) {
//删除禁用元素
return!element.disabled;
})。filter(function(element){
//删除未选中的复选框和单选按钮
return!/ ^ input $ / i.test(element.tagName)|| !/ ^(?:checkbox | radio)$ / i.test(element.type)|| element.checked;
})。filter(function(element){
//删除<选择多个>没有选定值的元素
return!/ ^ select $ / i.test(element.tagName) || element.selectedOptions.length> 0;
})。map(function(element){
switch(element.tagName.toLowerCase()){
case'checkbox':
case'radio':
return {
name:element.name,
value:element.value === null?'on':element.value
} ;
case'select':
if(element.multiple){
return {
name:element.name,
value:slice.call(element.selectedOptions )
.map(函数(选项){
返回option.value;
})
};
}
return {
name:element.name,
value:element.value
};
默认值:
返回{
名称:element.name,
value:element.value || ''
};
}
});
}
}(Array.prototype.slice));
I'm simply looking for a way to get all the values from a <form>
.
I searched the Web for a while, stumbling across FormData
, which seems quite what I'm looking for.
However its API is not available on any browser, so I need an alternative.
What I need in my specific case is an object of key/value pairs. For example:
<form>
<input type="text" name="firstname" value="John" />
<input type="text" name="surname" value="doe" />
<input type="email" name="email" value="" />
<input type="radio" name="gender" value="male" />
<input type="radio" name="gender" value="female" />
</form>
The object should be:
{
firstname: "John",
surname: "doe",
email: "",
gender: ""
}
Edit: The above is just an example, it should work not only with <input>
but also with the other tags (e.g. <select>
, <textarea>
and so on... even <input type="file">
should be supported).
Without a strong definition of what should happen with edge cases, and what level of browser support is required, it's difficult to give a single perfect answer to the question.
There are a lot of form behaviors that are easy to miss, which is why I recommend using a well-maintained function from a library, such as jQuery's serializeArray()
:
$('form').serializeArray();
I understand that there's a big push recently to move away from needlessly including jQuery, so for those who are interested in a vanilla JS solution serializeArray
just won't do.
The next difficulty comes from determining what level of browser support is required. HTMLFormElement.elements
significantly simplifies a serialization implementation, and selecting the form-associated elements without it is quite a pain.
Consider:
<form id="example">...</form>
<input type="text" form="example" name="lorem" value="ipsum"/>
A conforming implementation needs to include the input
element. I will assume that I can use it, and leave polyfilling it as an exercise to the reader.
After that it'd unclear how <input type="file"/>
should be supported. I'm not keen on needlessly serializing file elements into a string, so I've made the assumption that the serialization will be of the input's name and value, even though the value is practically useless.
Lastly, an input structure of:
{
'input name': 'value',
'textarea name': 'value'
}
Is excessively naive as it doesn't account for <select multiple>
elements, or cases where two inputs have the same name. I've made the assumption that the input would be better as:
[
{
name: 'input name',
value: 'value'
},
{
name: 'textarea name',
value: 'value'
}
]
...and again leave transforming this into a different structure as an exercise for the reader.
Give me teh codez already!
var serialize = (function (slice) {
return function (form) {
//no form, no serialization
if (form == null)
return null;
//get the form elements and convert to an array
return slice.call(form.elements)
.filter(function (element) {
//remove disabled elements
return !element.disabled;
}).filter(function (element) {
//remove unchecked checkboxes and radio buttons
return !/^input$/i.test(element.tagName) || !/^(?:checkbox|radio)$/i.test(element.type) || element.checked;
}).filter(function (element) {
//remove <select multiple> elements with no values selected
return !/^select$/i.test(element.tagName) || element.selectedOptions.length > 0;
}).map(function (element) {
switch (element.tagName.toLowerCase()) {
case 'checkbox':
case 'radio':
return {
name: element.name,
value: element.value === null ? 'on' : element.value
};
case 'select':
if (element.multiple) {
return {
name: element.name,
value: slice.call(element.selectedOptions)
.map(function (option) {
return option.value;
})
};
}
return {
name: element.name,
value: element.value
};
default:
return {
name: element.name,
value: element.value || ''
};
}
});
}
}(Array.prototype.slice));
这篇关于如何从HTML表单获取键/值数据集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!