You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
3.8 KiB
150 lines
3.8 KiB
2 weeks ago
|
/**
|
||
|
* Functions for manipulating web forms.
|
||
|
*
|
||
|
* @author David I. Lehn <dlehn@digitalbazaar.com>
|
||
|
* @author Dave Longley
|
||
|
* @author Mike Johnson
|
||
|
*
|
||
|
* Copyright (c) 2011-2014 Digital Bazaar, Inc. All rights reserved.
|
||
|
*/
|
||
|
var forge = require('./forge');
|
||
|
|
||
|
/* Form API */
|
||
|
var form = module.exports = forge.form = forge.form || {};
|
||
|
|
||
|
(function($) {
|
||
|
|
||
|
/**
|
||
|
* Regex for parsing a single name property (handles array brackets).
|
||
|
*/
|
||
|
var _regex = /([^\[]*?)\[(.*?)\]/g;
|
||
|
|
||
|
/**
|
||
|
* Parses a single name property into an array with the name and any
|
||
|
* array indices.
|
||
|
*
|
||
|
* @param name the name to parse.
|
||
|
*
|
||
|
* @return the array of the name and its array indices in order.
|
||
|
*/
|
||
|
var _parseName = function(name) {
|
||
|
var rval = [];
|
||
|
|
||
|
var matches;
|
||
|
while(!!(matches = _regex.exec(name))) {
|
||
|
if(matches[1].length > 0) {
|
||
|
rval.push(matches[1]);
|
||
|
}
|
||
|
if(matches.length >= 2) {
|
||
|
rval.push(matches[2]);
|
||
|
}
|
||
|
}
|
||
|
if(rval.length === 0) {
|
||
|
rval.push(name);
|
||
|
}
|
||
|
|
||
|
return rval;
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Adds a field from the given form to the given object.
|
||
|
*
|
||
|
* @param obj the object.
|
||
|
* @param names the field as an array of object property names.
|
||
|
* @param value the value of the field.
|
||
|
* @param dict a dictionary of names to replace.
|
||
|
*/
|
||
|
var _addField = function(obj, names, value, dict) {
|
||
|
// combine array names that fall within square brackets
|
||
|
var tmp = [];
|
||
|
for(var i = 0; i < names.length; ++i) {
|
||
|
// check name for starting square bracket but no ending one
|
||
|
var name = names[i];
|
||
|
if(name.indexOf('[') !== -1 && name.indexOf(']') === -1 &&
|
||
|
i < names.length - 1) {
|
||
|
do {
|
||
|
name += '.' + names[++i];
|
||
|
} while(i < names.length - 1 && names[i].indexOf(']') === -1);
|
||
|
}
|
||
|
tmp.push(name);
|
||
|
}
|
||
|
names = tmp;
|
||
|
|
||
|
// split out array indexes
|
||
|
var tmp = [];
|
||
|
$.each(names, function(n, name) {
|
||
|
tmp = tmp.concat(_parseName(name));
|
||
|
});
|
||
|
names = tmp;
|
||
|
|
||
|
// iterate over object property names until value is set
|
||
|
$.each(names, function(n, name) {
|
||
|
// do dictionary name replacement
|
||
|
if(dict && name.length !== 0 && name in dict) {
|
||
|
name = dict[name];
|
||
|
}
|
||
|
|
||
|
// blank name indicates appending to an array, set name to
|
||
|
// new last index of array
|
||
|
if(name.length === 0) {
|
||
|
name = obj.length;
|
||
|
}
|
||
|
|
||
|
// value already exists, append value
|
||
|
if(obj[name]) {
|
||
|
// last name in the field
|
||
|
if(n == names.length - 1) {
|
||
|
// more than one value, so convert into an array
|
||
|
if(!$.isArray(obj[name])) {
|
||
|
obj[name] = [obj[name]];
|
||
|
}
|
||
|
obj[name].push(value);
|
||
|
} else {
|
||
|
// not last name, go deeper into object
|
||
|
obj = obj[name];
|
||
|
}
|
||
|
} else if(n == names.length - 1) {
|
||
|
// new value, last name in the field, set value
|
||
|
obj[name] = value;
|
||
|
} else {
|
||
|
// new value, not last name, go deeper
|
||
|
// get next name
|
||
|
var next = names[n + 1];
|
||
|
|
||
|
// blank next value indicates array-appending, so create array
|
||
|
if(next.length === 0) {
|
||
|
obj[name] = [];
|
||
|
} else {
|
||
|
// if next name is a number create an array, otherwise a map
|
||
|
var isNum = ((next - 0) == next && next.length > 0);
|
||
|
obj[name] = isNum ? [] : {};
|
||
|
}
|
||
|
obj = obj[name];
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Serializes a form to a JSON object. Object properties will be separated
|
||
|
* using the given separator (defaults to '.') and by square brackets.
|
||
|
*
|
||
|
* @param input the jquery form to serialize.
|
||
|
* @param sep the object-property separator (defaults to '.').
|
||
|
* @param dict a dictionary of names to replace (name=replace).
|
||
|
*
|
||
|
* @return the JSON-serialized form.
|
||
|
*/
|
||
|
form.serialize = function(input, sep, dict) {
|
||
|
var rval = {};
|
||
|
|
||
|
// add all fields in the form to the object
|
||
|
sep = sep || '.';
|
||
|
$.each(input.serializeArray(), function() {
|
||
|
_addField(rval, this.name.split(sep), this.value || '', dict);
|
||
|
});
|
||
|
|
||
|
return rval;
|
||
|
};
|
||
|
|
||
|
})(jQuery);
|