PageRenderTime 25ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/ajax/libs/jquery.serializeJSON/2.3.0/jquery.serializejson.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 193 lines | 124 code | 21 blank | 48 comment | 46 complexity | a28b014042023dfa2fe514714798f389 MD5 | raw file
  1. /*!
  2. SerializeJSON jQuery plugin.
  3. https://github.com/marioizquierdo/jquery.serializeJSON
  4. version 2.3.0 (Sep, 2014)
  5. Copyright (c) 2014 Mario Izquierdo
  6. Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
  7. and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
  8. */
  9. (function ($) {
  10. "use strict";
  11. // jQuery('form').serializeJSON()
  12. $.fn.serializeJSON = function (options) {
  13. var serializedObject, formAsArray, keys, value, f, opts;
  14. f = $.serializeJSON;
  15. opts = f.optsWithDefaults(options); // calculate values for options {parseNumbers, parseBoolens, parseNulls}
  16. formAsArray = this.serializeArray(); // array of objects {name, value}
  17. f.readCheckboxUncheckedValues(formAsArray, this, opts); // add {name, value} of unchecked checkboxes if needed
  18. serializedObject = {};
  19. $.each(formAsArray, function (i, input) {
  20. keys = f.splitInputNameIntoKeysArray(input.name); // "some[deep][key]" => ['some', 'deep', 'key']
  21. value = f.parseValue(input.value, opts); // string, number, boolean or null
  22. if (opts.parseWithFunction) value = opts.parseWithFunction(value); // allow for custom parsing
  23. f.deepSet(serializedObject, keys, value, opts);
  24. });
  25. return serializedObject;
  26. };
  27. // Use $.serializeJSON as namespace for the auxiliar functions
  28. // and to define defaults
  29. $.serializeJSON = {
  30. defaultOptions: {
  31. parseNumbers: false, // convert values like "1", "-2.33" to 1, -2.33
  32. parseBooleans: false, // convert "true", "false" to true, false
  33. parseNulls: false, // convert "null" to null
  34. parseAll: false, // all of the above
  35. parseWithFunction: null, // to use custom parser, a function like: function(val){ return parsed_val; }
  36. checkboxUncheckedValue: undefined, // to include that value for unchecked checkboxes (instead of ignoring them)
  37. useIntKeysAsArrayIndex: false // name="foo[2]" value="v" => {foo: [null, null, "v"]}, instead of {foo: ["2": "v"]}
  38. },
  39. // Merge options with defaults to get {parseNumbers, parseBoolens, parseNulls, useIntKeysAsArrayIndex}
  40. optsWithDefaults: function(options) {
  41. var f, parseAll;
  42. if (options == null) options = {}; // arg default value = {}
  43. f = $.serializeJSON;
  44. parseAll = f.optWithDefaults('parseAll', options);
  45. return {
  46. parseNumbers: parseAll || f.optWithDefaults('parseNumbers', options),
  47. parseBooleans: parseAll || f.optWithDefaults('parseBooleans', options),
  48. parseNulls: parseAll || f.optWithDefaults('parseNulls', options),
  49. parseWithFunction: f.optWithDefaults('parseWithFunction', options),
  50. checkboxUncheckedValue: f.optWithDefaults('checkboxUncheckedValue', options),
  51. useIntKeysAsArrayIndex: f.optWithDefaults('useIntKeysAsArrayIndex', options)
  52. }
  53. },
  54. optWithDefaults: function(key, options) {
  55. return (options[key] !== false) && (options[key] !== '') && (options[key] || $.serializeJSON.defaultOptions[key]);
  56. },
  57. // Convert the string to a number, boolean or null, depending on the enable option and the string format.
  58. parseValue: function(str, opts) {
  59. var value, f;
  60. f = $.serializeJSON;
  61. if (opts.parseNumbers && f.isNumeric(str)) return Number(str); // number
  62. if (opts.parseBooleans && (str === "true" || str === "false")) return str === "true"; // boolean
  63. if (opts.parseNulls && str == "null") return null; // null
  64. return str; // otherwise, keep same string
  65. },
  66. isObject: function(obj) { return obj === Object(obj); }, // is this variable an object?
  67. isUndefined: function(obj) { return obj === void 0; }, // safe check for undefined values
  68. isValidArrayIndex: function(val) { return /^[0-9]+$/.test(String(val)); }, // 1,2,3,4 ... are valid array indexes
  69. isNumeric: function(obj) { return obj - parseFloat(obj) >= 0; }, // taken from jQuery.isNumeric implementation. Not using jQuery.isNumeric to support old jQuery and Zepto versions
  70. // Split the input name in programatically readable keys
  71. // "foo" => ['foo']
  72. // "[foo]" => ['foo']
  73. // "foo[inn][bar]" => ['foo', 'inn', 'bar']
  74. // "foo[inn][arr][0]" => ['foo', 'inn', 'arr', '0']
  75. // "arr[][val]" => ['arr', '', 'val']
  76. splitInputNameIntoKeysArray: function (name) {
  77. var keys, last, f;
  78. f = $.serializeJSON;
  79. if (f.isUndefined(name)) { throw new Error("ArgumentError: param 'name' expected to be a string, found undefined"); }
  80. keys = $.map(name.split('['), function (key) {
  81. last = key[key.length - 1];
  82. return last === ']' ? key.substring(0, key.length - 1) : key;
  83. });
  84. if (keys[0] === '') { keys.shift(); } // "[foo][inn]" should be same as "foo[inn]"
  85. return keys;
  86. },
  87. // Set a value in an object or array, using multiple keys to set in a nested object or array:
  88. //
  89. // deepSet(obj, ['foo'], v) // obj['foo'] = v
  90. // deepSet(obj, ['foo', 'inn'], v) // obj['foo']['inn'] = v // Create the inner obj['foo'] object, if needed
  91. // deepSet(obj, ['foo', 'inn', '123'], v) // obj['foo']['arr']['123'] = v //
  92. //
  93. // deepSet(obj, ['0'], v) // obj['0'] = v
  94. // deepSet(arr, ['0'], v, {useIntKeysAsArrayIndex: true}) // arr[0] = v
  95. // deepSet(arr, [''], v) // arr.push(v)
  96. // deepSet(obj, ['arr', ''], v) // obj['arr'].push(v)
  97. //
  98. // arr = [];
  99. // deepSet(arr, ['', v] // arr => [v]
  100. // deepSet(arr, ['', 'foo'], v) // arr => [v, {foo: v}]
  101. // deepSet(arr, ['', 'bar'], v) // arr => [v, {foo: v, bar: v}]
  102. // deepSet(arr, ['', 'bar'], v) // arr => [v, {foo: v, bar: v}, {bar: v}]
  103. //
  104. deepSet: function (o, keys, value, opts) {
  105. var key, nextKey, tail, lastIdx, lastVal, f;
  106. if (opts == null) opts = {};
  107. f = $.serializeJSON;
  108. if (f.isUndefined(o)) { throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined"); }
  109. if (!keys || keys.length === 0) { throw new Error("ArgumentError: param 'keys' expected to be an array with least one element"); }
  110. key = keys[0];
  111. // Only one key, then it's not a deepSet, just assign the value.
  112. if (keys.length === 1) {
  113. if (key === '') {
  114. o.push(value); // '' is used to push values into the array (assume o is an array)
  115. } else {
  116. o[key] = value; // other keys can be used as object keys or array indexes
  117. }
  118. // With more keys is a deepSet. Apply recursively.
  119. } else {
  120. nextKey = keys[1];
  121. // '' is used to push values into the array,
  122. // with nextKey, set the value into the same object, in object[nextKey].
  123. // Covers the case of ['', 'foo'] and ['', 'var'] to push the object {foo, var}, and the case of nested arrays.
  124. if (key === '') {
  125. lastIdx = o.length - 1; // asume o is array
  126. lastVal = o[lastIdx];
  127. if (f.isObject(lastVal) && (f.isUndefined(lastVal[nextKey]) || keys.length > 2)) { // if nextKey is not present in the last object element, or there are more keys to deep set
  128. key = lastIdx; // then set the new value in the same object element
  129. } else {
  130. key = lastIdx + 1; // otherwise, point to set the next index in the array
  131. }
  132. }
  133. // o[key] defaults to object or array, depending if nextKey is an array index (int or '') or an object key (string)
  134. if (f.isUndefined(o[key])) {
  135. if (nextKey === '') { // '' is used to push values into the array.
  136. o[key] = [];
  137. } else if (opts.useIntKeysAsArrayIndex && f.isValidArrayIndex(nextKey)) { // if 1, 2, 3 ... then use an array, where nextKey is the index
  138. o[key] = [];
  139. } else { // for anything else, use an object, where nextKey is going to be the attribute name
  140. o[key] = {};
  141. }
  142. }
  143. // Recursively set the inner object
  144. tail = keys.slice(1);
  145. f.deepSet(o[key], tail, value, opts);
  146. }
  147. },
  148. // Fill the formAsArray object with values for the unchecked checkbox inputs,
  149. // using the same format as the jquery.serializeArray function.
  150. // The value of the uncheked values is determined from the opts.checkboxUncheckedValue
  151. // and/or the data-unchecked-value attribute of the inputs.
  152. readCheckboxUncheckedValues: function (formAsArray, $form, opts) {
  153. var selector, $uncheckedCheckboxes, $el, dataUncheckedValue, f;
  154. if (opts == null) opts = {};
  155. f = $.serializeJSON;
  156. selector = 'input[type=checkbox]:not(:checked)';
  157. $uncheckedCheckboxes = $form.find(selector).add($form.filter(selector));
  158. $uncheckedCheckboxes.each(function (i, el) {
  159. $el = $(el);
  160. dataUncheckedValue = $el.attr('data-unchecked-value');
  161. if(dataUncheckedValue) { // data-unchecked-value has precedence over option opts.checkboxUncheckedValue
  162. formAsArray.push({name: el.name, value: dataUncheckedValue});
  163. } else {
  164. if (!f.isUndefined(opts.checkboxUncheckedValue)) {
  165. formAsArray.push({name: el.name, value: opts.checkboxUncheckedValue});
  166. }
  167. }
  168. });
  169. }
  170. };
  171. }(window.jQuery || window.Zepto || window.$));