1
|
/**
|
2
|
* Functions for manipulating web forms.
|
3
|
*
|
4
|
* @author David I. Lehn <dlehn@digitalbazaar.com>
|
5
|
* @author Dave Longley
|
6
|
* @author Mike Johnson
|
7
|
*
|
8
|
* Copyright (c) 2011-2014 Digital Bazaar, Inc. All rights reserved.
|
9
|
*/
|
10
|
var forge = require('./forge');
|
11
|
|
12
|
/* Form API */
|
13
|
var form = module.exports = forge.form = forge.form || {};
|
14
|
|
15
|
(function($) {
|
16
|
|
17
|
/**
|
18
|
* Regex for parsing a single name property (handles array brackets).
|
19
|
*/
|
20
|
var _regex = /([^\[]*?)\[(.*?)\]/g;
|
21
|
|
22
|
/**
|
23
|
* Parses a single name property into an array with the name and any
|
24
|
* array indices.
|
25
|
*
|
26
|
* @param name the name to parse.
|
27
|
*
|
28
|
* @return the array of the name and its array indices in order.
|
29
|
*/
|
30
|
var _parseName = function(name) {
|
31
|
var rval = [];
|
32
|
|
33
|
var matches;
|
34
|
while(!!(matches = _regex.exec(name))) {
|
35
|
if(matches[1].length > 0) {
|
36
|
rval.push(matches[1]);
|
37
|
}
|
38
|
if(matches.length >= 2) {
|
39
|
rval.push(matches[2]);
|
40
|
}
|
41
|
}
|
42
|
if(rval.length === 0) {
|
43
|
rval.push(name);
|
44
|
}
|
45
|
|
46
|
return rval;
|
47
|
};
|
48
|
|
49
|
/**
|
50
|
* Adds a field from the given form to the given object.
|
51
|
*
|
52
|
* @param obj the object.
|
53
|
* @param names the field as an array of object property names.
|
54
|
* @param value the value of the field.
|
55
|
* @param dict a dictionary of names to replace.
|
56
|
*/
|
57
|
var _addField = function(obj, names, value, dict) {
|
58
|
// combine array names that fall within square brackets
|
59
|
var tmp = [];
|
60
|
for(var i = 0; i < names.length; ++i) {
|
61
|
// check name for starting square bracket but no ending one
|
62
|
var name = names[i];
|
63
|
if(name.indexOf('[') !== -1 && name.indexOf(']') === -1 &&
|
64
|
i < names.length - 1) {
|
65
|
do {
|
66
|
name += '.' + names[++i];
|
67
|
} while(i < names.length - 1 && names[i].indexOf(']') === -1);
|
68
|
}
|
69
|
tmp.push(name);
|
70
|
}
|
71
|
names = tmp;
|
72
|
|
73
|
// split out array indexes
|
74
|
var tmp = [];
|
75
|
$.each(names, function(n, name) {
|
76
|
tmp = tmp.concat(_parseName(name));
|
77
|
});
|
78
|
names = tmp;
|
79
|
|
80
|
// iterate over object property names until value is set
|
81
|
$.each(names, function(n, name) {
|
82
|
// do dictionary name replacement
|
83
|
if(dict && name.length !== 0 && name in dict) {
|
84
|
name = dict[name];
|
85
|
}
|
86
|
|
87
|
// blank name indicates appending to an array, set name to
|
88
|
// new last index of array
|
89
|
if(name.length === 0) {
|
90
|
name = obj.length;
|
91
|
}
|
92
|
|
93
|
// value already exists, append value
|
94
|
if(obj[name]) {
|
95
|
// last name in the field
|
96
|
if(n == names.length - 1) {
|
97
|
// more than one value, so convert into an array
|
98
|
if(!$.isArray(obj[name])) {
|
99
|
obj[name] = [obj[name]];
|
100
|
}
|
101
|
obj[name].push(value);
|
102
|
} else {
|
103
|
// not last name, go deeper into object
|
104
|
obj = obj[name];
|
105
|
}
|
106
|
} else if(n == names.length - 1) {
|
107
|
// new value, last name in the field, set value
|
108
|
obj[name] = value;
|
109
|
} else {
|
110
|
// new value, not last name, go deeper
|
111
|
// get next name
|
112
|
var next = names[n + 1];
|
113
|
|
114
|
// blank next value indicates array-appending, so create array
|
115
|
if(next.length === 0) {
|
116
|
obj[name] = [];
|
117
|
} else {
|
118
|
// if next name is a number create an array, otherwise a map
|
119
|
var isNum = ((next - 0) == next && next.length > 0);
|
120
|
obj[name] = isNum ? [] : {};
|
121
|
}
|
122
|
obj = obj[name];
|
123
|
}
|
124
|
});
|
125
|
};
|
126
|
|
127
|
/**
|
128
|
* Serializes a form to a JSON object. Object properties will be separated
|
129
|
* using the given separator (defaults to '.') and by square brackets.
|
130
|
*
|
131
|
* @param input the jquery form to serialize.
|
132
|
* @param sep the object-property separator (defaults to '.').
|
133
|
* @param dict a dictionary of names to replace (name=replace).
|
134
|
*
|
135
|
* @return the JSON-serialized form.
|
136
|
*/
|
137
|
form.serialize = function(input, sep, dict) {
|
138
|
var rval = {};
|
139
|
|
140
|
// add all fields in the form to the object
|
141
|
sep = sep || '.';
|
142
|
$.each(input.serializeArray(), function() {
|
143
|
_addField(rval, this.name.split(sep), this.value || '', dict);
|
144
|
});
|
145
|
|
146
|
return rval;
|
147
|
};
|
148
|
|
149
|
})(jQuery);
|