IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    表单格式化插件jquery.serializeJSON

    ivan发表于 2016-12-17 09:25:23
    love 0

    前言

    前端在处理含有大量数据提交的表单时,除了使用Form直接提交刷新页面之外,经常碰到的需求是收集表单信息成数据对象,Ajax提交。

    而在处理复杂的表单时,需要一个一个区手动判断处理字段值,显得非常麻烦。接下来介绍的插件将解决这个问题。

    关于serializeJSON

    使用jquery.serializeJSON,可以在基于jQuery或者Zepto的页面中,调用 .serializeJSON() 方法来序列化form表单的数据成JS对象。

    使用

    下载: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、select等标签)

    <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"]
    }

    serializeJSON方法返回一个JS对象,并非JSON字符串。可以使用 JSON.stringify 转换成字符串(注意IE8兼容性)。

    var jsonString = JSON.stringify(obj);

    指定数据类型

    获取到的属性值一般是字符串,可以通过HTML指定类型 : type 进行强制转换。

    <form>
        <input type="text" name="notype"           value="default type is :string"/>
        <input type="text" name="string:string"    value=":string type overrides parsing options"/>
        <input type="text" name="excluded:skip"    value="Use :skip to not include this field in the result"/>
    
        <input type="text" name="number[1]:number"           value="1"/>
        <input type="text" name="number[1.1]:number"         value="1.1"/>
        <input type="text" name="number[other stuff]:number" value="other stuff"/>
    
        <input type="text" name="boolean[true]:boolean"      value="true"/>
        <input type="text" name="boolean[false]:boolean"     value="false"/>
        <input type="text" name="boolean[0]:boolean"         value="0"/>
    
        <input type="text" name="null[null]:null"            value="null"/>
        <input type="text" name="null[other stuff]:null"     value="other stuff"/>
    
        <input type="text" name="auto[string]:auto"          value="text with stuff"/>
        <input type="text" name="auto[0]:auto"               value="0"/>
        <input type="text" name="auto[1]:auto"               value="1"/>
        <input type="text" name="auto[true]:auto"            value="true"/>
        <input type="text" name="auto[false]:auto"           value="false"/>
        <input type="text" name="auto[null]:auto"            value="null"/>
        <input type="text" name="auto[list]:auto"            value="[1, 2, 3]"/>
    
        <input type="text" name="array[empty]:array"         value="[]"/>
        <input type="text" name="array[list]:array"          value="[1, 2, 3]"/>
    
        <input type="text" name="object[empty]:object"       value="{}"/>
        <input type="text" name="object[dict]:object"        value='{"my": "stuff"}'/>
    </form>

    $('form').serializeJSON();
    
    // returns =>
    {
        "notype": "default type is :string",
        "string": ":string type overrides parsing options",
        // :skip type removes the field from the output
        "number": {
            "1": 1,
            "1.1": 1.1,
            "other stuff": NaN, // <-- Other stuff parses as NaN (Not a Number)
        },
        "boolean": {
            "true": true,
            "false": false,
            "0": false, // <-- "false", "null", "undefined", "", "0" parse as false
        },
        "null": {
            "null": null, // <-- "false", "null", "undefined", "", "0" parse as null
            "other stuff": "other stuff"
        },
        "auto": { // 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
        },
        "array": { // <-- works using JSON.parse
            "empty": [],
            "not empty": [1,2,3]
        },
        "object": { // <-- works using JSON.parse
            "empty": {},
            "not empty": {"my": "stuff"}
        }
    }

    数据类型也可以指定在 data-value-type 属性中,代替 :type 标记。

    <form>
      <input type="text" name="number[1]"     data-value-type="number"  value="1"/>
      <input type="text" name="number[1.1]"   data-value-type="number"  value="1.1"/>
      <input type="text" name="boolean[true]" data-value-type="boolean" value="true"/>
      <input type="text" name="null[null]"    data-value-type="null"    value="null"/>
      <input type="text" name="auto[string]"  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为整数时,将序列化为数组

     包含未勾选的checkboxes

    serializeJSON 支持 checkboxUncheckedValue 配置,或者可以在checkboxes添加 data-unchecked-value 属性。

    默认方法:

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

    $('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
      }
    }

    自动检测转换类型

    默认的类型为字符串 :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>

    $('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": ""
    }

    总结

    这个插件支持的配置非常丰富,自定义程度很高,带来很大的便捷性。



沪ICP备19023445号-2号
友情链接