如何从HTML表单中获取键/值数据集

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)

......并再次将其转化为不同的结构,作为读者的练习.


给我teh codez吧!

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)


sha*_*han 7

你可以采用手动方式(虽然下面的代码没有经过测试);

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)

  • 对于它的价值 - 这不适用于无线电按钮. (2认同)