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.
149 lines
3.8 KiB
149 lines
3.8 KiB
/** |
|
* 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);
|
|
|