PageSourceSearch

https://www.fundable.com/web/v1/js/other/form2js.js?_cache=1790843367

js fundable.com collected 2026-10-01 08:31:48 UTC 9,267 bytes, 338 lines download raw bytes

1/**
2 * Copyright (c) 2010 Maxim Vasiliev
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 *
22 * @author Maxim Vasiliev
23 * Date: 09.09.2010
24 * Time: 19:02:33
25 */
26
27
28(function (root, factory)
29{
30	if (typeof define === 'function' && define.amd)
31	{
32		// AMD. Register as an anonymous module.
33		define(factory);
34	}
35	else
36	{
37		// Browser globals
38		root.form2js = factory();
39	}
40}(this, function ()
41{
42	"use strict";
43
44	/**
45	 * Returns form values represented as Javascript object
46	 * "name" attribute defines structure of resulting object
47	 *
48	 * @param rootNode {Element|String} root form element (or it's id) or array of root elements
49	 * @param delimiter {String} structure parts delimiter defaults to '.'
50	 * @param skipEmpty {Boolean} should skip empty text values, defaults to true
51	 * @param nodeCallback {Function} custom function to get node value
52	 * @param useIdIfEmptyName {Boolean} if true value of id attribute of field will be used if name of field is empty
53	 */
54	function form2js(rootNode, delimiter, skipEmpty, nodeCallback, useIdIfEmptyName)
55	{
56		if (typeof skipEmpty == 'undefined' || skipEmpty == null) skipEmpty = true;
57		if (typeof delimiter == 'undefined' || delimiter == null) delimiter = '.';
58		if (arguments.length < 5) useIdIfEmptyName = false;
59
60		rootNode = typeof rootNode == 'string' ? document.getElementById(rootNode) : rootNode;
61
62		var formValues = [],
63			currNode,
64			i = 0;
65
66		/* If rootNode is array - combine values */
67		if (rootNode.constructor == Array || (typeof NodeList != "undefined" && rootNode.constructor == NodeList))
68		{
69			while(currNode = rootNode[i++])
70			{
71				formValues = formValues.concat(getFormValues(currNode, nodeCallback, useIdIfEmptyName));
72			}
73		}
74		else
75		{
76			formValues = getFormValues(rootNode, nodeCallback, useIdIfEmptyName);
77		}
78
79		return processNameValues(formValues, skipEmpty, delimiter);
80	}
81
82	/**
83	 * Processes collection of { name: 'name', value: 'value' } objects.
84	 * @param nameValues
85	 * @param skipEmpty if true skips elements with value == '' or value == null
86	 * @param delimiter
87	 */
88	function processNameValues(nameValues, skipEmpty, delimiter)
89	{
90		var result = {},
91			arrays = {},
92			i, j, k, l,
93			value,
94			nameParts,
95			currResult,
96			arrNameFull,
97			arrName,
98			arrIdx,
99			namePart,
100			name,
101			_nameParts;
102
103		for (i = 0; i < nameValues.length; i++)
104		{
105			value = nameValues[i].value;
106
107			if (skipEmpty && (value === '' || value === null)) continue;
108
109			name = nameValues[i].name;
110			_nameParts = name.split(delimiter);
111			nameParts = [];
112			currResult = result;
113			arrNameFull = '';
114
115			for(j = 0; j < _nameParts.length; j++)
116			{
117				namePart = _nameParts[j].split('][');
118				if (namePart.length > 1)
119				{
120					for(k = 0; k < namePart.length; k++)
121					{
122						if (k == 0)
123						{
124							namePart[k] = namePart[k] + ']';
125						}
126						else if (k == namePart.length - 1)
127						{
128							namePart[k] = '[' + namePart[k];
129						}
130						else
131						{
132							namePart[k] = '[' + namePart[k] + ']';
133						}
134
135						arrIdx = namePart[k].match(/([a-z_]+)?\[([a-z_][a-z0-9_]+?)\]/i);
136						if (arrIdx)
137						{
138							for(l = 1; l < arrIdx.length; l++)
139							{
140								if (arrIdx[l]) nameParts.push(arrIdx[l]);
141							}
142						}
143						else{
144							nameParts.push(namePart[k]);
145						}
146					}
147				}
148				else
149					nameParts = nameParts.concat(namePart);
150			}
151
152			for (j = 0; j < nameParts.length; j++)
153			{
154				namePart = nameParts[j];
155
156				if (namePart.indexOf('[]') > -1 && j == nameParts.length - 1)
157				{
158					arrName = namePart.substr(0, namePart.indexOf('['));
159					arrNameFull += arrName;
160
161					if (!currResult[arrName]) currResult[arrName] = [];
162					currResult[arrName].push(value);
163				}
164				else if (namePart.indexOf('[') > -1)
165				{
166					arrName = namePart.substr(0, namePart.indexOf('['));
167					arrIdx = namePart.replace(/(^([a-z_]+)?\[)|(\]$)/gi, '');
168
169					/* Unique array name */
170					arrNameFull += '_' + arrName + '_' + arrIdx;
171
172					/*
173					 * Because arrIdx in field name can be not zero-based and step can be
174					 * other than 1, we can't use them in target array directly.
175					 * Instead we're making a hash where key is arrIdx and value is a reference to
176					 * added array element
177					 */
178
179					if (!arrays[arrNameFull]) arrays[arrNameFull] = {};
180					if (arrName != '' && !currResult[arrName]) currResult[arrName] = [];
181
182					if (j == nameParts.length - 1)
183					{
184						if (arrName == '')
185						{
186							currResult.push(value);
187							arrays[arrNameFull][arrIdx] = currResult[currResult.length - 1];
188						}
189						else
190						{
191							currResult[arrName].push(value);
192							arrays[arrNameFull][arrIdx] = currResult[arrName][currResult[arrName].length - 1];
193						}
194					}
195					else
196					{
197						if (!arrays[arrNameFull][arrIdx])
198						{
199							if ((/^[a-z_]+\[?/i).test(nameParts[j+1])) currResult[arrName].push({});
200							else currResult[arrName].push([]);
201
202							arrays[arrNameFull][arrIdx] = currResult[arrName][currResult[arrName].length - 1];
203						}
204					}
205
206					currResult = arrays[arrNameFull][arrIdx];
207				}
208				else
209				{
210					arrNameFull += namePart;
211
212					if (j < nameParts.length - 1) /* Not the last part of name - means object */
213					{
214						if (!currResult[namePart]) currResult[namePart] = {};
215						currResult = currResult[namePart];
216					}
217					else
218					{
219						currResult[namePart] = value;
220					}
221				}
222			}
223		}
224
225		return result;
226	}
227
228    function getFormValues(rootNode, nodeCallback, useIdIfEmptyName)
229    {
230        var result = extractNodeValues(rootNode, nodeCallback, useIdIfEmptyName);
231        return result.length > 0 ? result : getSubFormValues(rootNode, nodeCallback, useIdIfEmptyName);
232    }
233
234    function getSubFormValues(rootNode, nodeCallback, useIdIfEmptyName)
235	{
236		var result = [],
237			currentNode = rootNode.firstChild;
238		
239		while (currentNode)
240		{
241			result = result.concat(extractNodeValues(currentNode, nodeCallback, useIdIfEmptyName));
242			currentNode = currentNode.nextSibling;
243		}
244
245		return result;
246	}
247
248    function extractNodeValues(node, nodeCallback, useIdIfEmptyName) {
249        var callbackResult, fieldValue, result, fieldName = getFieldName(node, useIdIfEmptyName);
250
251        callbackResult = nodeCallback && nodeCallback(node);
252
253        if (callbackResult && callbackResult.name) {
254            result = [callbackResult];
255        }
256        else if (fieldName != '' && node.nodeName.match(/INPUT|TEXTAREA/i)) {
257            fieldValue = getFieldValue(node);
258			result = [ { name: fieldName, value: fieldValue} ];
259        }
260        else if (fieldName != '' && node.nodeName.match(/SELECT/i)) {
261	        fieldValue = getFieldValue(node);
262	        result = [ { name: fieldName.replace(/\[\]$/, ''), value: fieldValue } ];
263        }
264        else {
265            result = getSubFormValues(node, nodeCallback, useIdIfEmptyName);
266        }
267
268        return result;
269    }
270
271	function getFieldName(node, useIdIfEmptyName)
272	{
273		if (node.name && node.name != '') return node.name;
274		else if (useIdIfEmptyName && node.id && node.id != '') return node.id;
275		else return '';
276	}
277
278
279	function getFieldValue(fieldNode)
280	{
281		if (fieldNode.disabled) return null;
282		
283		switch (fieldNode.nodeName) {
284			case 'INPUT':
285			case 'TEXTAREA':
286				switch (fieldNode.type.toLowerCase()) {
287					case 'radio':
288			if (fieldNode.checked && fieldNode.value === "false") return false;
289					case 'checkbox':
290                        if (fieldNode.checked && fieldNode.value === "true") return true;
291                        if (!fieldNode.checked && fieldNode.value === "true") return false;
292			if (fieldNode.checked) return fieldNode.value;
293						break;
294
295					case 'button':
296					case 'reset':
297					case 'submit':
298					case 'image':
299						return '';
300						break;
301
302					default:
303						return fieldNode.value;
304						break;
305				}
306				break;
307
308			case 'SELECT':
309				return getSelectedOptionValue(fieldNode);
310				break;
311
312			default:
313				break;
314		}
315
316		return null;
317	}
318
319	function getSelectedOptionValue(selectNode)
320	{
321		var multiple = selectNode.multiple,
322			result = [],
323			options,
324			i, l;
325
326		if (!multiple) return selectNode.value;
327
328		for (options = selectNode.getElementsByTagName("option"), i = 0, l = options.length; i < l; i++)
329		{
330			if (options[i].selected) result.push(options[i].value);
331		}
332
333		return result;
334	}
335
336	return form2js;
337
338}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.