Giter VIP home page Giter VIP logo

jquery.serializejson's Introduction

jquery.serializeJSON

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

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:

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.serializejson.js"></script>

Usage Example

HTML form:

<form>
  <input type="text" name="title" value="Dune"/>
  <input type="text" name="author[name]" value="Frank Herbert"/>
  <input type="text" name="author[period]" value="1945–1986"/>
</form>

JavaScript:

$('form').serializeJSON();

// returns =>
{
  title: "Dune",
  author: {
    name: "Frank Herbert",
    period: "1945–1986"
  }
}

Nested attributes and arrays can be specified by naming fields with the syntax: name="attr[nested][nested]".

HTML form:

<form id="my-profile">
  <!-- simple attribute -->
  <input type="text" name="name" value="Mario" />

  <!-- 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" />

  <!-- nested arrays, 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",

  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. 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).

var obj = $('form').serializeJSON();
var 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.

Parse values with :types

Fields values are :string by default. But can be parsed with types by appending a :type suffix to the field name:

<form>
  <input type="text" name="default"          value=":string is default"/>
  <input type="text" name="text:string"      value="some text string"/>
  <input type="text" name="excluded:skip"    value="ignored field because of type :skip"/>

  <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]:number"    value="other"/>

  <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]:null"        value="other"/>

  <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 =>
{
  "default": ":string is the default",
  "text": "some text string",
  // excluded:skip is ignored in the output

  "numbers": {
    "1": 1,
    "1.1": 1.1,
    "other": NaN, // <-- "other" is parsed as NaN
  },
  "bools": {
    "true": true,
    "false": false,
    "0": false, // <-- "false", "null", "undefined", "", "0" are parsed as false
  },
  "nulls": {
    "null": null, // <-- "false", "null", "undefined", "", "0"  are parsed as null
    "other": "other" // <-- if not null, the type is a string
  },
  "arrays": { // <-- uses JSON.parse
    "empty": [],
    "not empty": [1,2,3]
  },
  "objects": { // <-- uses JSON.parse
    "empty": {},
    "not empty": {"my": "stuff"}
  }
}

Types can also be specified with the attribute data-value-type, instead of adding the :type suffix in the field name:

<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="anarray" data-value-type="array"   value="[1, 2, 3]"/>
</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 }.

Custom Types

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.

<form>
  <input type="text" name="scary:alwaysBoo" value="not boo"/>
  <input type="text" name="str:string"      value="str"/>
  <input type="text" name="five:number"     value="5"/>
</form>
$('form').serializeJSON({
  customTypes: {
    alwaysBoo: (strVal, el) => {
      // strVal: is the input value as a string
      // el: is the dom element. $(el) would be the jQuery element
      return "boo"; // value returned in the serialization of this type
    },
  }
});

// returns =>
{
  "scary": "boo",  // <-- parsed with custom type "alwaysBoo"
  "str": "str",
  "five": 5,
}

The provided customTypes can include one of the detaultTypes to override the default behavior:

$('form').serializeJSON({
  customTypes: {
    alwaysBoo: (strVal) => { return "boo"; },
    string: (strVal) => { return strVal + "-OVERDRIVE"; },
  }
});

// returns =>
{
  "scary": "boo",         // <-- parsed with custom type "alwaysBoo"
  "str": "str-OVERDRIVE", // <-- parsed with custom override "string"
  "five": 5,              // <-- parsed with default type "number"
}

Default types used by the plugin are defined in $.serializeJSON.defaultOptions.defaultTypes.

Options

With no options, .serializeJSON() returns the same as a regular HTML form submission when serialized as Rack/Rails params. In particular:

  • Values are strings (unless appending a :type to the input name)
  • Unchecked checkboxes are ignored (as defined in the W3C rules for successful controls).
  • Disabled elements are ignored (W3C rules)
  • Keys (input names) are always strings (nested params are objects by default)

Available options:

  • checkboxUncheckedValue: string, return this value on checkboxes that are not checked. Without this option, they would be ignored. For example: {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.
  • 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"}).
  • skipFalsyValuesForFields: [], skip given fields (by name) with 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 (default) is still truthy, but 0 as :number is falsy.
  • skipFalsyValuesForTypes: [], skip given fields (by :type) with falsy values (i.e. skipFalsyValuesForTypes: ["string", "number"] would skip "" for :string fields, and 0 for :number fields).
  • customTypes: {}, define your own :type functions. Defined as an object like { type: function(value){...} }. For example: {customTypes: {nullable: function(str){ return str || null; }}. Custom types extend defaultTypes.
  • defaultTypes: {defaults}, contains the orignal type functions string, number, boolean, null, array, object and skip.
  • defaultType: "string", fields that have no :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.
  • disableColonTypes: true, do not parse input names as types, allowing field names to use colons. If this option is used, types can still be specified with the 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.

Include unchecked checkboxes

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:

<!-- 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 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:

<form>
  <input type="checkbox" name="check1" value="true" checked/>
  <input type="checkbox" name="check2" value="true"/>
  <input type="checkbox" name="check3" value="true"/>
</form>

Serializes like this by default:

$('form').serializeJSON();

// returns =>
{check1: 'true'} // check2 and check3 are ignored

To include all checkboxes, use the checkboxUncheckedValue option:

$('form').serializeJSON({checkboxUncheckedValue: "false"});

// returns =>
{check1: "true", check2: "false", check3: "false"}

The data-unchecked-value HTML attribute can be used to targed specific values per field:

<form id="checkboxes">
  <input type="checkbox" name="checked[b]:boolean"   value="true" data-unchecked-value="false" checked/>
  <input type="checkbox" name="checked[numb]"        value="1"    data-unchecked-value="0"     checked/>
  <input type="checkbox" name="checked[cool]"        value="YUP"                               checked/>

  <input type="checkbox" name="unchecked[b]:boolean" value="true" data-unchecked-value="false" />
  <input type="checkbox" name="unchecked[numb]"      value="1"    data-unchecked-value="0" />
  <input type="checkbox" name="unchecked[cool]"      value="YUP" /> <!-- No unchecked value specified -->
</form>
$('form#checkboxes').serializeJSON(); // No option is needed if the data attribute is used

// returns =>
{
  'checked': {
    'b':     true,
    'numb':  '1',
    'cool':  'YUP'
  },
  'unchecked': {
    'bool': false,
    'bin':  '0'
    // 'cool' is not included, 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 option is used as default value (the data attribute has precedence).

$('form#checkboxes').serializeJSON({checkboxUncheckedValue: 'NOPE'});

// returns =>
{
  'checked': {
    'b':     true,
    'numb':  '1',
    'cool':  'YUP'
  },
  'unchecked': {
    'bool': false,   // value from data-unchecked-value attribute, and parsed with type "boolean"
    'bin':  '0',     // value from data-unchecked-value attribute
    'cool': 'NOPE'   // value from checkboxUncheckedValue option
  }
}

Ignore Empty Form Fields

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):

// 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();

Ignore Fields With Falsy Values

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)).

Use integer keys as array indexes

By default, all serialized keys are strings, this includes keys that look like numbers like this:

<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();

// arr is an object =>
{'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:

$('form').serializeJSON({useIntKeysAsArrayIndex: true});

// arr is an array =>
{'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.

Option Defaults

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:

$.serializeJSON.defaultOptions.checkboxUncheckedValue = ""; // include unckecked checkboxes as empty strings
$.serializeJSON.defaultOptions.customTypes.foo = (str) => { return str + "-foo"; }; // define global custom type ":foo"

Alternatives

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:

  • Simple and small code base. The minimified version is < 1Kb.
  • Yet flexible enough with features like nested objects, unchecked-checkboxes and custom types.
  • Implementation follows the same rules as the jQuery method 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.
  • The format for the input field names is the same used by Rails (from Rack::Utils.parse_nested_query), that is successfully used by many backend systems and already well understood by many front end developers.
  • Exaustive test suite helps iterate on new releases and bugfixes with confidence.
  • Compatible with bower, zepto.js and pretty much every version of jQuery.

Contributions

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.

Changelog

See CHANGELOG.md

Author

Written and maintained by Mario Izquierdo

jquery.serializejson's People

Contributors

bcjordan avatar brock avatar diaswrd avatar jisaacks avatar katt avatar kotas avatar marioizquierdo avatar milkaknap avatar nicowecode avatar rywall avatar skarr avatar stricte avatar tomturner10 avatar tygriffin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jquery.serializejson's Issues

`parseXYZ` options

I don't like that the parseNumbers option automagically parses everything that looks like a number to numbers, it gets confusing as the backend receiving the data can be type sensitive and won't like to receive a number for a string field, just because you inputted something that looks like a number in a string field. I have the same issue with parseBooleans/parseNulls.

Possible alternatives:

  • having a data attribute on inputs, i.e.

    <input type="text" name="Numeric -2.25" value="-2.25" data-serialize-number="true" />`
  • passing an Array of the names you want to parse as numbers, i.e.

    obj = $form.serializeJSON({parseNumbers: ['Numeric -2.25'/*[, otherName ] [, .. ] )*/});

What do you think? Either solution could be added with backwards compatibility.

How to replace key

I want to replace the key

I know how to replace the value, but not the key.
parseWithFunction

Use with jQuery clones?

Has anyone used this with a alternative jQuery, like Zepto or Minified.js please? Usually jQuery is in a project, but sometimes I try to avoid for mobile.

serializeArray in IE on non form element

Hello,

I discovered that in in IE11 and probably Edge using a serializeArray will not get the data if the selector is not a form.

I made a simple test changing from:
formAsArray = $form.serializeArray();
To
formAsArray = $form.find(':input').serializeArray();

and it seems to work also on IE.

Is this a valid approach or it might have any side effects.

I'm actually trying to serialize a div element.
Maybe i should call serializeJSON with this find instead?
e.g: $('#myDiv').find(':input').serializeJSON();

Any suggestions would help.

Thanks in advance!

Data types

Is it possible to define the type of the form fields in the attribute (e.g. data-type="number") instead of put it part of the name of the field? It's much easier to populate data back to the form, and it will work better with other libs?

Breaks when dealing with a property ending in '='

The '=' gets misinterpreted and ends up as ': '

Page source:
<input name="authenticity_token" type="hidden" value="UHomjpa8+9ljdfbUqGhQ9NGFUSONCzFZE66bicpLGjU=">

AJAX header:
X-CSRF-Token:UHomjpa8+9ljdfbUqGhQ9NGFUSONCzFZE66bicpLGjU=

Serialized JSON:
{"utf8":"✓","_method":"put","authenticity_token":"UHomjpa8 9ljdfbUqGhQ9NGFUSONCzFZE66bicpLGjU:","vote":{"up":"false"}}

Doesn't handle multiple select

I tried the plugin on my form but it failed to render a multiple select with multiple selections as an array. It just showed one value.

Bug with <select multiple>

I got a bug with select "multiple" attr

<form>
    <select name="city" multiple>
        <option></option>
        <option value="1" selected>NY</option>
        <option value="2" selected>London</option>
        <option value="3">Tokyo</option>
    </select>
</form>
var data = $('form').serializeJSON();
// > data = {city: "2"}

imho, {city: ["1", "2"]} would be right

UPD: but

<form>
    <select name="city[]" multiple>
        <option></option>
        <option value="1" selected>NY</option>
        <option value="2" selected>London</option>
        <option value="3">Tokyo</option>
    </select>
</form>

works ok

readCheckboxUncheckedValues get attr data-unchecked-value is misspelled

readCheckboxUncheckedValues: function (formAsArray, $form, opts) {
   // ...
        dataUncheckedValue = $el.attr('data-unckecked-value');
        if(dataUncheckedValue) { // data-unchecked-value has precedence over option opts.checkboxUncheckedValue
          formAsArray.push({name: el.name, value: dataUncheckedValue});
        } else {
          if (!f.isUndefined(opts.checkboxUncheckedValue)) {
            formAsArray.push({name: el.name, value: opts.checkboxUncheckedValue});
          }
        }
      });
    }

Add jquery.serializeJSON to bower

Hello, it could be great if you can add jquery.serializeJSON to bower repository, in order to include it easily in heavy projects.

Incorrect JSON generation for nested attribute.

Hey,

I was using your jQuery plugin and have encountered this weird behaviour.

<!DOCTYPE html>
<html>

<head>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript" src="jquery.serializejson.js"></script>
</head>

<body>
    <form id= "new_form">
        User Email:
        <input type="text" name = "agent_signup[user_user_emails_attributes[0][email]]">
        <button>Submit</button>
    </form>
</body>

</html>

To serialize the form, I ran

$("#new_form").serializeJSON()

The returned object was

"{"agent_signup":{"user_user_emails_attributes":{"0":{"email]":""}}}}"

whereas the expected object is

"{"agent_signup":{"user_user_emails_attributes":{"0":{"email":""}}}}"

Problem with checkbox checked

Hi, I have the next checkbox:

<input type="checkbox" name="show" value="true" checked>

if I uncheck the checkbox, continues send true on the object.

What i should do for this work right?

Can I serialize radio input types?

From the readme file, there is no mention of radio input types and it doesn't work either. Will be nice if the functionality is added too, or is there any reason why it isn't added?

Parsing Error, second ] is ignored.

Greetings,

In a certain set of circumstances the second ] in a input name is incorrectly parsed.

An example here:

    <!DOCTYPE html>
    <html>
      <head>
        <script src="/javascript/jquery-1.11.1.min.js"></script>
        <script src="/javascript/serializeJSON/jquery.serializeJSON.min.js"></script>
        <script>
        //<![CDATA[
        jQuery(document).ready(function() {
            // save the form
            jQuery('.js-submit-button').on('click', function(e) {
                e.preventDefault();
                $('#fart').replaceWith(JSON.stringify($('#my_form').serializeJSON(), undefined, 2));
            });
        });
        //]]>
        </script>
      </head>
      <body>
        <form id="my_form">
          <input name="guide[section[abcd]][anchor_target]" value="41268" type="hidden">
          <input name="guide[section[defg]][anchor_target]" value="170805" type="hidden">

          <button class="js-submit-button">Save Guide</button>
        </form>
        <div id="fart">
          testing
        </div>
      </body>
    </html>

Generates this result:

    { "guide": { "section": { "abcd]": { "anchor_target": "41268" }, "defg]": { "anchor_target": "170805" } } } }

Note that the key name is "abcd]", the ']' bracket should not be part of the key.

When I run this though the rails parser, I get the following:
(reference: http://codefol.io/posts/How-Does-Rack-Parse-Query-Params-With-parse-nested-query )

[RAILS_ENV=development deployer@local current]$ irb
irb(main):001:0> require 'rack'
=> true
irb(main):002:0> def p(params)
irb(main):003:1>   Rack::Utils.parse_nested_query(params)
irb(main):004:1> end
=> :p
irb(main):005:0> p("guide[section[abcd]][anchor_target]=41268&guide[section[defg]][anchor_target]=170805")
=> {"guide"=>{"section"=>{"abcd"=>{"anchor_target"=>"41268"}, "defg"=>{"anchor_target"=>"170805"}}}}
irb(main):006:0>

I get the expected output.

Let me know if there is anything I can do to help!

-daniel

Extra array items when using data-unchecked-value

In this form example:

<input type="text"     name="question" value="Favorite color?">

<input type="checkbox" name="answers[][correct]:boolean" value="true" data-unchecked-value="false">
<input type="text"     name="answers[][text]" value="Blue">

<input type="checkbox" name="answers[][correct]:boolean" value="true" data-unchecked-value="false">
<input type="text"     name="answers[][text]" value="Green">

<input type="checkbox" name="answers[][correct]:boolean" value="true" data-unchecked-value="false">
<input type="text"     name="answers[][text]" value="Red">

If all checkboxes are ticked (checked), it returns the correct JSON:

{
  "question": "Favorite color?",
  "answers":[
    {"correct":true,"text":"Blue"},
    {"correct":true,"text":"Green"},
    {"correct":true,"text":"Red"}
  ]
}

But if none of the checkboxes are ticked, it returns invalid JSON:

{
  "question": "Favorite color?",
  "answers": [
    {"text":"Blue"},
    {"text":"Green"},
    {"text":"Red","correct":false},
    {"correct":false},
    {"correct":false}
  ]
}

npm publish

could you npm publish to push the latest version 2.7.2 to npm?

Thx

Values with quotes

Hi,

Is this a bug of the plugin that it can't handle double quotes in strings?

It doesn't escape them at all, when I'm trying to JSON a form with tinyMCE inside it. In the textarea from tinyMCE I have images with attibutes like class="" etc.

Is there any way I could escape the double quotes?

Ability to read disabled input values

I'm very happy to find this library. It really helps me to solve the unchecked checkbox issues.

However, It seems it doesn't have an option to read disabled input values. Any ideas or suggestions?

`checkboxUncheckedValue` and arrays

I ran into an issue with combining checkboxUncheckedValue and array-like checkboxes

<label class="checkbox-inline">
  <input type="checkbox" name="flags[]" value="input1"> Input 1
</label>
<label class="checkbox-inline">
  <input type="checkbox" name="flags[]" value="input2"> Input 2
</label>

It's currently getting treated as hash, i.e.

{ 
  "flags": {
    "input1": false,
    "input2": true
  }
}

It would make sense if they were defined as name="flags[input1]" but in this case it should rather be parsed as an array.

Expected result

No checked boxes:

{ 
  "flags": []
}

Checked boxes:

{ 
  "flags": ["input2"]
}

Problem with names with array-style numerical keys

Say you've got a form like:

<form>
    <input type="hidden" name="status[1]" value="1">
    <input type="hidden" name="status[3]" value="0">
    <input type="hidden" name="status[6]" value="1">
</form>

$('form').serializeJSON() gives you:

{
    "status": [ // Array[3]
        1: "1",
        3: "0",
        6: "1"
    ]
}

which on many backends will get converted into a non-associative array, delinking the keys. This means you can't use things like IDs as keys.

However, both https://github.com/danheberden/jquery-serializeForm and https://github.com/serbanghita/formToObject.js get this right, and $('form').serializeForm() gives you:

{
    "status": { // Object
        "1": "1",
        "3": "0",
        "6": "1"
    }
}

IMO, anytime an explicit value is given in the form array-syntax, that element should be an object. So given status[1], status would be an object, whereas given status[], status would be an array.

Problem with parsing array of nested objects

Hello!

I've found not quite correct behavior (compared to php's parsing algo).
Better to explain with an example:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="js/lib/zepto.min.js"></script>
    <script src="js/lib/jquery.serializejson.min.js"></script>
  </head>
  <body>
    <pre><?php
      if (! empty ($_POST)) {
        print_r ($_POST);
        echo json_encode ($_POST, JSON_NUMERIC_CHECK);
      }
    ?></pre>

    <form id="test" method="post">
      <!--
      <select name="users[id][]" multiple>
      js: {"users":{"id":[["2","3"]]}}
      php: {"users":{"id":[2,3]}}
      -->

      <select name="users[][id]" multiple>
      <!-- 
      js: {"users":[{"id":["2","3"]}]}
      php: {"users":[{"id":2},{"id":3}]}
      -->
        <option value="1">a</option>
        <option value="2">b</option>
        <option value="3">c</option>
      </select>
      <button type="submit">submit</button>
    </form>

    <script>
      $ (function () {
        $ ('#test').on ('submit', function (event) {
          console.log ( JSON.stringify ($ (this).serializeJSON ({ parseNumbers : true })) );
        });
      });
    </script>
  </body>
</html>

That is i get array of ids instead of array of key/value objects pairs.

Support parse comma separated value as Array.

Consider some HTML select tag replacement (such as dropdown component of semantic-ui) allow multiple selection. And it will write multiple selection as comma separated string to a hidden field's value property.

switching from SerializeObject

I'm switching from using this code (https://github.com/hongymagic/jQuery.serializeObject) to using your serializeJSON instead. In both cases, I'm trying to send JSON to a java backend. My application was developed with the SerializeObject in mind, but I'd like to switch over to using your code here.

Can you see any reason why SerializeJSON would produce a different data structure than SerializeObject? I'm comparing the outputs of [ form -> SerializeObject ] vs. [ form -> serializeJSON -> JSON.stringify ]. I feel stumped.

checkbox value is fail!

html:
<input type="checkbox" name="test" value="1" checked="checked" /> <input type="checkbox" name="test" value="2" checked="checked" /> <input type="checkbox" name="test" value="3" checked="checked" />

jquery.serializeJson result:
{test:3}

desired result:
{test:[1,2,3]}

Option to parse only non-text fields

So frequently, the fields we wish to parse are actually number fields, checkboxes, or radio buttons--maybe selects. But we don't want to parse, say, a plain text field just because the user happened to enter a number. An option to specify what input types you would like parsed would be very helpful. I'd be glad to help implement this.

File attachement

i use jquary serializeJson ,but i have one troulbe i can't post File how i can do this ?

my code

var courseType = $('#main-form').serializeJSON();

    $.post("/course/types/save",
        courseType, function(data){}

form action="#" class="form-horizontal" id="main-form" enctype="multipart/form-data">

input type="file" name="photo"

form

.js fails to load on linux (ubuntu) due to filename mismatch

Hi Mario.

in your example you give the following snippet to include the .js:

  <script type="text/javascript" src="jquery.serializeJSON.min.js"></script>

but the file in the download is actually named :

  jquery.serializejson.min.js

Fails to load (at least on ubuntu 14) most probably 'cause since linux FS is context sensitive.

I'am actually wondering why this works on mac osx ??? It does, I run it without problems. Windows is fine (Windows7), too.

serializeJSON ignoring <select>

I'm kind of puzzled - I've created a simple select in MVC as follows:
<%:Html.DropDownList("PersonJobDescription", new SelectListItem[] {
new SelectListItem { Text = null, Value = null },
new SelectListItem { Text = "Administrator", Value = "Administrator" },
new SelectListItem { Text = "Nurse", Value = "Nurse" },
new SelectListItem { Text = "Teacher", Value = "Teacher" },
new SelectListItem { Text = "Secretary", Value = "Secretary" },
new SelectListItem { Text = "Health Aide/UAP", Value = "Health Aide/UAP" },
new SelectListItem { Text = "Other", Value = "Other" }
})%>

The name "PersonJobDescription" is rendered correctly in HTML. However upon using the following:

var formData = $("#myForm").serializeJSON();
var jsonstring = JSON.stringify(formData);

Everything else is scooped up into json nicely but the selector "PersonJobDescription" is ignored even though it has a name property being rendered. I also tinkered with Selected=true which is rendered as Selected="selected" it is still being ignored.
Thoughts?

Array of Objects with dot (.) syntax

Hi,

I'm currently using this stuff to populate array of objects. This is on ASP.NET MVC
http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/.

What it does is something like this :

<ul>
<li>
<input name="Ingredients.Index" type="hidden" value="425b56ca-5c9c-4d49-b30b-346b6d0bff6f">
<input name="Ingredients[425b56ca-5c9c-4d49-b30b-346b6d0bff6f].IngredientSubTitle" type="text" value="">
<input name="Ingredients[425b56ca-5c9c-4d49-b30b-346b6d0bff6f].IngredientName" type="text" value="cauliflower">
</li>


<li style="padding-bottom:15px">

<input name="Ingredients.Index" type="hidden" value="d5422e9d-7cec-4b01-9378-d71f2ea9b188">
<input name="Ingredients[d5422e9d-7cec-4b01-9378-d71f2ea9b188].IngredientSubTitle" type="text" value="">
<input name="Ingredients[d5422e9d-7cec-4b01-9378-d71f2ea9b188].IngredientName" type="text" value="apples">
</li>


<li>
<input autocomplete="off" name="Ingredients.Index" type="hidden" value="5f9dda33-4be4-4f21-a249-3c291af03153">
<input name="Ingredients[5f9dda33-4be4-4f21-a249-3c291af03153].IngredientSubTitle" type="text" value="">
<input name="Ingredients[5f9dda33-4be4-4f21-a249-3c291af03153].IngredientName" type="text" value="red onion">

</li>
</ul>

Basically, it is indexing an array with the use of GUID instead of int.

I've used useIntKeysAsArrayIndex:true but what it does is it is only removing the label in front of the GUID.

What I would like to achieve is some thing like this :

"Ingredients": [
         { "IngredientSubtitle": "", "IngredientName": "cauliflower" },
         { "IngredientSubtitle": "", "IngredientName": "apples" },
         { "IngredientSubtitle": "", "IngredientName": "red onion" },
]

Thanks

Incorrect git tag

Looks like you incorrectly tagged the most recent release as 2.1.1 instead of 1.2.2, which confuses bower.

2.6.0 release?

Hiya, (first off thanks for the very handy plugin) I could really use the new "customTypes" option but it seems the 2.6.0 version has not been tagged yet so I cant pull it via bower (properly) unless i go to the latest commit. Would very much appreciate a new tag. Cheers!

"select multiple options, just name it as an array[]" is not worling for me

Hello marioizquierdo,

Apart from the fact that adding the brackets in the name is not very suitable for me it also is not working.
When I include "multiple" in the select tag the tag is not included in the element array. If I put [] after the name or not.

Is there another option to get a multiple select element included?

Kind regards,
Mario

Auto-index with unchecked checkboxes problem

If I have some HTML like this:

<input type="checkbox" name="rows[][replicate]" value="1" />
...
<input type="checkbox" name="rows[][replicate]" value="1" checked />
...
<input type="checkbox" name="rows[][replicate]" value="1" />

I expect the result to be this:

{
  rows:  [
    { replicate: "0" },
    { replicate: "1" },
    { replicate: "0" },
  ]
}

Instead, I get something like this:

{
  rows:  [
    {},
    { replicate: "1" },
    {},
    { replicate: "0" },
    { replicate: "0" },
  ]
}

Instead of adding the unchecked values to the correct dynamic indexes, it adds them to new array indices at the end of the array. Am I doing something wrong, or is this a bug?

array with object notation overwriting previous array entries

I'm having problems getting the array and objection notation to work together. I have put together the following jsfiddle to represent the situation: https://jsfiddle.net/9kurm7qz/15/

If I remove the nested object nation, everything will be pushed into an array fine. If I keep the object notation after the array notation, only the last entry is created. It might be my syntax, but I can't seem to figure out where the issue is.

Empty multiple select

So I have a select sg like this:

<select name="camel[]" multiple>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
</select>

When I try to serialize with serializeJSON and no one option is selected, the camel array is missing from the result, but I check any of the options, the camel array is appearing in the result.

Can I miss something? I searched, but I not found any options for serializeJSON to give me back the empty camel array.
Or if this is not possible at this time could implement this feature?

I temporary bypass the problem with a hidden input, but I really don't like this solution.

Array of object ?

Hi,

In your example you create an array of projects :

<!-- 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"/>

And result is :

  projects: {
    '0': { name: "serializeJSON", language: "javascript", popular: "1" },
    '1': { name: "tinytest.js",   language: "javascript", popular: "0" }
  },

I'd like to get an array of result like this :

  projects: [
     { name: "serializeJSON", language: "javascript", popular: "1" },
     { name: "tinytest.js",   language: "javascript", popular: "0" }
  ],

Is it possible ?

Does it sanitize inputs?

Hello,

I am using your script to get data from a from and make them a JS object, all works fine but I'm wondering if I can "sanitize" the input from nasty tags, formatting, script tags etc...

obj is undefined

I am getting this error message in firefox console 27 :(

TypeError: obj is undefined jquery.serializeJSON.js:87

Ignoring empty form fields

As far as I could understand, there is no way to ignore empty form fields, excluding them from the resulting object. If so, is this feature on the roadmap or are you open to a pull request?

option/callback/something to remove properties

how about an option or condition or callback or something to remove properties if they match a condition?

maybe something like this:

var data = someForm.serializeJSON({parseWithFunction: function(val){
    if (val === "") return; // removes the property from the returned object
    return val;
}});

so this would mean returning nothing wouldnt lead to "undefined", but to remove the property

or maybe an additional option like parseCondition?

or is this already possible and i just didnt find it?

really great library, thanks :)

Multiple select with default property

Hi,

thanks for plugin, helped me alot.

I have 2 select multiple, is it posibble to serialize it with default property value for each one

  <select name="users[][id]" data-typeid="1" multiple>
        <option value="1">a</option>
        <option value="2" selected>b</option>
        <option value="3" selected>c</option>
    </select>


    <select name="users[][id]" data-typeid="2" multiple>
        <option value="4">d</option>
        <option value="5" selected>e</option>
        <option value="6" selected>f</option>
    </select>

expected result

{"users":[{"id":"2","typeid":"1"},{"id":"3","typeid":"1"},{"id":"5","typeid":"2"},{"id":"6","typeid":"2"}]}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.