Skip to content

Commit d017062

Browse files
Merge pull request prototypejs#66 from rydenius/1384-form-serialize-fix
Fix regression in `Form.serialize` when handling `<select multiple>` elements. [#1384 state:resolved]
2 parents fccc5c3 + a03039d commit d017062

File tree

3 files changed

+48
-13
lines changed

3 files changed

+48
-13
lines changed

src/prototype/dom/form.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,27 @@ var Form = {
113113
accumulator = function(result, key, value) {
114114
if (key in result) {
115115
if (!Object.isArray(result[key])) result[key] = [result[key]];
116-
result[key].push(value);
116+
result[key] = result[key].concat(value);
117117
} else result[key] = value;
118118
return result;
119119
};
120120
} else {
121121
initial = '';
122-
accumulator = function(result, key, value) {
123-
// Normalize newlines as \r\n because the HTML spec says newlines should
124-
// be encoded as CRLFs.
125-
value = value.gsub(/(\r)?\n/, '\r\n');
126-
value = encodeURIComponent(value);
127-
// Likewise, according to the spec, spaces should be '+' rather than
128-
// '%20'.
129-
value = value.gsub(/%20/, '+');
130-
return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
131-
}
122+
accumulator = function(result, key, values) {
123+
if (!Object.isArray(values)) {values = [values];}
124+
if (!values.length) {return result;}
125+
// According to the spec, spaces should be '+' rather than '%20'.
126+
var encodedKey = encodeURIComponent(key).gsub(/%20/, '+');
127+
return result + (result ? "&" : "") + values.map(function (value) {
128+
// Normalize newlines as \r\n because the HTML spec says newlines should
129+
// be encoded as CRLFs.
130+
value = value.gsub(/(\r)?\n/, '\r\n');
131+
value = encodeURIComponent(value);
132+
// According to the spec, spaces should be '+' rather than '%20'.
133+
value = value.gsub(/%20/, '+');
134+
return encodedKey + "=" + value;
135+
}).join("&");
136+
};
132137
}
133138

134139
return elements.inject(initial, function(result, element) {

test/unit/fixtures/form.html

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,29 @@
118118
</form>
119119

120120
<form id="form_with_inputs_needing_encoding" style="display:none">
121-
<input type="hidden" name="user[wristbands][][nickname]" id="fine_1" value="Hässlich" />
121+
<input type="hidden" name="user[wristbands][ ][nickname]" id="fine_1" value="Hässlich" />
122122
</form>
123123

124124
<form id="form_with_troublesome_input_names">
125125
<input type="text" name="length" value="foo" />
126126
<input type="text" name="bar" value="baz" />
127127
</form>
128+
129+
<form id="form_with_multiple_select">
130+
<input type="text" name="peewee" value="herman" />
131+
<input type="hidden" name="colors" value="pink" />
132+
<select name="colors" multiple="multiple">
133+
<option value="blue" selected>blue</option>
134+
<option value="red">red</option>
135+
<option value="green">green</option>
136+
<option value="yellow" selected>yellow</option>
137+
<option value="not grey" selected>grey</option>
138+
</select>
139+
<select name="number">
140+
<option value="0">0</option>
141+
<option value="1">1</option>
142+
<option value="2" selected>2</option>
143+
<option value="3">3</option>
144+
</select>
145+
<input type="submit" />
146+
</form>

test/unit/form_test.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ new Test.Unit.Runner({
301301
},
302302

303303
testFormSerializeURIEncodesInputs: function() {
304-
this.assertEqual("user%5Bwristbands%5D%5B%5D%5Bnickname%5D=H%C3%A4sslich", $('form_with_inputs_needing_encoding').serialize(false));
304+
this.assertEqual("user%5Bwristbands%5D%5B+%5D%5Bnickname%5D=H%C3%A4sslich", $('form_with_inputs_needing_encoding').serialize(false));
305305
},
306306

307307
testFormMethodsOnExtendedElements: function() {
@@ -325,6 +325,17 @@ new Test.Unit.Runner({
325325
this.assert(!select.anInputMethod);
326326
this.assertEqual('select', select.aSelectMethod());
327327
},
328+
329+
testFormSerializeMultipleSelect: function () {
330+
var form = $("form_with_multiple_select");
331+
this.assertEqual("peewee=herman&colors=pink&colors=blue&colors=yellow&colors=not+grey&number=2", form.serialize(false));
332+
var hash = {
333+
peewee: 'herman',
334+
colors: ['pink', 'blue', 'yellow', 'not grey'],
335+
number: '2'
336+
};
337+
this.assertHashEqual(hash, form.serialize(true));
338+
},
328339

329340
testFormRequest: function() {
330341
var request = $("form").request();

0 commit comments

Comments
 (0)