PageSourceSearch

https://www.socialmotus.com/js/wl_Form.js

js socialmotus.com collected 2026-10-04 21:14:43 UTC 17,870 bytes, 620 lines download raw bytes

1/*----------------------------------------------------------------------*/
2/* wl_Form v 1.1 by revaxarts.com
3/* description:	handles the serialization, unserialization and sending
4/*				of a form
5/* dependency: 	$.confirm, wl_Number*, wl_Slider*, wl_Date*, wl_Value*,
6/* 				wl_Password*, wl_File*
7/*				* only when fields are within the form
8/*----------------------------------------------------------------------*/
9
10
11$.fn.wl_Form = function (method) {
12
13	var args = arguments;
14	return this.each(function () {
15
16		var $this = $(this);
17
18		if ($.fn.wl_Form.methods[method]) {
19			return $.fn.wl_Form.methods[method].apply(this, Array.prototype.slice.call(args, 1));
20		} else if (typeof method === 'object' || !method) {
21			if ($this.data('wl_Form')) {
22				var opts = $.extend({}, $this.data('wl_Form'), method);
23			} else {
24				var opts = $.extend({}, $.fn.wl_Form.defaults, method, $this.data());
25			}
26		} else {
27			$.error('Method "' + method + '" does not exist');
28		}
29
30		//all fields within that form
31		var $inputs = $this.find('input,textarea,select,div.date,div.slider'),
32		//$required = $inputs.filter('[required]'), //Doenst work on IE7/8
33			$submitbtn = $this.find(opts.submitButton);
34
35		if (!$this.data('wl_Form')) {
36
37			$this.data('wl_Form', {});
38
39			//get options from the forms nativ attributes
40			opts.action = $this.attr('action') || opts.action;
41			opts.method = $this.attr('method') || opts.method;
42
43			//prevent the forms defautl behaviour
44			$this.bind('submit.wl_Form', function (event) {
45				event.preventDefault();
46				return false;
47			});
48
49			//bind the click action to the submit button
50			$submitbtn.bind('click.wl_Form', function (event) {
51				$.fn.wl_Form.methods.submit.call($this[0]);
52				return false;
53			});
54
55			//iterate thru the fields
56			$inputs.each(function () {
57				var _this = $(this),
58					_row = _this.closest('section'),
59				//the label should be nice readable
60					_label = _row.find('label').eq(0).html() || this.name || this.id || '';
61
62
63				//This is required because IEs < 9 can't handle this as expected
64				if (_this.is('[required]') || typeof _this.prop('required') == 'string') {
65					_this.data('required', true);
66					_row.find('label').eq(0).append('&nbsp;<span class="required">&nbsp;</span>');
67				}
68
69				//add the label to the field (and strip out unwanted info)
70				_this.data('wl_label', _label.replace(/<span>([^<]+)<\/span>|<([^>]+)\/?>/g, ''));
71			});
72
73
74			//set the form status after the submit button if status is true
75			if (opts.status && !$submitbtn.closest('div').is('span.wl_formstatus')) {
76				$submitbtn.closest('div').append('<span class="wl_formstatus"></span>');
77			}
78
79			//parse the location.search parameters
80			if (opts.parseQuery) {
81				$this.wl_Form.methods.unserialize.call(this);
82			}
83
84		} else {
85
86		}
87
88		if (opts) $.extend($this.data('wl_Form'), opts);
89	});
90
91};
92
93$.fn.wl_Form.defaults = {
94	submitButton: 'button:last',
95	method: 'post',
96	action: null,
97	ajax: true,
98	serialize: false,
99	parseQuery: true,
100	dataType: 'text',
101	status: true,
102	sent: false,
103	confirmSend: true,
104	text: {
105		required: 'This field is required',
106		valid: 'This field is invalid',
107		password: 'This password is to short',
108		passwordmatch: 'This password doesn\'t match',
109		fileinqueue: 'There is at least one file in the queue',
110		incomplete: 'Please fill out the form correctly!',
111		send: 'send form...',
112		sendagain: 'send again?',
113		success: 'form sent!',
114		error: 'error while sending!',
115		parseerror: 'Can\'t unserialize query string:\n %e'
116	},
117	tooltip: {
118		gravity: 'nw'
119	},
120	onRequireError: function (element) {},
121	onValidError: function (element) {},
122	onPasswordError: function (element) {},
123	onFileError: function (element) {},
124	onBeforeSubmit: function (data) {},
125	onComplete: function (textStatus, jqXHR) {},
126	onError: function (textStatus, error, jqXHR) {},
127	onSuccess: function (data, textStatus, jqXHR) {}
128};
129$.fn.wl_Form.version = '1.1';
130
131
132$.fn.wl_Form.methods = {
133	disable: function () {
134		var $this = $(this),
135			_inputs = $this.find($this.data('wl_Form').submitButton + ',input,textarea,select,div.date,div.slider');
136		//iterate thru all fields
137		_inputs.each(function () {
138			var _this = $(this);
139			if (_this.is('div')) {
140				//disable slider and datefields
141				if (_this.is('div.slider') && _this.data('wl_Slider')) {
142					_this.wl_Slider('disable');
143				} else if (_this.is('div.date') && _this.data('wl_Date')) {
144					_this.wl_Date('disable');
145				}
146			} else {
147				//disable normal fields
148				_this.prop('disabled', true);
149			}
150		});
151		$this.data('wl_Form').disabled = true;
152	},
153	enable: function () {
154		var $this = $(this),
155			_inputs = $this.find($this.data('wl_Form').submitButton + ',input,textarea,select,div.date,div.slider');
156		//iterate thru all fields
157		_inputs.each(function () {
158			var _this = $(this);
159			if (_this.is('div')) {
160				//enable slider and datefields
161				if (_this.is('div.slider') && _this.data('wl_Slider')) {
162					_this.wl_Slider('enable');
163				} else if (_this.is('div.date') && _this.data('wl_Date')) {
164					_this.wl_Date('enable');
165				}
166			} else {
167				//enable normal fields
168				_this.prop('disabled', false);
169			}
170		});
171		$this.data('wl_Form').disabled = false;
172	},
173	submit: function () {
174
175		//collect some required info
176		var $this = $(this),
177			_data = {},
178			_opts = $this.data('wl_Form'),
179			_inputs = $this.find('input,textarea,select,div.date,div.slider'),
180			_statusel = $this.find('.wl_formstatus'),
181			_requiredelements = Array(),
182			_validelements = Array(),
183			_passwordelements = Array(),
184			_fileelements = Array(),
185			_submit = true;
186
187
188		//status reset
189		_statusel.text("");
190
191		//iterate thru all fields
192		_inputs.each(function (i, e) {
193			var _this = $(this),
194				_row = _this.closest('section');
195
196			//passwords has a different error handling
197			if (_this.attr('type') != 'password' && !_this.data('wl_Password') || _this.data('wl_Password') && _this.data('wl_Password').connect) {
198				_row.removeClass('error');
199			}
200
201			//if a placeholder is set remove the value temporary
202			if (_this.prop('placeholder') && _this.val() == _this.prop('placeholder') && !_this.data('uservalue')) {
203				_this.val('');
204			}
205			//if field is required an a value is set or it is a checkbox and the checkbox isn't checked or it is a file upload with no files
206			if (_this.data('required')) {
207				if ((!_this.val() || _this.is(':checkbox') && !_this.is(':checked')) && !_this.data('wl_File')) {
208					_row.addClass('error');
209					_requiredelements.push(_this);
210					_submit = false;
211				} else if (_this.data('wl_File') && !_this.data('wl_File').files.length) {
212					_row.addClass('error');
213					//use the filepool for the tooltip
214					_requiredelements.push(_row.find('.fileuploadpool').eq(0));
215					_submit = false;
216
217				}
218			}
219			//if it is a valid field but it isn't valid
220			if (_this.data('wl_Valid') && !_this.data('wl_Valid').valid) {
221				_row.addClass('error');
222				_validelements.push(_this);
223				_submit = false;
224			}
225			//check if there is a file in the queue
226			if (_this.data('wl_File') && !$.isEmptyObject(_this.data('wl_File').queue)) {
227				_row.addClass('error');
228				//use the filepool for the tooltip
229				_fileelements.push(_row.find('.fileuploadpool').eq(0));
230				_submit = false;
231			}
232			//if it is a password
233			if (_this.data('wl_Password')) {
234				var value = _this.val();
235				//password confirmation is set and the confirmation isn't equal the password or the password is shorter than the minlength of the password field
236				if ((_this.data('wl_Password').confirm && _this.data('wl_Password').connect && value != $('#' + _this.data('wl_Password').connect).val()) || (value && value.length < _this.data('wl_Password').minLength)) {
237					_row.addClass('error');
238					_passwordelements.push(_this);
239					_submit = false;
240
241				}
242			};
243		});
244
245		//if some of the above errors occures
246		if (!_submit) {
247
248			//iterate thru all required fields
249			$.each(_requiredelements, function (i, e) {
250
251				//callback
252				_opts.onRequireError.call(e[0], e);
253
254				//use tipsy for a tooltip
255				e.tipsy($.extend({}, config.tooltip, _opts.tooltip, {
256					trigger: 'manual',
257					fallback: e.data('errortext') || _opts.text.required
258				}));
259				e.tipsy('show');
260
261				//hide tooltip on fieldfocus or change
262				e.bind('focus.tooltip, click.tooltip, change.tooltip', function () {
263					$(this).unbind('focus.tooltip, click.tooltip, change.tooltip').tipsy('hide');
264				});
265			});
266
267
268			//iterate thru all valid fields
269			$.each(_validelements, function (i, e) {
270
271				//callback
272				_opts.onValidError.call(e[0], e);
273
274				//use tipsy for a tooltip
275				e.tipsy($.extend({}, config.tooltip, _opts.tooltip, {
276					trigger: 'manual',
277					fallback: e.data('errortext') || e.data('wl_Valid').errortext || _opts.text.valid
278				}));
279				e.tipsy('show');
280
281				//hide tooltip on fieldfocus
282				e.bind('focus.tooltip, click.tooltip', function () {
283					$(this).unbind('focus.tooltip, click.tooltip').tipsy('hide');
284				});
285			});
286
287			//iterate thru all password fields
288			$.each(_passwordelements, function (i, e) {
289				var text = '',
290					value = e.val();
291
292				//confirmation is set
293				if (e.data('wl_Password').confirm) {
294					var connect = $('#' + e.data('wl_Password').connect);
295
296					//but password is not equal confimration
297					if (value != connect.val()) {
298
299						//tipsy on the confirmation field
300						connect.tipsy($.extend({}, config.tooltip, _opts.tooltip, {
301							trigger: 'manual',
302							fallback: connect.data('errortext') || _opts.text.passwordmatch
303						}));
304						connect.tipsy('show');
305
306						//hide tooltip in fieldfocus
307						connect.bind('focus.tooltip, click.tooltip', function () {
308							$(this).unbind('focus.tooltip, click.tooltip').tipsy('hide');
309						});
310					}
311				}
312
313				//length is to short
314				if (value.length < e.data('wl_Password').minLength) {
315					_opts.onPasswordError.call(e[0], e);
316
317					//tipsy
318					e.tipsy($.extend({}, config.tooltip, _opts.tooltip, {
319						trigger: 'manual',
320						fallback: e.data('errortext') || _opts.text.password
321					}));
322					e.tipsy('show');
323
324					//hide tooltip in fieldfocus
325					e.bind('focus.tooltip, click.tooltip', function () {
326						$(this).unbind('focus.tooltip, click.tooltip').tipsy('hide');
327					});
328				}
329
330			});
331
332			//iterate thru all file upload fields
333			$.each(_fileelements, function (i, e) {
334
335				//callback
336				_opts.onFileError.call(e[0], e);
337
338				//use tipsy for a tooltip
339				e.tipsy($.extend({}, config.tooltip, _opts.tooltip, {
340					trigger: 'manual',
341					fallback: e.data('errortext') || _opts.text.fileinqueue
342				}));
343				e.tipsy('show');
344
345				//hide tooltip on fieldfocus or change
346				e.bind('focus.tooltip, click.tooltip, change.tooltip', function () {
347					$(this).unbind('focus.tooltip, click.tooltip, change.tooltip').tipsy('hide');
348				});
349			});
350			//Set status message
351			_statusel.text(_opts.text.incomplete);
352			return false;
353		}
354
355		//confirmation is required if the form was allready sent
356		if (_opts.confirmSend && _opts.sent === true) {
357			$.confirm(_opts.text.sendagain, function () {
358				_opts.sent = false;
359				$.fn.wl_Form.methods.submit.call($this[0]);
360			});
361			return false;
362		}
363
364		//iterate thru all fields and prepare data
365		_inputs.each(function (i, e) {
366			var _el = $(e),
367				key = _el.attr('name') || e.id,
368				value = null;
369
370
371			//datepicker
372			if (_el.data('wl_Date')) {
373
374				var connect = $this.find('input[data-connect=' + e.id + ']').eq(0),
375					dateobj = new Date(_el.datepicker('getDate')),
376					//format: YYYY-MM-DD
377					date = dateobj.getFullYear() + '-' + $.leadingZero(dateobj.getMonth() + 1) + '-' + $.leadingZero(dateobj.getDate());
378				if (dateobj.getTime()) {
379					//is connected to a timefield
380					if (connect.length) {
381						value = date + ' ' + (connect.data('wl_Time').time || '00:00');
382					} else {
383						value = date;
384					}
385				}
386				_data[key] = value;
387
388				//slider
389			} else if (_el.data('wl_Slider')) {
390
391				//if it is connected we have a input field too so skip it
392				if (!_el.is('[data-connect]')) {
393					if (_el.data('wl_Slider').range !== true) {
394						value = _el.slider('option', 'value');
395						_data[key] = value;
396					} else {
397						value = _el.slider('option', 'values');
398					}
399					_data[key] = value;
400				}
401
402				//wysiwyg editor
403			} else if (_el.data('wl_Editor')) {
404
405				//copy the content to the textarea
406				_el.wysiwyg('save');
407				_data[key] = _el.val();
408
409				//file upload
410			} else if (_el.data('wl_File')) {
411
412				_data[key] = _el.data('wl_File').files;
413
414				//if no file was uploaded value is null
415				if ($.isEmptyObject(_data[key])) _data[key] = null;
416
417				//timefield
418			} else if (_el.data('wl_Time')) {
419
420				//if it is connected we have a datefield too so skip it
421				if (!_el.is('[data-connect]')) {
422					_data[key] = _el.data('wl_Time').time;
423				}
424
425				//timefield
426			} else if (_el.is(':checkbox')) {
427
428				_data[key] = _el.is(':checked');
429
430				//password
431			} else if (_el.is(':password')) {
432
433				_data[key] = _el.val();
434
435				//radio buttons
436			} else if (_el.is(':radio')) {
437
438				if (_el.is(':checked')) {
439					//use the value attribute if present or id as fallback (new in 1.1)
440					_data[key] = (_el.val() != 'on') ? _el.val() : e.id;
441				}
442
443				//number field
444			} else if (_el.data('wl_Number')) {
445
446				value = parseFloat(_el.val());
447				if (isNaN(value)) {
448					value = null;
449				}
450				_data[key] = value;
451
452				//other fields
453			} else {
454				_data[key] = _el.val();
455			}
456		});
457
458		//should we serialize it? (key=value&key2=value2&...)
459		if (_opts.serialize) {
460			_data = $.param(_data);
461		}
462
463		//callback can return false to prevent sending
464		if (_opts.onBeforeSubmit.call($this[0], _data) === false) {
465			return false;
466		}
467
468		//set status text
469		_statusel.text(_opts.text.send);
470
471		//send the form natively
472		if (!_opts.ajax) {
473			$this.unbind('submit.wl_Form');
474			$this.submit();
475			return false;
476		}
477
478		//now disable it
479		$.fn.wl_Form.methods.disable.call(this);
480
481		//send the form
482		$.ajax({
483			url: _opts.action,
484			type: _opts.method,
485			data: _data,
486			dataType: _opts.dataType,
487			//callback on success
488			success: function (data, textStatus, jqXHR) {
489				_statusel.textFadeOut(_opts.text.success);
490				_opts.onSuccess.call($this[0], data, textStatus, jqXHR);
491			},
492			//callback on complete
493			complete: function (jqXHR, textStatus) {
494				$.fn.wl_Form.methods.enable.call($this[0]);
495				_opts.sent = true;
496				_opts.onComplete.call($this[0], textStatus, jqXHR);
497			},
498			//callback on error
499			error: function (jqXHR, textStatus, error) {
500				_statusel.text(_opts.text.error);
501				_opts.onError.call($this[0], textStatus, error, jqXHR);
502			}
503		});
504
505	},
506	unserialize: function (string) {
507		var $this = $(this),
508			_searchquery = string || location.search.substr(1);
509
510		//parse only if we have something to parse
511		if (_searchquery) {
512
513			//could throw an error because its an userinput
514			try {
515
516				//prepare string to get a clean array with with key => value
517				values = decodeURIComponent(_searchquery).split('&');
518
519				var serialized_values = [];
520
521				$.each(values, function () {
522					var properties = this.split("="),
523						key = properties.shift();
524
525					properties = properties.join('=');
526
527					if ((typeof key !== 'undefined') && (typeof properties !== 'undefined')) {
528						serialized_values[key.replace(/\+/g, " ")] = properties.replace(/\+/g, " ");
529					}
530				});
531				values = serialized_values;
532
533				// Iterate thru each element
534				$("input,textarea,select,div.date,div.slider").each(function () {
535					var _this = $(this),
536						_type = _this.attr("type"),
537						tag_name = this.name || this.id;
538
539
540
541					// Set the values to field
542					if (values[tag_name] != null) {
543
544						//chechboxes
545						if (_type == "checkbox") {
546							_this.prop("checked", (values[tag_name] == 'true'));
547
548							//radio buttons
549						} else if (_type == "radio") {
550							$('input[id="' + values[tag_name] + '"]').attr("checked", true);
551
552							//password
553						} else if (_type == "password") {
554							//don't write passwords for security reasons
555							//_this.val(values[tag_name]).trigger('change')
556							//datepicker
557						} else if (_this.is('input.date')) {
558							if (/(\d\d:\d\d)$/.test(values[tag_name])) {
559								var time = values[tag_name].substr(11),
560									date = values[tag_name].substr(0, 10);
561								_this.datepicker('setDate', new Date(date));
562								$('input[data-connect="' + tag_name + '"]').val(time).data('wl_Time').time = time;
563							} else {
564								_this.datepicker('setDate', new Date(values[tag_name]));
565							}
566
567							//inline datepicker
568						} else if (_this.is('div.date')) {
569							_this.datepicker('setDate', new Date(values[tag_name]));
570
571							//colorpicker
572						} else if (_this.is('.color')) {
573							_this.wl_Color('set', 'value', values[tag_name]);
574
575							//Slider
576						} else if (_this.is('.slider')) {
577							_this.wl_Slider('values', values[tag_name]);
578							if (_this.data('wl_Slider')) {
579								_this.wl_Slider("change");
580								_this.wl_Slider("slide");
581							}
582
583							//wysiwyg editor
584						} else if (_this.is('textarea.html')) {
585							_this.val(values[tag_name]);
586							if (_this.data('wl_Editor')) {
587								_this.wysiwyg("setContent", values[tag_name]);
588							}
589
590							//other fields
591						} else {
592							_this.val(values[tag_name]).trigger('change');
593						}
594					}
595				});
596			} catch (e) {
597
598				//call a message to prevent crashing the application
599				$.msg($this.data('wl_Form').text.parseerror.replace('%e', e));
600			}
601		}
602	},
603	set: function () {
604		var $this = $(this),
605			options = {};
606		if (typeof arguments[0] === 'object') {
607			options = arguments[0];
608		} else if (arguments[0] && arguments[1] !== undefined) {
609			options[arguments[0]] = arguments[1];
610		}
611		$.each(options, function (key, value) {
612			if ($.fn.wl_Form.defaults[key] !== undefined && $.fn.wl_Form.defaults[key] !== null) {
613				$this.data('wl_Form')[key] = value;
614			} else {
615				$.error('Key "' + key + '" is not defined');
616			}
617		});
618
619	}
620};

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.