Bug Tracker

Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#448 closed enhancement (fixed)

Handling Parameter Arrays

Reported by: squinn Owned by:
Priority: major Milestone:
Component: ajax Version: 1.1a
Keywords: Cc:
Blocked by: Blocking:

Description

I have a situation where I have a bunch of form elements that all have the same name, and I need to submit their values to the server as a unit using that name. I also have other data that I need to submit as part of the same request, so I'm using syntax like the following:

$.post("myurl", {

someName: [1, 2, 3], regularThing: "blah"

}); I would expect for jQuery to turn that into a URL something like:

myurl?someName=1&someName=2&someName=3&regularThing=blah

in order to follow the "normal" HTML form submission rules when more then one input element has the same name (the server side technology - in my case JSP - then normally converts the values back into an array since it sees more then one value with the same key name). Instead, jQuery is currently turning that request it into something like:

myurl?someName=1,2,3&regularThing=blah

I've changed the "param" function in my version of jQuery to handle this, and it seems to work well. Could this be added to the main distribution? The following is my updated "param" function:

Serialize an array of form elements or a set of key/values into a query string param: function(a) {

var s = [];

If an array was passed in, assume that it is an array of form elements

if ( a.constructor == Array
a.jquery ) {

Serialize the form elements for ( var i = 0; i < a.length; i++ )

s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );

Otherwise, assume that it's an object of key/value pairs } else {

Serialize the key/values for ( var j in a ) {

If the value is an array then the key names need to be repeated

if(a[j].constructor == Array) {

for ( var i = 0; i < a[j].length; i++ )

s.push( j + "=" + encodeURIComponent( a[j][i] ) );

} else {

s.push( j + "=" + encodeURIComponent( a[j] ) );

}

}

}

Return the resulting serialization return s.join("&");

}

Thanks,

-Shawn

Change History (5)

comment:1 Changed 12 years ago by squinn

Wow, that code got formatted real ugly. Here it the recommendation again more cleary:

// Serialize an array of form elements or a set of
// key/values into a query string
param: function(a) {
  var s = [];

  // If an array was passed in, assume that it is an array
  // of form elements
  if ( a.constructor == Array || a.jquery ) {
    // Serialize the form elements
    for ( var i = 0; i < a.length; i++ )
      s.push( a[i].name + "=" + encodeURIComponent( a[i].value ) );

  // Otherwise, assume that it's an object of key/value pairs
  } else {
    // Serialize the key/values
    for ( var j in a ) {
      // If the value is an array then the key names need to be repeated
      if(a[j].constructor == Array) {
        for ( var i = 0; i < a[j].length; i++ )
          s.push( j + "=" + encodeURIComponent( a[j][i] ) );
      } else {   
        s.push( j + "=" + encodeURIComponent( a[j] ) );
      }
    }
  }

  // Return the resulting serialization
  return s.join("&");
}

comment:2 Changed 12 years ago by joern

Version: 1.1

Looks good to me. If no one disagrees, it will be added to jQuery 1.1.

comment:3 Changed 12 years ago by aaron.heimli

Sounds like a good addition.

Some quick tests (don't worry, all of them check out):

var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
//foo=bar&baz=42&quux=All%20your%20base%20are%20belong%20to%20us

var params = {someName: [1, 2, 3], regularThing: "blah" };
//someName=1&someName=2&someName=3&regularThing=blah

var params = {"foo[]":["baz", 42, "All your base are belong to us"]};
foo[]=baz&foo[]=42&foo[]=All%20your%20base%20are%20belong%20to%20us

var params = {"foo[bar]":"baz", "foo[beep]":42, "foo[quux]":"All your base are belong to us"};
//foo[bar]=baz&foo[beep]=42&foo[quux]=All%20your%20base%20are%20belong%20to%20us

For those wondering about the brackets, when PHP processes the param string, it will turn

foo[]=baz&foo[]=42&foo[]=All%20your%20base%20are%20belong%20to%20us

into

an array named "foo" that looks like this:

$foo[0] = "baz"
$foo[1] = 42
$foo[2] = "All your base are belong to us"

and

foo[bar]=baz&foo[beep]=42&foo[quux]=All%20your%20base%20are%20belong%20to%20us

into an associative array named "foo" that looks like this:

$foo['bar'] = "baz"
$foo['beep'] = 42
$foo['quux'] = "All your base are belong to us"

comment:4 Changed 12 years ago by andrea ercol

good

comment:5 Changed 12 years ago by joern

Resolution: fixed
Status: newclosed

Fixed in SVN.

Note: See TracTickets for help on using tickets.