108 lines
3.9 KiB
JavaScript
108 lines
3.9 KiB
JavaScript
(function($) {
|
|
|
|
/**
|
|
* Go through the current JQuery match, and build a
|
|
* javascript object based on the name attributes of
|
|
* child elements. This is intended to be used for forms
|
|
* with inputs: var jsObj = $('#myform').formToObject();
|
|
*
|
|
* Using dots in the name attributes will build nested
|
|
* structures into the resulting object:
|
|
*
|
|
* <input name="foo.bar" value="x" />
|
|
* returns
|
|
* { foo: { bar:"x" } }
|
|
*
|
|
* The same name appearing twice will be returned as an array:
|
|
*
|
|
* <input type="checkbox" name="foo" value="a" checked="true"/>
|
|
* <input type="checkbox" name="foo" value="b" checked="true"/>
|
|
* returns
|
|
* { foo: ['a','b'] }
|
|
*
|
|
* Checkboxes and Radio inputs which are not checked will not
|
|
* appear at all, nor will any inputs which are disabled.
|
|
*
|
|
* Form fields which are optional can be omitted from the resulting
|
|
* object by providing a value for that field of "__OMIT__".
|
|
*
|
|
*/
|
|
$.fn.formToObject = function() {
|
|
// don't want to depend on other libs. Provide our own size to check
|
|
// length of an associative array:
|
|
function _size(obj) {
|
|
var key, size=0;
|
|
for (key in obj) {
|
|
if (obj.hasOwnProperty(key)) size++;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
var formObject = {},
|
|
a = this.serializeArray();
|
|
|
|
$.each(a, function() {
|
|
var data = $('[name="' + this.name + '"]').first().data(),
|
|
current = formObject,
|
|
childKey,
|
|
path = this.name.split('.'),
|
|
key = path.pop(),
|
|
val = (data && data.parseInt !== undefined && data.parseInt) ? parseInt(this.value) : (
|
|
(this.value.toLowerCase() == 'true') ? true : (
|
|
(this.value.toLowerCase() == 'false') ? false : (
|
|
(this.value.toLowerCase() == 'null') ? null : (
|
|
(typeof this.value == 'undefined') ? '' : this.value
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
while (path.length > 0) {
|
|
// Shift the front element from path into childKey
|
|
childKey = path.shift();
|
|
if (!(childKey in current)) {
|
|
current[childKey] = {};
|
|
}
|
|
// Move down and start working with the child object
|
|
current = current[childKey];
|
|
}
|
|
|
|
// We're at the right level in hierarchy. Define property next.
|
|
if (key in current) { // already exists.
|
|
if ($.isPlainObject(current[key])) { // about to overwrite obj with property!
|
|
throw "Can't overwrite named structure";
|
|
}
|
|
if (!current[key].push) { // convert property to array
|
|
current[key] = [current[key]];
|
|
}
|
|
current[key].push(val);
|
|
} else { // doesn't exist. Just set.
|
|
if (val !== '__OMIT__') {
|
|
current[key] = val;
|
|
}
|
|
}
|
|
});
|
|
|
|
// Trim any keys who hold nothing but empty objects: {}
|
|
|
|
var removeEmptyObjects = function(o) {
|
|
var k;
|
|
var trimlist = [];
|
|
for (k in o) {
|
|
if ($.isPlainObject(o[k])) { // recurse: deep first
|
|
removeEmptyObjects(o[k]);
|
|
}
|
|
if ($.isPlainObject(o[k]) && _size(o[k]) === 0) {
|
|
trimlist.push(k);
|
|
}
|
|
}
|
|
$.each(trimlist, function() {
|
|
delete o[this];
|
|
});
|
|
};
|
|
|
|
removeEmptyObjects(formObject);
|
|
return (_size(formObject) === 0) ? null : formObject;
|
|
};
|
|
|
|
})(jQuery); |