Gathering detailed insights and metrics for jquery-serializejson
Gathering detailed insights and metrics for jquery-serializejson
Gathering detailed insights and metrics for jquery-serializejson
Gathering detailed insights and metrics for jquery-serializejson
npm install jquery-serializejson
99.9
Supply Chain
100
Quality
75.9
Maintenance
100
Vulnerability
100
License
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
1,716 Stars
213 Commits
431 Forks
61 Watching
5 Branches
16 Contributors
Updated on 27 Nov 2024
JavaScript (97.47%)
CSS (1.86%)
HTML (0.67%)
Cumulative downloads
Total Downloads
Last day
8.8%
9,436
Compared to previous day
Last week
5.4%
57,857
Compared to previous week
Last month
3.9%
234,123
Compared to previous month
Last year
41.4%
2,264,091
Compared to previous year
1
Adds the method .serializeJSON()
to jQuery to serializes a form into a JavaScript Object. Supports the same format for nested parameters that is used in Ruby on Rails.
Install with bower bower install jquery.serializeJSON
, or npm npm install jquery-serializejson
, or just download the jquery.serializejson.js script.
And make sure it is included after jQuery, for example:
1<script type="text/javascript" src="jquery.js"></script> 2<script type="text/javascript" src="jquery.serializejson.js"></script>
HTML form:
1<form> 2 <input type="text" name="title" value="Dune"/> 3 <input type="text" name="author[name]" value="Frank Herbert"/> 4 <input type="text" name="author[period]" value="1945–1986"/> 5</form>
JavaScript:
1$('form').serializeJSON(); 2 3// returns => 4{ 5 title: "Dune", 6 author: { 7 name: "Frank Herbert", 8 period: "1945–1986" 9 } 10}
Nested attributes and arrays can be specified by naming fields with the syntax: name="attr[nested][nested]"
.
HTML form:
1<form id="my-profile"> 2 <!-- simple attribute --> 3 <input type="text" name="name" value="Mario" /> 4 5 <!-- nested attributes --> 6 <input type="text" name="address[city]" value="San Francisco" /> 7 <input type="text" name="address[state][name]" value="California" /> 8 <input type="text" name="address[state][abbr]" value="CA" /> 9 10 <!-- array --> 11 <input type="text" name="jobbies[]" value="code" /> 12 <input type="text" name="jobbies[]" value="climbing" /> 13 14 <!-- nested arrays, textareas, checkboxes ... --> 15 <textarea name="projects[0][name]">serializeJSON</textarea> 16 <textarea name="projects[0][language]">javascript</textarea> 17 <input type="hidden" name="projects[0][popular]" value="0" /> 18 <input type="checkbox" name="projects[0][popular]" value="1" checked /> 19 20 <textarea name="projects[1][name]">tinytest.js</textarea> 21 <textarea name="projects[1][language]">javascript</textarea> 22 <input type="hidden" name="projects[1][popular]" value="0" /> 23 <input type="checkbox" name="projects[1][popular]" value="1"/> 24 25 <!-- select --> 26 <select name="selectOne"> 27 <option value="paper">Paper</option> 28 <option value="rock" selected>Rock</option> 29 <option value="scissors">Scissors</option> 30 </select> 31 32 <!-- select multiple options, just name it as an array[] --> 33 <select multiple name="selectMultiple[]"> 34 <option value="red" selected>Red</option> 35 <option value="blue" selected>Blue</option> 36 <option value="yellow">Yellow</option> 37 </select> 38</form> 39
JavaScript:
1$('#my-profile').serializeJSON(); 2 3// returns => 4{ 5 fullName: "Mario", 6 7 address: { 8 city: "San Francisco", 9 state: { 10 name: "California", 11 abbr: "CA" 12 } 13 }, 14 15 jobbies: ["code", "climbing"], 16 17 projects: { 18 '0': { name: "serializeJSON", language: "javascript", popular: "1" }, 19 '1': { name: "tinytest.js", language: "javascript", popular: "0" } 20 }, 21 22 selectOne: "rock", 23 selectMultiple: ["red", "blue"] 24}
The serializeJSON
function returns a JavaScript object, not a JSON String. The plugin should probably have been called serializeObject
or similar, but that plugin name was already taken.
To convert into a JSON String, use the JSON.stringify
method, that is available on all major new browsers.
If you need to support very old browsers, just include the json2.js polyfill (as described on stackoverfow).
1var obj = $('form').serializeJSON(); 2var jsonString = JSON.stringify(obj);
The plugin serializes the same inputs supported by .serializeArray(), following the standard W3C rules for successful controls. 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.
Fields values are :string
by default. But can be parsed with types by appending a :type
suffix to the field name:
1<form> 2 <input type="text" name="default" value=":string is default"/> 3 <input type="text" name="text:string" value="some text string"/> 4 <input type="text" name="excluded:skip" value="ignored field because of type :skip"/> 5 6 <input type="text" name="numbers[1]:number" value="1"/> 7 <input type="text" name="numbers[1.1]:number" value="1.1"/> 8 <input type="text" name="numbers[other]:number" value="other"/> 9 10 <input type="text" name="bools[true]:boolean" value="true"/> 11 <input type="text" name="bools[false]:boolean" value="false"/> 12 <input type="text" name="bools[0]:boolean" value="0"/> 13 14 <input type="text" name="nulls[null]:null" value="null"/> 15 <input type="text" name="nulls[other]:null" value="other"/> 16 17 <input type="text" name="arrays[empty]:array" value="[]"/> 18 <input type="text" name="arrays[list]:array" value="[1, 2, 3]"/> 19 20 <input type="text" name="objects[empty]:object" value="{}"/> 21 <input type="text" name="objects[dict]:object" value='{"my": "stuff"}'/> 22</form>
1$('form').serializeJSON(); 2 3// returns => 4{ 5 "default": ":string is the default", 6 "text": "some text string", 7 // excluded:skip is ignored in the output 8 9 "numbers": { 10 "1": 1, 11 "1.1": 1.1, 12 "other": NaN, // <-- "other" is parsed as NaN 13 }, 14 "bools": { 15 "true": true, 16 "false": false, 17 "0": false, // <-- "false", "null", "undefined", "", "0" are parsed as false 18 }, 19 "nulls": { 20 "null": null, // <-- "false", "null", "undefined", "", "0" are parsed as null 21 "other": "other" // <-- if not null, the type is a string 22 }, 23 "arrays": { // <-- uses JSON.parse 24 "empty": [], 25 "not empty": [1,2,3] 26 }, 27 "objects": { // <-- uses JSON.parse 28 "empty": {}, 29 "not empty": {"my": "stuff"} 30 } 31}
Types can also be specified with the attribute data-value-type
, instead of adding the :type
suffix in the field name:
1<form> 2 <input type="text" name="anumb" data-value-type="number" value="1"/> 3 <input type="text" name="abool" data-value-type="boolean" value="true"/> 4 <input type="text" name="anull" data-value-type="null" value="null"/> 5 <input type="text" name="anarray" data-value-type="array" value="[1, 2, 3]"/> 6</form>
If your field names contain colons (e.g. name="article[my::key][active]"
) the last part after the colon will be confused as an invalid type. One way to avoid that is to explicitly append the type :string
(e.g. name="article[my::key][active]:string"
), or to use the attribute data-value-type="string"
. Data attributes have precedence over :type
name suffixes. It is also possible to disable parsing :type
suffixes with the option { disableColonTypes: true }
.
Use the customTypes
option to provide your own parsing functions. The parsing functions receive the input name as a string, and the DOM elment of the serialized input.
1<form> 2 <input type="text" name="scary:alwaysBoo" value="not boo"/> 3 <input type="text" name="str:string" value="str"/> 4 <input type="text" name="five:number" value="5"/> 5</form>
1$('form').serializeJSON({ 2 customTypes: { 3 alwaysBoo: (strVal, el) => { 4 // strVal: is the input value as a string 5 // el: is the dom element. $(el) would be the jQuery element 6 return "boo"; // value returned in the serialization of this type 7 }, 8 } 9}); 10 11// returns => 12{ 13 "scary": "boo", // <-- parsed with custom type "alwaysBoo" 14 "str": "str", 15 "five": 5, 16}
The provided customTypes
can include one of the detaultTypes
to override the default behavior:
1$('form').serializeJSON({ 2 customTypes: { 3 alwaysBoo: (strVal) => { return "boo"; }, 4 string: (strVal) => { return strVal + "-OVERDRIVE"; }, 5 } 6}); 7 8// returns => 9{ 10 "scary": "boo", // <-- parsed with custom type "alwaysBoo" 11 "str": "str-OVERDRIVE", // <-- parsed with custom override "string" 12 "five": 5, // <-- parsed with default type "number" 13}
Default types used by the plugin are defined in $.serializeJSON.defaultOptions.defaultTypes
.
With no options, .serializeJSON()
returns the same as a regular HTML form submission when serialized as Rack/Rails params. In particular:
:type
to the input name)Available options:
{checkboxUncheckedValue: ""}
returns an empty string. If the field has a :type
, the returned value will be properly parsed; for example if the field type is :boolean
, it returns false
instead of an empty string.<input name="foods[0]" value="banana">
), serialize as an array ({"foods": ["banana"]}
) instead of an object ({"foods": {"0": "banana"}
).data-skip-falsy="true"
input attribute as well. Falsy values are determined after converting to a given type, note that "0"
as :string
(default) is still truthy, but 0
as :number
is falsy.skipFalsyValuesForTypes: ["string", "number"]
would skip ""
for :string
fields, and 0
for :number
fields).:type
functions. Defined as an object like { type: function(value){...} }
. For example: {customTypes: {nullable: function(str){ return str || null; }}
. Custom types extend defaultTypes.string
, number
, boolean
, null
, array
, object
and skip
.:type
suffix and no data-value-type
attribute are parsed with the string
type function by default, but it could be changed to use a different type function instead.data-value-type
attribute. For example <input name="foo::bar" value="1" data-value-type="number">
will be parsed as a number.More details about these options in the sections below.
One of the most confusing details when serializing a form is the input type checkbox, because it includes the value if checked, but nothing if unchecked.
To deal with this, a common practice in HTML forms is to use hidden fields for the "unchecked" values:
1<!-- Only one booleanAttr will be serialized, being "true" or "false" depending if the checkbox is selected or not --> 2<input type="hidden" name="booleanAttr" value="false" /> 3<input type="checkbox" name="booleanAttr" value="true" />
This solution is somehow verbose, but ensures progressive enhancement, it works even when JavaScript is disabled.
But, to make things easier, serializeJSON
includes the option checkboxUncheckedValue
and the possibility to add the attribute data-unchecked-value
to the checkboxes:
1<form> 2 <input type="checkbox" name="check1" value="true" checked/> 3 <input type="checkbox" name="check2" value="true"/> 4 <input type="checkbox" name="check3" value="true"/> 5</form>
Serializes like this by default:
1$('form').serializeJSON(); 2 3// returns => 4{check1: 'true'} // check2 and check3 are ignored
To include all checkboxes, use the checkboxUncheckedValue
option:
1$('form').serializeJSON({checkboxUncheckedValue: "false"}); 2 3// returns => 4{check1: "true", check2: "false", check3: "false"}
The data-unchecked-value
HTML attribute can be used to targed specific values per field:
1<form id="checkboxes"> 2 <input type="checkbox" name="checked[b]:boolean" value="true" data-unchecked-value="false" checked/> 3 <input type="checkbox" name="checked[numb]" value="1" data-unchecked-value="0" checked/> 4 <input type="checkbox" name="checked[cool]" value="YUP" checked/> 5 6 <input type="checkbox" name="unchecked[b]:boolean" value="true" data-unchecked-value="false" /> 7 <input type="checkbox" name="unchecked[numb]" value="1" data-unchecked-value="0" /> 8 <input type="checkbox" name="unchecked[cool]" value="YUP" /> <!-- No unchecked value specified --> 9</form>
1$('form#checkboxes').serializeJSON(); // No option is needed if the data attribute is used 2 3// returns => 4{ 5 'checked': { 6 'b': true, 7 'numb': '1', 8 'cool': 'YUP' 9 }, 10 'unchecked': { 11 'bool': false, 12 'bin': '0' 13 // 'cool' is not included, because it doesn't use data-unchecked-value 14 } 15}
You can use both the option checkboxUncheckedValue
and the attribute data-unchecked-value
at the same time, in which case the option is used as default value (the data attribute has precedence).
1$('form#checkboxes').serializeJSON({checkboxUncheckedValue: 'NOPE'}); 2 3// returns => 4{ 5 'checked': { 6 'b': true, 7 'numb': '1', 8 'cool': 'YUP' 9 }, 10 'unchecked': { 11 'bool': false, // value from data-unchecked-value attribute, and parsed with type "boolean" 12 'bin': '0', // value from data-unchecked-value attribute 13 'cool': 'NOPE' // value from checkboxUncheckedValue option 14 } 15}
You can use the option .serializeJSON({skipFalsyValuesForTypes: ["string"]})
, which ignores any string field with an empty value (default type is :string, and empty strings are falsy).
Another option, since serializeJSON()
is called on a jQuery object, is to just use the proper jQuery selector to skip empty values (see Issue #28 for more info):
1// Select only imputs that have a non-empty value 2$('form :input[value!=""]').serializeJSON(); 3 4// Or filter them from the form 5obj = $('form').find('input').not('[value=""]').serializeJSON(); 6 7// For more complicated filtering, you can use a function 8obj = $form.find(':input').filter(function () { 9 return $.trim(this.value).length > 0 10 }).serializeJSON();
When using :types, you can also skip falsy values (false, "", 0, null, undefined, NaN
) by using the option skipFalsyValuesForFields: ["fullName", "address[city]"]
or skipFalsyValuesForTypes: ["string", "null"]
.
Or setting a data attribute data-skip-falsy="true"
on the inputs that should be ignored. Note that data-skip-falsy
is aware of field :types, so it knows how to skip a non-empty input like this <input name="foo" value="0" data-value-type="number" data-skip-falsy="true">
(Note that "0"
as a string is not falsy, but 0
as number is falsy)).
By default, all serialized keys are strings, this includes keys that look like numbers like this:
1<form> 2 <input type="text" name="arr[0]" value="foo"/> 3 <input type="text" name="arr[1]" value="var"/> 4 <input type="text" name="arr[5]" value="inn"/> 5</form>
1$('form').serializeJSON(); 2 3// arr is an object => 4{'arr': {'0': 'foo', '1': 'var', '5': 'inn' }}
Which is how Rack parse_nested_query behaves. Remember that serializeJSON input name format is fully compatible with Rails parameters, that are parsed using this Rack method.
Use the option useIntKeysAsArrayIndex
to interpret integers as array indexes:
1$('form').serializeJSON({useIntKeysAsArrayIndex: true}); 2 3// arr is an array => 4{'arr': ['foo', 'var', undefined, undefined, undefined, 'inn']}
Note: this was the default behavior of serializeJSON before version 2. You can use this option for backwards compatibility.
All options defaults are defined in $.serializeJSON.defaultOptions
. You can just modify it to avoid setting the option on every call to serializeJSON
. For example:
1$.serializeJSON.defaultOptions.checkboxUncheckedValue = ""; // include unckecked checkboxes as empty strings 2$.serializeJSON.defaultOptions.customTypes.foo = (str) => { return str + "-foo"; }; // define global custom type ":foo"
Other plugins solve the same problem in similar ways:
None of them did what I needed at the time serializeJSON
was created. Factors that differentiate serializeJSON
from the alternatives:
serializeArray
, that creates a JavaScript array of objects, ready to be encoded as a JSON string. Taking into account the W3C rules for successful controls for better compatibility.Contributions are awesome. Feature branch pull requests are the preferred method. Just make sure to add tests for it. To run the jasmine specs, just open spec/spec_runner_jquery.html
in your browser.
See CHANGELOG.md
Written and maintained by Mario Izquierdo
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 2/19 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
10 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More