Skip to content

Commit

Permalink
Serialize form elements to string in the order in which they appear i…
Browse files Browse the repository at this point in the history
…n the DOM
  • Loading branch information
duncanbeevers authored and tobie committed May 13, 2010
1 parent 339bc8c commit 876ece6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 11 deletions.
31 changes: 20 additions & 11 deletions src/dom/form.js
Expand Up @@ -104,25 +104,34 @@ var Form = {
// default true, as that's the new preferred approach.
if (typeof options != 'object') options = { hash: !!options };
else if (Object.isUndefined(options.hash)) options.hash = true;
var key, value, submitted = false, submit = options.submit;

var data = elements.inject({ }, function(result, element) {
var key, value, submitted = false, submit = options.submit, accumulator, initial;

if (options.hash) {
initial = {};
accumulator = function(result, key, value) {
if (key in result) {
if (!Object.isArray(result[key])) result[key] = [result[key]];
result[key].push(value);
} else result[key] = value;
return result;
};
} else {
initial = '';
accumulator = function(result, key, value) {
return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
}
}

return elements.inject(initial, function(result, element) {
if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue();
if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
submit !== false && (!submit || key == submit) && (submitted = true)))) {
if (key in result) {
// a key is already present; construct an array of values
if (!Object.isArray(result[key])) result[key] = [result[key]];
result[key].push(value);
}
else result[key] = value;
result = accumulator(result, key, value);
}
}
return result;
});

return options.hash ? data : Object.toQueryString(data);
}
};

Expand Down
11 changes: 11 additions & 0 deletions test/unit/fixtures/form.html
Expand Up @@ -106,3 +106,14 @@
</form>

</div>

<form id="form_with_duplicate_input_names" style="display:none">
<input type="hidden" name="fact" id="fdn_f_1" value="sea-wet" />
<input type="hidden" name="opinion" id="fnd_o_1" value="sea-cold" />
<input type="hidden" name="fact" id="fnd_f_2" value="sun-hot" />
<input type="hidden" name="opinion" id="fnd_o_2" value="sun-ugly" />
</form>

<form id="form_with_inputs_needing_encoding" style="display:none">
<input type="hidden" name="user[wristbands][][nickname]" id="fine_1" value="Hässlich" />
</form>
8 changes: 8 additions & 0 deletions test/unit/form_test.js
Expand Up @@ -280,6 +280,14 @@ new Test.Unit.Runner({
this.assertEqual('', $('form_with_file_input').serialize());
},

testFormSerializeWithDuplicateNames: function() {
this.assertEqual("fact=sea-wet&opinion=sea-cold&fact=sun-hot&opinion=sun-ugly", $('form_with_duplicate_input_names').serialize(false));
},

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

testFormMethodsOnExtendedElements: function() {
var form = $('form');
this.assertEqual(Form.serialize('form'), form.serialize());
Expand Down

0 comments on commit 876ece6

Please sign in to comment.