Ajax Requests Many developers who learned web development through…
JQuery: 提交表单数据,转换表单数据为json,values of Form to Json (jquery.serializeJSON)
项目:https://github.com/marioizquierdo/jquery.serializeJSON
下载:jquery.serializeJSON-master
jquery.serializeJSON
前端在处理含有大量数据提交的表单时,除了使用Form直接提交刷新页面之外,经常碰到的需求是收集表单信息成数据对象,Ajax提交。
而在处理复杂的表单时,需要一个一个区手动判断处理字段值,显得非常麻烦。接下来介绍的插件将解决这个问题。
使用jquery.serializeJSON
,可以在基于jQuery或者Zepto的页面中,调用 .serializeJSON()
方法来序列化form表单的数据成JS对象。
安装
Install with bower bower install jquery.serializeJSON
, or npm npm install jquery-serializejson
, or just download the jquery.serializejson.js script.
下载:https://github.com/marioizquierdo/jquery.serializeJSON
只需要在jQuery或者Zepto时候引入即可
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="jquery.serializejson.js"></script>
用法
HTML form (input, textarea and select tags supported):
<form id="my-profile"> <!-- simple attribute --> <input type="text" name="fullName" value="Mario Izquierdo" /> <!-- nested attributes --> <input type="text" name="address[city]" value="San Francisco" /> <input type="text" name="address[state][name]" value="California" /> <input type="text" name="address[state][abbr]" value="CA" /> <!-- array --> <input type="text" name="jobbies[]" value="code" /> <input type="text" name="jobbies[]" value="climbing" /> <!-- textareas, checkboxes ... --> <textarea name="projects[0][name]">serializeJSON</textarea> <textarea name="projects[0][language]">javascript</textarea> <input type="hidden" name="projects[0][popular]" value="0" /> <input type="checkbox" name="projects[0][popular]" value="1" checked /> <textarea name="projects[1][name]">tinytest.js</textarea> <textarea name="projects[1][language]">javascript</textarea> <input type="hidden" name="projects[1][popular]" value="0" /> <input type="checkbox" name="projects[1][popular]" value="1"/> <!-- select --> <select name="selectOne"> <option value="paper">Paper</option> <option value="rock" selected>Rock</option> <option value="scissors">Scissors</option> </select> <!-- select multiple options, just name it as an array[] --> <select multiple name="selectMultiple[]"> <option value="red" selected>Red</option> <option value="blue" selected>Blue</option> <option value="yellow">Yellow</option> </select> </form>
JavaScript:
$('#my-profile').serializeJSON(); // returns => { fullName: "Mario Izquierdo", address: { city: "San Francisco", state: { name: "California", abbr: "CA" } }, jobbies: ["code", "climbing"], projects: { '0': { name: "serializeJSON", language: "javascript", popular: "1" }, '1': { name: "tinytest.js", language: "javascript", popular: "0" } }, selectOne: "rock", selectMultiple: ["red", "blue"] }
The serializeJSON
function returns a JavaScript object, not a JSON String. It should probably have been called serializeObject
, or something like that, but those names were already taken.
To serialize into JSON, use the JSON.stringify
method, that is available on all major new browsers. To support old browsers, just include the json2.js polyfill (as described on stackoverfow).
serializeJSON
方法返回一个JS对象,并非JSON字符串。可以使用 JSON.stringify
转换成字符串(注意IE8兼容性)。
var jsonString = JSON.stringify(obj);
Note that .serializeJSON()
implememtation relies on jQuery’s .serializeArray() to grab the form attributes and then create the object using the names. That means, it will serialize the inputs that are supported by .serializeArray()
, that uses the standard W3C rules for successful controls to determine which elements it should include. In particular, the included elements cannot be disabled and must contain a name attribute. No submit button value is serialized since the form was not submitted using a button. And data from file select elements is not serialized.
指定数据类型 Parse values with :types
获取到的属性值一般是字符串,可以通过HTML指定类型 : type 进行强制转换。
<form> <input type="text" name="deftype" value=":string is the default (implicit) type"/> <input type="text" name="text:string" value=":string type can still be used to overrid other parsing options"/> <input type="text" name="excluded:skip" value="Use :skip to not include this field in the result"/> <input type="text" name="numbers[1]:number" value="1"/> <input type="text" name="numbers[1.1]:number" value="1.1"/> <input type="text" name="numbers[other stuff]:number" value="other stuff"/> <input type="text" name="bools[true]:boolean" value="true"/> <input type="text" name="bools[false]:boolean" value="false"/> <input type="text" name="bools[0]:boolean" value="0"/> <input type="text" name="nulls[null]:null" value="null"/> <input type="text" name="nulls[other stuff]:null" value="other stuff"/> <input type="text" name="autos[string]:auto" value="text with stuff"/> <input type="text" name="autos[0]:auto" value="0"/> <input type="text" name="autos[1]:auto" value="1"/> <input type="text" name="autos[true]:auto" value="true"/> <input type="text" name="autos[false]:auto" value="false"/> <input type="text" name="autos[null]:auto" value="null"/> <input type="text" name="autos[list]:auto" value="[1, 2, 3]"/> <input type="text" name="arrays[empty]:array" value="[]"/> <input type="text" name="arrays[list]:array" value="[1, 2, 3]"/> <input type="text" name="objects[empty]:object" value="{}"/> <input type="text" name="objects[dict]:object" value='{"my": "stuff"}'/> </form>
$('form').serializeJSON(); // returns => { "deftype": "default type is :string", "text": ":string type overrides parsing options", // excluded:skip is not included in the output "numbers": { "1": 1, "1.1": 1.1, "other stuff": NaN, // <-- Other stuff parses as NaN (Not a Number) }, "bools": { "true": true, "false": false, "0": false, // <-- "false", "null", "undefined", "", "0" parse as false }, "nulls": { "null": null, // <-- "false", "null", "undefined", "", "0" parse as null "other stuff": "other stuff" }, "autos": { // works as the parseAll option "string": "text with stuff", "0": 0, // <-- parsed as number "1": 1, // <-- parsed as number "true": true, // <-- parsed as boolean "false": false, // <-- parsed as boolean "null": null, // <-- parsed as null "list": "[1, 2, 3]" // <-- array and object types are not auto-parsed }, "arrays": { // <-- works using JSON.parse "empty": [], "not empty": [1,2,3] }, "objects": { // <-- works using JSON.parse "empty": {}, "not empty": {"my": "stuff"} } }
数据类型也可以指定在 data-value-type
属性中,代替 :type
标记。
<form> <input type="text" name="anumb" data-value-type="number" value="1"/> <input type="text" name="abool" data-value-type="boolean" value="true"/> <input type="text" name="anull" data-value-type="null" value="null"/> <input type="text" name="anauto" data-value-type="auto" value="0"/> </form>
Options配置
默认配置
- Values始终为字符串(除非在
input names
使用:types
) Keys
始终为字符串(默认不自动检测是否需要转换为数组)- 未选择的
checkboxes
会被忽略 disabled
的elements
会被忽略
自定义配置
写法 | 释义 |
---|---|
checkboxUncheckedValue: string | 针对未勾选的checkboxes,设定值 |
parseBooleans: true | 自动检测转换”true”、”false”为布尔值true、false |
parseNumbers: true | 自动检测转换”1″、”33.33″、”-44″为数字1、33.33、-44 |
parseNulls: true | 自动检测字符串”null”为null |
parseAll: true | 自动检测转换以上类型的字符串 |
parseWithFunction: function | 自定义转换函数 function(value, name){return parsedValue} |
customTypes: {} | 自定义:types覆盖默认types,如{type: function(value){…}} |
defaultTypes: {defaultTypes} | 重新定义所有的:types,如{type: function(value){…}} |
useIntKeysAsArrayIndex: true | 当keys为整数时,将序列化为数组 |
For convenience, you can change the default behavior with:
- checkboxUncheckedValue: string, Use this value for unchecked checkboxes, instead of ignoring them. Make sure to use a String. If the value needs to be parsed (i.e. to a Boolean) use a parse option (i.e.
parseBooleans: true
). - parseBooleans: true, automatically detect and convert strings
"true"
and"false"
to booleanstrue
andfalse
. - parseNumbers: true, automatically detect and convert strings like
"1"
,"33.33"
,"-44"
to numbers like1
,33.33
,-44
. - parseNulls: true, automatically detect and convert the string
"null"
to the null valuenull
. - parseAll: true, all of the above. This is the same as if the default :type was
:auto
instead of:string
. - parseWithFunction: function, define your own parse function(inputValue, inputName) { return parsedValue }
- skipFalsyValuesForFields: [], skip fields with given names and falsy values. You can use
data-skip-falsy="true"
input attribute as well. Falsy values are determined after converting to a given type, note that"0"
as :string is truthy, but0
as :number is falsy. - skipFalsyValuesForTypes: [], skip fields with given types and falsy values (i.e.
skipFalsyValuesForTypes: ["string", "number"]
would skip""
for:string
fields, and0
for:number
fields). - customTypes: {}, define your own :types or override the default types. Defined as an object like
{ type: function(value){...} }
- defaultTypes: {defaultTypes}, in case you want to re-define all the :types. Defined as an object like
{ type: function(value){...} }
- useIntKeysAsArrayIndex: true, when using integers as keys (i.e.
<input name="foods[0]" value="banana">
), serialize as an array ({"foods": ["banana"]}
) instead of an object ({"foods": {"0": "banana"}
).
More info about options usage in the sections below.
包含未勾选的checkboxes
serializeJSON 支持 checkboxUncheckedValue
配置,或者可以在checkboxes
添加 data-unchecked-value
属性。
<!-- Only one booleanAttr will be serialized, being "true" or "false" depending if the checkbox is selected or not --> <input type="hidden" name="booleanAttr" value="false" /> <input type="checkbox" name="booleanAttr" value="true" />
This solution is somehow verbose, but it is unobtrusive and ensures progressive enhancement, because it is the standard HTML behavior (also works without JavaScript).
But, to make things easier, serializeJSON
includes the option checkboxUncheckedValue
and the possibility to add the attribute data-unchecked-value
to the checkboxes.
For example:
<form> <input type="checkbox" name="check1" value="true" checked/> <input type="checkbox" name="check2" value="true"/> <input type="checkbox" name="check3" value="true"/> </form>
默认方法:
$('form').serializeJSON(); // returns => {'check1': 'true'} // Note that check2 and check3 are not included because they are not checked
上面的写法会忽略未勾选的复选框。如果需要包含,则可以使用以下方法:
1. 配置checkboxUncheckedValue
$('form').serializeJSON({checkboxUncheckedValue: "false"}); // returns => {'check1': 'true', check2: 'false', check3: 'false'}
2. 添加data-unchecked-value
属性
<form id="checkboxes"> <input type="checkbox" name="checked[bool]" value="true" data-unchecked-value="false" checked/> <input type="checkbox" name="checked[bin]" value="1" data-unchecked-value="0" checked/> <input type="checkbox" name="checked[cool]" value="YUP" checked/> <input type="checkbox" name="unchecked[bool]" value="true" data-unchecked-value="false" /> <input type="checkbox" name="unchecked[bin]" value="1" data-unchecked-value="0" /> <input type="checkbox" name="unchecked[cool]" value="YUP" /> <!-- No unchecked value specified --> </form>
Serializes like this by default:
$('form#checkboxes').serializeJSON(); // Note no option is used // returns => { 'checked': { 'bool': 'true', 'bin': '1', 'cool': 'YUP' }, 'unchecked': { 'bool': 'false', 'bin': '0' // Note that unchecked cool does not appear, because it doesn't use data-unchecked-value } }
You can use both the option checkboxUncheckedValue
and the attribute data-unchecked-value
at the same time, in which case the attribute has precedence over the option. And remember that you can combine it with other options to parse values as well.
$('form#checkboxes').serializeJSON({checkboxUncheckedValue: 'NOPE', parseBooleans: true, parseNumbers: true}); // returns => { 'checked': { 'bool': true, 'bin': 1, 'cool': 'YUP' }, 'unchecked': { 'bool': false, // value from data-unchecked-value attribute, and parsed with parseBooleans 'bin': 0, // value from data-unchecked-value attribute, and parsed with parseNumbers 'cool': 'NOPE' // value from checkboxUncheckedValue option } }
自动检测转换类型
默认的类型为字符串 :string
,可以通过配置转换为其它类型
$('form').serializeJSON({parseNulls: true, parseNumbers: true}); // returns => { "bool": { "true": "true", // booleans are still strings, because parseBooleans was not set "false": "false", } "number": { "0": 0, // numbers are parsed because parseNumbers: true "1": 1, "2.2": 2.2, "-2.25": -2.25, } "null": null, // "null" strings are converted to null becase parseNulls: true "string": "text is always string", "empty": "" }
在极少数情况下,可以使用自定义转换函数
var emptyStringsAndZerosToNulls = function(val, inputName) { if (val === "") return null; // parse empty strings as nulls if (val === 0) return null; // parse 0 as null return val; } $('form').serializeJSON({parseWithFunction: emptyStringsAndZerosToNulls, parseNumbers: true}); // returns => { "bool": { "true": "true", "false": "false", } "number": { "0": null, // <-- parsed with custom function "1": 1, "2.2": 2.2, "-2.25": -2.25, } "null": "null", "string": "text is always string", "empty": null // <-- parsed with custom function }
自定义类型
可以使用 customTypes
配置自定义类型或者覆盖默认类型($.serializeJSON.defaultOptions.defaultTypes
)
<form> <input type="text" name="scary:alwaysBoo" value="not boo"/> <input type="text" name="str:string" value="str"/> <input type="text" name="number:number" value="5"/> </form>
JS
$('form').serializeJSON({ customTypes: { alwaysBoo: function(str) { // value is always a string return "boo"; }, string: function(str) { // all strings will now end with " override" return str + " override"; } } }); // returns => { "scary": "boo", // <-- parsed with type :alwaysBoo "str": "str override", // <-- parsed with new type :string (instead of the default) "number": 5, // <-- the default :number still works }
忽略空表单字段
// Select only imputs that have a non-empty value $('form :input[value!=""]').serializeJSON(); // Or filter them from the form obj = $('form').find('input').not('[value=""]').serializeJSON(); // For more complicated filtering, you can use a function obj = $form.find(':input').filter(function () { return $.trim(this.value).length > 0 }).serializeJSON();
使用整数keys作为数组的顺序
使用useIntKeyAsArrayIndex
配置
<form> <input type="text" name="arr[0]" value="foo"/> <input type="text" name="arr[1]" value="var"/> <input type="text" name="arr[5]" value="inn"/> </form>
按照默认的方法,结果为:
$('form').serializeJSON(); // returns => {'arr': {'0': 'foo', '1': 'var', '5': 'inn' }}
使用useIntKeyAsArrayIndex
可以将记过转换为数组并制定顺序
$('form').serializeJSON({useIntKeysAsArrayIndex: true}); // returns => {'arr': ['foo', 'var', undefined, undefined, undefined, 'inn']}
默认配置Defaults
所有的默认配置均定义在 $.serializeJSON.defaultOptions
,可以进行修改。
$.serializeJSON.defaultOptions.parseAll = true; // parse booleans, numbers and nulls by default $('form').serializeJSON(); // No options => then use $.serializeJSON.defaultOptions // returns => { "bool": { "true": true, "false": false, } "number": { "0": 0, "1": 1, "2.2": 2.2, "-2.25": -2.25, } "null": null, "string": "text is always string", "empty": "" }
总结
这个插件支持的配置非常丰富,自定义程度很高,带来很大的便捷性。
更多参考:jquery.serializeJSON: 包含未勾选的checkboxes, Problem with checkbox checked,
本文:JQuery: 提交表单数据,转换表单数据为json,values of Form to Json (jquery.serializeJSON)