|
|
/** * 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);
|