Commit 927e1966 authored by Ben Alman's avatar Ben Alman Committed by John Resig

Further modified jQuery 1.4 .param() method to serialize arrays containing...

Further modified jQuery 1.4 .param() method to serialize arrays containing non-scalar values. PHP and jQuery BBQ can both deserialize these structures, while rack (as of 1.0.0) cannot.
parent aa81bb5e
...@@ -591,7 +591,10 @@ jQuery.extend({ ...@@ -591,7 +591,10 @@ jQuery.extend({
// Serialize an array of form elements or a set of // Serialize an array of form elements or a set of
// key/values into a query string // key/values into a query string
param: function( a ) { param: function( a ) {
var s = [], var s = [],
// Set jQuery.param.traditional to true for jQuery <= 1.3.2 behavior.
param_traditional = jQuery.param.traditional; param_traditional = jQuery.param.traditional;
function add( key, value ){ function add( key, value ){
...@@ -600,44 +603,50 @@ jQuery.extend({ ...@@ -600,44 +603,50 @@ jQuery.extend({
s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value); s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(value);
} }
// If an array was passed in, assume that it is an array // Recursively encode parameters from object.
// of form elements function buildParams( prefix, obj ) {
if ( jQuery.isArray(a) || a.jquery ) {
// Serialize the form elements
jQuery.each( a, function() {
add( this.name, this.value );
});
} else {
// Encode parameters from object, recursively. If
// jQuery.param.traditional is set, encode the "old" way
// (the way 1.3.2 or older did it)
jQuery.each( a, function buildParams( prefix, obj ) {
if ( jQuery.isArray(obj) ) { if ( jQuery.isArray(obj) ) {
// Serialize array item.
jQuery.each( obj, function(i,v){ jQuery.each( obj, function(i,v){
// Due to rails' limited request param syntax, numeric array
// indices are not supported. To avoid serialization ambiguity
// issues, serialized arrays can only contain scalar values. php
// does not have this issue, but we should go with the lowest
// common denominator
add( prefix + ( param_traditional ? "" : "[]" ), v );
});
} else if ( typeof obj == "object" ) {
if ( param_traditional ) { if ( param_traditional ) {
add( prefix, obj ); add( prefix, v );
} else { } else {
// If array item is non-scalar (array or object), encode its numeric
// index to resolve deserialization ambiguity issues. Note that rack
// (as of 1.0.0) can't currently deserialize nested arrays properly,
// and attempting to do so may cause a server error. Possible fixes
// are to modify rack's deserialization algorithm or to provide an
// option or flag to force array serialization to be shallow.
buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
}
});
} else if ( !param_traditional && typeof obj === "object" ) {
// Serialize object item.
jQuery.each( obj, function(k,v){ jQuery.each( obj, function(k,v){
buildParams( prefix ? prefix + "[" + k + "]" : k, v ); buildParams( prefix + "[" + k + "]", v );
}); });
}
} else { } else {
// Serialize scalar item.
add( prefix, obj ); add( prefix, obj );
} }
}
// If an array was passed in, assume that it is an array of form elements.
if ( jQuery.isArray(a) || a.jquery ) {
// Serialize the form elements
jQuery.each( a, function() {
add( this.name, this.value );
}); });
} else {
// If jQuery.param.traditional is set, encode the "old" way (the way
// 1.3.2 or older did it), otherwise encode params recursively.
jQuery.each( a, buildParams );
} }
// Return the resulting serialization // Return the resulting serialization
return s.join("&").replace(r20, "+"); return s.join("&").replace(r20, "+");
} }
......
...@@ -251,7 +251,7 @@ test("serialize()", function() { ...@@ -251,7 +251,7 @@ test("serialize()", function() {
}); });
test("jQuery.param()", function() { test("jQuery.param()", function() {
expect(13); expect(15);
equals( jQuery.param.traditional, undefined, "traditional flag, undefined by default" ); equals( jQuery.param.traditional, undefined, "traditional flag, undefined by default" );
...@@ -271,7 +271,10 @@ test("jQuery.param()", function() { ...@@ -271,7 +271,10 @@ test("jQuery.param()", function() {
equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" ); equals( jQuery.param(params), "foo%5Bbar%5D=baz&foo%5Bbeep%5D=42&foo%5Bquux%5D=All+your+base+are+belong+to+us", "even more arrays" );
params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
equals( jQuery.param(params), "a%5B%5D=1&a%5B%5D=2&b%5Bc%5D=3&b%5Bd%5D%5B%5D=4&b%5Bd%5D%5B%5D=5&b%5Be%5D%5Bx%5D%5B%5D=6&b%5Be%5D%5By%5D=7&b%5Be%5D%5Bz%5D%5B%5D=8&b%5Be%5D%5Bz%5D%5B%5D=9&b%5Bf%5D=true&b%5Bg%5D=false&b%5Bh%5D=undefined&i%5B%5D=10&i%5B%5D=11&j=true&k=false&l%5B%5D=undefined&l%5B%5D=0&m=cowboy+hat%3F", "huge structure" ); equals( decodeURIComponent( jQuery.param(params) ), "a[]=1&a[]=2&b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9&b[f]=true&b[g]=false&b[h]=undefined&i[]=10&i[]=11&j=true&k=false&l[]=undefined&l[]=0&m=cowboy+hat?", "huge structure" );
params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
equals( decodeURIComponent( jQuery.param(params) ), "a[]=0&a[1][]=1&a[1][]=2&a[2][]=3&a[2][1][]=4&a[2][1][]=5&a[2][2][]=6&a[3][b][]=7&a[3][b][1][]=8&a[3][b][1][]=9&a[3][b][2][0][c]=10&a[3][b][2][0][d]=11&a[3][b][3][0][]=12&a[3][b][4][0][0][]=13&a[3][b][5][e][f][g][]=14&a[3][b][5][e][f][g][1][]=15&a[3][b][]=16&a[]=17", "nested arrays" );
jQuery.param.traditional = true; jQuery.param.traditional = true;
...@@ -293,6 +296,9 @@ test("jQuery.param()", function() { ...@@ -293,6 +296,9 @@ test("jQuery.param()", function() {
params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" }; params = { a:[1,2], b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }, f:true, g:false, h:undefined }, i:[10,11], j:true, k:false, l:[undefined,0], m:"cowboy hat?" };
equals( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure" ); equals( jQuery.param(params), "a=1&a=2&b=%5Bobject+Object%5D&i=10&i=11&j=true&k=false&l=undefined&l=0&m=cowboy+hat%3F", "huge structure" );
params = { a: [ 0, [ 1, 2 ], [ 3, [ 4, 5 ], [ 6 ] ], { b: [ 7, [ 8, 9 ], [ { c: 10, d: 11 } ], [ [ 12 ] ], [ [ [ 13 ] ] ], { e: { f: { g: [ 14, [ 15 ] ] } } }, 16 ] }, 17 ] };
equals( jQuery.param(params), "a=0&a=1%2C2&a=3%2C4%2C5%2C6&a=%5Bobject+Object%5D&a=17", "nested arrays (not possible when jQuery.param.traditional == true)" );
}); });
test("synchronous request", function() { test("synchronous request", function() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment