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 years 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);
							 |