Join the Stack Overflow Community
Stack Overflow is a community of 6.4 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

Just wondering if there is anything built-in to Javascript that can take a Form and return the query parameters, eg: "var1=value&var2=value2&arr[]=foo&arr[]=bar..."

I've been wondering this for years.

share|improve this question
    
1  
possible duplicate of Create query parameters in javascript – Moes Apr 22 '15 at 1:19

12 Answers 12

up vote 3 down vote accepted

I tried to search for an answer to this question some while ago, but I ended up writing my own function that extracts the values from the form ..

it's not perfect but it fits my needs.

function form_params( form )
{
    var params = new Array()
    var length = form.elements.length
    for( var i = 0; i < length; i++ )
    {
        element = form.elements[i]

        if(element.tagName == 'TEXTAREA' )
        {
            params[element.name] = element.value
        }
        else if( element.tagName == 'INPUT' )
        {
            if( element.type == 'text' || element.type == 'hidden' || element.type == 'password')
            {
                params[element.name] = element.value
            }
            else if( element.type == 'radio' && element.checked )
            {
                if( !element.value )
                    params[element.name] = "on"
                else
                    params[element.name] = element.value

            }
            else if( element.type == 'checkbox' && element.checked )
            {
                if( !element.value )
                    params[element.name] = "on"
                else
                    params[element.name] = element.value
            }
        }
    }
    return params;
}

form_params returns a (key -> value) mapping of the parameters. the input is the form element (DOM Element)

It doesn't handle fields that allow multiple selection.

share|improve this answer
    
I have the same code :D It beats including some giant framework. – Kevin Dente Nov 25 '08 at 9:55
20  
Is it just me or does this not answer the question at all? He was asking for a query string, not a mapped array. – Jake Wilson Jan 28 '13 at 22:19
    
@JakeWilson Yeah, this answer only half answers the question. The array still needs to get into a query string format. – Hutch Moore May 26 at 21:22

If you're using jQuery you might want to check out jQuery.param() http://api.jquery.com/jQuery.param/

Example:

var 
    params = {
        parameter1: 'value1',
        parameter2: 'value2',
        parameter3: 'value3' 
    },
    ​query = $.param(params);
document.write(query);
share|improve this answer
7  
This is actually the correct answer! The query string for a form is $.param($('#myform').serializeArray()). – Jesse Mar 5 '14 at 6:26
7  
@Jesse, that would be the same result as: $('#myform').serialize() – cleaver May 29 '14 at 17:26
43  
jQuery !== JavaScript – gphilip Sep 3 '14 at 9:31
1  
@gphilip Well that's why I started the response with "If you're using jQuery ...". Otherwise if you want to implement it in vanilla JS you can examine the implementation of jQuery.param() here github.com/jquery/jquery/blob/master/src/serialize.js :) – techouse Oct 25 at 14:23

This doesn't directly answer your question, but here's a generic function which will create a URL that contains query string parameters. The parameters (names and values) are safely escaped for inclusion in a URL.

function buildUrl(url, parameters){
  var qs = "";
  for(var key in parameters) {
    var value = parameters[key];
    qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
  }
  if (qs.length > 0){
    qs = qs.substring(0, qs.length-1); //chop off last "&"
    url = url + "?" + qs;
  }
  return url;
}

// example:
var url = "http://example.com/";

var parameters = {
  name: "George Washington",
  dob: "17320222"
};

console.log(buildUrl(url, parameters));
// => http://www.example.com/?name=George%20Washington&dob=17320222
share|improve this answer
1  
Is there any built-in function similar to this one in one of the populars javascript frameworks like jquery, mootools, etc...? – Samuel Oct 2 '12 at 19:10
    
A more robust native JavaScript solution is at stackoverflow.com/a/1714899/1269037 – Dan Dascalescu Nov 18 '13 at 12:12
    
Weirdest implementation ever, why do you need to initialize a new Array while you actually use it as an object? o,O – Umut Sirin Aug 29 at 23:40
    
@UmutSirin Lol yeah I didn't know a lot about Javascript at the time. xD I think I was treating it like a PHP array. Feel free to refactor if you want. – Michael Aug 30 at 18:59
    
@Michael Haha, yeah. I just sent an edit. Thank you for the answer! – Umut Sirin Sep 2 at 1:47

With jQuery you can do this by $.param

$.param({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })

// -> "action=ship&order_id=123&fees%5B%5D=f1&fees%5B%5D=f2&label=a+demo"
share|improve this answer

Without jQuery

var params = {
    parameter1: 'value_1',
    parameter2: 'value 2',
    parameter3: 'value&3' 
};

var esc = encodeURIComponent;
var query = Object.keys(params)
    .map(k => esc(k) + '=' + esc(params[k]))
    .join('&');
share|improve this answer
1  
Best solution I've seen yet - very clean and concise. A couple of caveats, though. 1) in the .map(), both k and params[k] should be encoded, e.g. encodeURIComponent(k) and encodeURIComponent(params[k]). 2) You are allowed to have more than one instance of a named parameter in a query string. If you want that capability, you'll have to use an array instead of an object (most applications won't want or need that). – user1738579 Mar 4 at 14:13
3  
3) Not all browsers will support arrow function syntax (that requires ES5). If you want to support all browsers (and encode the parts), replace the above .map() with .map(function(k) {return encodeURIComponent(k) + '=' + encodeURIComponent(params[k]);}) – user1738579 Mar 4 at 14:13

No, I don't think standard JavaScript has that built in, but Prototype JS has that function (surely most other JS frameworks have too, but I don't know them), they call it serialize.

I can reccomend Prototype JS, it works quite okay. The only drawback I've really noticed it it's size (a few hundred kb) and scope (lots of code for ajax, dom, etc.). Thus if you only want a form serializer it's overkill, and strictly speaking if you only want it's Ajax functionality (wich is mainly what I used it for) it's overkill. Unless you're careful you may find that it does a little too much "magic" (like extending every dom element it touches with Prototype JS functions just to find elements) making it slow on extreme cases.

share|improve this answer
    
Just wondering if there's anything built-in. Seems like there should be. I hate prototype, but I'm not holding that against you :) – Kevin Dente Nov 25 '08 at 9:53
    
When JavaScript was designed, Ajax was not yet discovered, therfore parsing a form just to get the querystring (that it would creati itself when submitted) probably did not make much sense. Today it does, tough... Btw, compared to script.aculo.us, prototype is nice. :) – Stein G. Strindhaug Nov 25 '08 at 10:34

If you don't want to use a library, this should cover most/all of the same form element types.

function serialize(form) {
  if (!form || !form.elements) return;

  var serial = [], i, j, first;
  var add = function (name, value) {
    serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
  }

  var elems = form.elements;
  for (i = 0; i < elems.length; i += 1, first = false) {
    if (elems[i].name.length > 0) { /* don't include unnamed elements */
      switch (elems[i].type) {
        case 'select-one': first = true;
        case 'select-multiple':
          for (j = 0; j < elems[i].options.length; j += 1)
            if (elems[i].options[j].selected) {
              add(elems[i].name, elems[i].options[j].value);
              if (first) break; /* stop searching for select-one */
            }
          break;
        case 'checkbox':
        case 'radio': if (!elems[i].checked) break; /* else continue */
        default: add(elems[i].name, elems[i].value); break;
      }
    }
  }

  return serial.join('&');
}
share|improve this answer
    
Thanks! I was just facing the same problem as the original poster, and your function was exactly what I needed. – dagw Feb 3 '09 at 10:31

I'm not entirely certain myself, I recall seeing jQuery did it to an extent, but it doesn't handle hierarchical records at all, let alone in a php friendly way.

One thing I do know for certain, is when building URLs and sticking the product into the dom, don't just use string-glue to do it, or you'll be opening yourself to a handy page breaker.

For instance, certain advertising software in-lines the version string from whatever runs your flash. This is fine when its adobes generic simple string, but however, that's very naive, and blows up in an embarrasing mess for people whom have installed Gnash, as gnash'es version string happens to contain a full blown GPL copyright licences, complete with URLs and <a href> tags. Using this in your string-glue advertiser generator, results in the page blowing open and having imbalanced HTML turning up in the dom.

The moral of the story:

   var foo = document.createElement("elementnamehere"); 
   foo.attribute = allUserSpecifiedDataConsideredDangerousHere; 
   somenode.appendChild(foo); 

Not:

   document.write("<elementnamehere attribute=\"" 
        + ilovebrokenwebsites 
        + "\">" 
        + stringdata 
        + "</elementnamehere>");

Google need to learn this trick. I tried to report the problem, they appear not to care.

share|improve this answer
    
Right on. Document.write is so 1995, anyway. – Kevin Dente Nov 25 '08 at 9:37

As Stein says, you can use the prototype javascript library from http://www.prototypejs.org. Include the JS and it is very simple then, $('formName').serialize() will return what you want!

share|improve this answer

You don't actually need a form to do this with Prototype. Just use Object.toQueryString function:

Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })

// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'
share|improve this answer

For those of us who prefer jQuery, you would use the form plugin: http://plugins.jquery.com/project/form, which contains a formSerialize method.

share|improve this answer

Is is probably too late to answer your question.
I had the same question and I didn't like to keep appending strings to create a URL. So, I started using $.param as techhouse explained.
I also found a URI.js library that creates the URLs easily for you. There are several examples that will help you: URI.js Documentation.
Here is one of them:

var uri = new URI("?hello=world");
uri.setSearch("hello", "mars"); // returns the URI instance for chaining
// uri == "?hello=mars"

uri.setSearch({ foo: "bar", goodbye : ["world", "mars"] });
// uri == "?hello=mars&foo=bar&goodbye=world&goodbye=mars"

uri.setSearch("goodbye", "sun");
// uri == "?hello=mars&foo=bar&goodbye=sun"

// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.setSearch("foo", ["bar", "baz"]);
uri.setSearch("foo[]", ["bar", "baz"]);`
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.