Created
January 20, 2009 18:58
-
-
Save mcmire/49602 to your computer and use it in GitHub Desktop.
Extending Prototype to retain order of form data when sending an Ajax request
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Object.extend(Object, { | |
clone: function(object) { | |
return object.clone ? object.clone() : Object.extend({ }, object); | |
}, | |
toQueryString: function(object) { | |
return object.toQueryString ? object.toQueryString() : $H(object).toQueryString() | |
} | |
}); | |
var PseudoHash = Class.create(Hash, (function() { | |
function toQueryPair(key, value) { | |
if (Object.isUndefined(value)) return key; | |
return key + '=' + encodeURIComponent(String.interpret(value)); | |
} | |
return { | |
initialize: function(object) { | |
this._object = object ? (object.toArray ? object.toArray() : object) : []; | |
}, | |
_each: function(iterator) { | |
for (var i=0, len=this._object.length; i<len; i++) { | |
var pair = this._object[i]; // do we need to clone this? | |
if (!Object.isArray(pair)) pair = [ pair.key, pair.value ]; | |
pair.key = pair[0]; | |
pair.value = pair[1]; | |
iterator(pair); | |
} | |
}, | |
set: function(key, value) { | |
this.unset(key); | |
return this._object.push({ key: key, value: value }); | |
}, | |
get: function(key) { | |
var pair = this._object.find(function(pair) { pair.key == key }); | |
return pair ? pair.value : null; | |
}, | |
unset: function(key) { | |
var value = this.get(key); | |
this._object = this._object.reject(function(pair) { pair.key == key }); | |
return value; | |
}, | |
update: function(object) { | |
return new PseudoHash(object).inject(this, function(result, pair) { | |
result.set(pair.key, pair.value); | |
return result; | |
}); | |
}, | |
toHash: function() { | |
return this.inject({}, function(h, pair) { | |
h[pair.key] = pair.value; | |
return h; | |
}); | |
}, | |
toQueryString: function() { | |
return this.map(function(pair) { | |
var key = encodeURIComponent(pair.key), values = pair.value; | |
if (values && typeof values == 'object') { | |
if (Object.isArray(values)) | |
return values.map(toQueryPair.curry(key)).join('&'); | |
} | |
return toQueryPair(key, values); | |
}).join('&'); | |
}, | |
inspect: function() { | |
return '#<PseudoHash:{' + this.map(function(pair) { | |
return pair.map(Object.inspect).join(': '); | |
}).join(', ') + '}>'; | |
}, | |
clone: function() { | |
return new PseudoHash(this); | |
} | |
} | |
})()); | |
String.prototype.toQueryParams = function(separator) { | |
var match = this.strip().match(/([^?#]*)(#.*)?$/); | |
if (!match) return { }; | |
return match[1].split(separator || '&').inject((new PseudoHash), function(hash, pair) { | |
if ((pair = pair.split('='))[0]) { | |
var key = decodeURIComponent(pair.shift()); | |
var value = pair.length > 1 ? pair.join('=') : pair[0]; | |
if (value != undefined) value = decodeURIComponent(value); | |
var v; | |
if (v = hash.get(key)) { | |
// a key is already present; construct an array of values | |
if (!Object.isArray(v)) { v = [v]; hash.set(key, v) } | |
v.push(value); | |
} | |
else hash.set(key, value); | |
} | |
return hash; | |
}); | |
}; | |
Form.serializeElements = function(elements, options) { | |
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((new PseudoHash), function(result, element) { | |
if (!element.disabled && element.name) { | |
key = element.name; value = $(element).getValue(); | |
if ( | |
value != null && | |
( | |
element.type != 'submit' || | |
(!submitted && submit !== false && (!submit || key == submit) && (submitted = true)) | |
) | |
) | |
{ | |
var v; | |
if (v = result.get(key)) { | |
// a key is already present; construct an array of values | |
if (!Object.isArray(v)) { v = [v]; result.set(key, v) } | |
v.push(value); | |
} | |
else result.set(key, value); | |
} | |
} | |
return result; | |
}); | |
if (options.hash) { | |
return data.toHash(); | |
} else { | |
return data.toQueryString(); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment