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