|
33 | 33 | var typeFunctions = $.extend({}, opts.defaultTypes, opts.customTypes);
|
34 | 34 |
|
35 | 35 | // Make a list with {name, value, el} for each matched element.
|
36 |
| - var formAsArray = f.serializeArray($form); |
37 |
| - f.readCheckboxUncheckedValues(formAsArray, opts, $form); // add objects to the array from unchecked checkboxes if needed |
| 36 | + var serializedArray = f.serializeArray($form, opts); |
38 | 37 |
|
39 |
| - // Convert the formAsArray into a serializedObject with nested keys |
| 38 | + // Convert the serializedArray into a serializedObject with nested keys |
40 | 39 | var serializedObject = {};
|
41 |
| - $.each(formAsArray, function (_i, obj) { |
| 40 | + $.each(serializedArray, function (_i, obj) { |
42 | 41 | var ogName = obj.name; // original input name
|
43 | 42 | var ogValue = obj.value; // original input value
|
44 | 43 |
|
|
123 | 122 | return $.extend({}, f.defaultBaseOptions, f.defaultOptions, options);
|
124 | 123 | },
|
125 | 124 |
|
126 |
| - // Similar to jQuery serializeArray, returns an array of objects with name and value, |
127 |
| - // but in addition has the dom element, so it can be referenced later for configuration data attrs. |
128 |
| - serializeArray: function($form) { |
| 125 | + // Just like jQuery's serializeArray method, returns an array of objects with name and value. |
| 126 | + // but also includes the dom element (el) and is handles unchecked checkboxes if the option or data attribute are provided. |
| 127 | + serializeArray: function($form, opts) { |
| 128 | + if (opts == null) { opts = {}; } |
| 129 | + var f = $.serializeJSON; |
| 130 | + |
129 | 131 | return $form.map(function() {
|
130 | 132 | var elements = $.prop(this, "elements"); // handle propHook "elements" to filter or add form elements
|
131 | 133 | return elements ? $.makeArray(elements) : this;
|
132 | 134 |
|
133 | 135 | }).filter(function() {
|
| 136 | + var $el = $(this); |
134 | 137 | var type = this.type;
|
135 |
| - return this.name && |
136 |
| - !$( this ).is(":disabled") && // .is(":disabled") so that fieldset[disabled] works |
137 |
| - rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && // only form fields |
138 |
| - (this.checked || !rcheckableType.test(type)); // remove unchecked checkboxes |
| 138 | + |
| 139 | + // Filter with the standard W3C rules for successful controls: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2 |
| 140 | + return this.name && // must contain a name attribute |
| 141 | + !$el.is(":disabled") && // must not be disable (use .is(":disabled") so that fieldset[disabled] works) |
| 142 | + rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && // only serialize submittable fields (and not buttons) |
| 143 | + (this.checked || !rcheckableType.test(type) || f.getCheckboxUncheckedValue($el, opts) != null); // skip unchecked checkboxes (unless using opts) |
139 | 144 |
|
140 | 145 | }).map(function(_i, el) {
|
141 |
| - var val = $(this).val(); |
| 146 | + var $el = $(this); |
| 147 | + var val = $el.val(); |
| 148 | + var type = this.type; |
| 149 | + |
142 | 150 | if (val == null) {
|
143 | 151 | return null;
|
144 | 152 | }
|
145 | 153 |
|
| 154 | + if (rcheckableType.test(type) && !this.checked) { |
| 155 | + val = f.getCheckboxUncheckedValue($el, opts); |
| 156 | + } |
| 157 | + |
146 | 158 | if (isArray(val)) {
|
147 | 159 | return $.map(val, function(val) {
|
148 | 160 | return { name: el.name, value: val.replace(rCRLF, "\r\n"), el: el };
|
|
154 | 166 | }).get();
|
155 | 167 | },
|
156 | 168 |
|
| 169 | + getCheckboxUncheckedValue: function($el, opts) { |
| 170 | + var val = $el.attr("data-unchecked-value"); |
| 171 | + if (val == null) { |
| 172 | + val = opts.checkboxUncheckedValue; |
| 173 | + } |
| 174 | + return val |
| 175 | + }, |
| 176 | + |
157 | 177 | // Parse value with type function
|
158 | 178 | applyTypeFunc: function(name, valStr, type, typeFunctions) {
|
159 | 179 | var typeFunc = typeFunctions[type];
|
|
163 | 183 | return typeFunc(valStr);
|
164 | 184 | },
|
165 | 185 |
|
166 |
| - // Fill the formAsArray object with values for the unchecked checkbox inputs, |
167 |
| - // using the same format as the jquery.serializeArray function. |
168 |
| - // The value of the unchecked values is determined from the opts.checkboxUncheckedValue |
169 |
| - // and/or the data-unchecked-value attribute of the inputs. |
170 |
| - readCheckboxUncheckedValues: function (formAsArray, opts, $form) { |
171 |
| - if (opts == null) { opts = {}; } |
172 |
| - |
173 |
| - var selector = "input[type=checkbox][name]:not(:checked):not([disabled])"; |
174 |
| - var $uncheckedCheckboxes = $form.find(selector).add($form.filter(selector)); |
175 |
| - $uncheckedCheckboxes.each(function (_i, el) { |
176 |
| - // Check data attr first, then the option |
177 |
| - var $el = $(el); |
178 |
| - var uncheckedValue = $el.attr("data-unchecked-value"); |
179 |
| - if (uncheckedValue == null) { |
180 |
| - uncheckedValue = opts.checkboxUncheckedValue; |
181 |
| - } |
182 |
| - |
183 |
| - // If there's an uncheckedValue, push it into the serialized formAsArray |
184 |
| - if (uncheckedValue != null) { |
185 |
| - if (el.name && el.name.indexOf("[][") !== -1) { // identify a non-supported |
186 |
| - throw new Error("serializeJSON ERROR: checkbox unchecked values are not supported on nested arrays of objects like '"+el.name+"'. See https://github.com/marioizquierdo/jquery.serializeJSON/issues/67"); |
187 |
| - } |
188 |
| - formAsArray.push({name: el.name, value: uncheckedValue}); |
189 |
| - } |
190 |
| - }); |
191 |
| - }, |
192 |
| - |
193 | 186 | // Splits a field name into the name and the type. Examples:
|
194 | 187 | // "foo" => ["foo", ""]
|
195 | 188 | // "foo:boolean" => ["foo", "boolean"]
|
|
0 commit comments