app/assets/javascripts/plugins/jquerymx.deparam.js

Summary

Maintainability
A
3 hrs
Test Coverage
var digitTest = /^\d+$/,
    keyBreaker = /([^\[\]]+)|(\[\])/g,
    plus = /\+/g,
    paramTest = /([^?#]*)(#.*)?$/;

/**
 * @add jQuery.String
 */
$.String = $.extend($.String || {}, { 

  /**
   * @function deparam
   *
   * Takes a string of name value pairs and returns a Object literal that represents those params.
   *
   * @param {String} params a string like <code>"foo=bar&person[age]=3"</code>
   * @return {Object} A JavaScript Object that represents the params:
   *
   *     {
   *       foo: "bar",
   *       person: {
   *         age: "3"
   *       }
   *     }
   */
  deparam: function(params){

    if(! params) {
      return {};
    } 

    var data = {},
      pairs = params.split('&'),
      current;

    for(var i=0; i < pairs.length; i++){
      current = data;
      var pair = pairs[i].split('=');

      // if we find foo=1+1=2
      if(pair.length != 2) { 
        pair = [pair[0], pair.slice(1).join("=")]
      }

      var key = decodeURIComponent(pair[0].replace(plus, " ")), 
        value = decodeURIComponent(pair[1].replace(plus, " ")),
        parts = key.match(keyBreaker);

      for ( var j = 0; j < parts.length - 1; j++ ) {
        var part = parts[j];
        if (!current[part] ) {
          // if what we are pointing to looks like an array
          current[part] = digitTest.test(parts[j+1]) || parts[j+1] == "[]" ? [] : {}
        }
        current = current[part];
      }
      lastPart = parts[parts.length - 1];
      if(lastPart == "[]"){
        current.push(value)
      }else{
        current[lastPart] = value;
      }
    }
    return data;
  }
});