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