150 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * 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);
 |