Sim*_*one 40 html javascript forms html5 form-data
我只是在寻找一种方式来获得所有的值从<form>
.
我在网上搜索了一会儿,磕磕绊绊FormData
,这似乎正是我正在寻找的.
但是它的API 在任何浏览器上都不可用,所以我需要一个替代方案.
在我的具体情况下我需要的是键/值对的对象.例如:
<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>
Run Code Online (Sandbox Code Playgroud)
对象应该是:
{
firstname: "John",
surname: "doe",
email: "",
gender: ""
}
Run Code Online (Sandbox Code Playgroud)
编辑:上面只是一个例子,它不仅应该<input>
与其他标签一起工作(例如<select>
,<textarea>
等等......甚至<input type="file">
应该支持).
zzz*_*Bov 21
如果没有对边缘情况应该发生什么的强烈定义,以及需要什么级别的浏览器支持,那么很难给出一个完美的问题答案.
有很多表单行为容易被遗漏,这就是为什么我建议使用库中维护良好的函数,例如jQueryserializeArray()
:
$('form').serializeArray();
Run Code Online (Sandbox Code Playgroud)
我知道最近有一个很大的推动,摆脱不必要的包括jQuery,所以对那些对vanilla JS解决方案感兴趣的人serializeArray
不会这样做.
下一个困难来自于确定需要什么级别的浏览器支持.HTMLFormElement.elements
显着地简化了序列化实现,并且在没有它的情况下选择与表单相关的元素是非常痛苦的.
考虑:
<form id="example">...</form>
<input type="text" form="example" name="lorem" value="ipsum"/>
Run Code Online (Sandbox Code Playgroud)
符合要求的实现需要包含该input
元素.我将假设我可以使用它,并将其作为练习留给阅读器.
之后,不清楚<input type="file"/>
应该如何支持.我并不热衷于不必要地将文件元素序列化为字符串,所以我假设序列化将是输入的名称和值,即使该值实际上是无用的.
最后,输入结构:
{
'input name': 'value',
'textarea name': 'value'
}
Run Code Online (Sandbox Code Playgroud)
过于天真,因为它没有考虑<select multiple>
元素,或两个输入具有相同名称的情况.我已经假设输入会更好:
[
{
name: 'input name',
value: 'value'
},
{
name: 'textarea name',
value: 'value'
}
]
Run Code Online (Sandbox Code Playgroud)
......并再次将其转化为不同的结构,作为读者的练习.
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));
Run Code Online (Sandbox Code Playgroud)
你可以采用手动方式(虽然下面的代码没有经过测试);
var form = document.getElementsByTagName("form");
var inputs = form[0].getElementsByTagName("input");
var formData = {};
for(var i=0; i< inputs.length; i++){
formData[inputs[i].name] = inputs[i].value;
}
var formdata = JSON.stringify(formData);
Run Code Online (Sandbox Code Playgroud)
如果您使用库,这将更容易.例如: - 在jQuery中:
var formObjects = $("form :input");
formObjects.each(
function(){
formData[$(this).attr("name")] = $(this).val(); /*setting up name/value pairs */
}
);
Run Code Online (Sandbox Code Playgroud)
在此代码中,formObjects包含所有输入,select和textarea 以及其他表单元素标记.所以我们不需要在普通的JS中手动搜索每个.除了单选按钮(因为@enhzflep暗示这对输入[type = radio]不正确)
但是如果你使用jQuery,你可以直接使用jQuery的serialize()函数通过名称 - 值对来获取整个表单.
var url_friendly_name_value_string = $("form").serialize();
Run Code Online (Sandbox Code Playgroud)