PageSourceSearch

https://cirbn.org/assets/js/form-validator.js?v=1.0.1&m=1554909878

js cirbn.org collected 2026-10-04 11:27:49 UTC 10,775 bytes, 509 lines download raw bytes

1/**
2 * Form Validator
3 */
4var FORM_VALIDATOR = function($FORM, OPTIONS) {
5
6	if(typeof($FORM) == "undefined") { console.log("No Form Argument"); return false; }
7	if(typeof(OPTIONS) == "undefined") { OPTIONS = {}; }
8
9	/**
10	 * Configure options and default option fallbacks
11	 */
12	var DEFAULTS = {
13		"fill": false,
14		"nodes": {
15			"submit": $(".contact-form-submit", $FORM),
16			"loading": $(".contact-form-loading-icon", $FORM),
17			"message": $(".contact-form-message", $FORM),
18		},
19		"onValid": function(CONFIG) {},
20		"onInvalid": function(INVALID_ELEMENTS, MESSAGE) {},
21		"messages": {
22			"validating": "Validating...",
23			"required_fields": "Please fill in all required fields.",
24			"invalid_email": "E-mail address is invalid.",
25			"invalid_password": "Password is invalid.",
26			"success": "Your message has been sent!",
27			"unknown_error": "Unknown error."
28		}
29	};
30
31	OPTIONS = $.extend({}, DEFAULTS, OPTIONS);
32
33	var EXTEND_JSON = $("script[type='application/json']", $FORM),
34		EXTEND = EXTEND_JSON.length > 0 ? JSON.parse($.trim(EXTEND_JSON.html())) : false;
35
36	if(EXTEND) { OPTIONS = $.extend(true, OPTIONS, EXTEND); }
37
38	/**
39	 * Store instance for return value
40	 */
41	var MODULE = {};
42
43	/**
44	 * Store block ID
45	 */
46	var BLOCK_ID = $FORM.data("block");
47
48	/**
49	 * Message
50	 */
51	var MESSAGE_TIMEOUT = null;
52	var MESSAGE = function(MESSAGE, TYPE, TIMEOUT) {
53
54		if(typeof(MESSAGE) == "undefined") { MESSAGE = ""; }
55		if(typeof(TYPE) == "undefined") { TYPE = "loading"; }
56		if(typeof(TIMEOUT) == "undefined") { TIMEOUT = false; }
57
58		clearTimeout(MESSAGE_TIMEOUT);
59
60		var CLASSES = ['loading', 'success', 'error'];
61
62		$FORM.removeClass(CLASSES.join(" ")).addClass(TYPE);
63
64		OPTIONS["nodes"]["message"].html(MESSAGE);
65
66		if(TIMEOUT) {
67
68			MESSAGE_TIMEOUT = setTimeout(function() {
69
70				$FORM.removeClass(CLASSES.join(" "))
71				OPTIONS["nodes"]["message"].html("");
72
73			}, TIMEOUT);
74
75		}
76
77	};
78
79	/**
80	 * Initialize
81	 */
82	var INIT = function() {
83
84		CONDITIONALS["init"]();
85
86		if(OPTIONS["fill"]) {
87
88			$(".form-item", $FORM).each(function(i, DIV) {
89
90				var $ELEMENT = $("input,textarea,select", DIV).first();
91
92				if($ELEMENT.is(":visible")) {
93
94					if($ELEMENT.is(".checkbox-group input")) {
95
96						var $GROUP = $ELEMENT.closest('.checkbox-group'),
97							$INPUTS = $("input", $GROUP),
98							SIZE = $INPUTS.length,
99							RANDOM = Math.floor(Math.random() * SIZE) + 1;
100
101						$INPUTS.each(function(i, v) {
102
103							if(i < RANDOM) {
104								$(this).prop("checked", true).trigger('change');
105							}
106
107						});
108
109					} else if($ELEMENT.is(".radio-group input")) {
110
111						$ELEMENT.prop("checked", true).trigger('change');
112
113					} else if($ELEMENT.is("select")) {
114
115						var SELECTED_OPTION = "";
116
117						$("option", $ELEMENT).each(function() {
118
119							var VAL = $.trim($(this).val());
120
121							if(VAL != "") {
122								SELECTED_OPTION = VAL;
123							}
124
125						});
126
127						$ELEMENT.val(SELECTED_OPTION).trigger('change');
128
129					} else {
130
131						var RANDOM_STRING = Math.random().toString(36).slice(2);
132
133						if($ELEMENT.data("email")) { RANDOM_STRING += "@test.com"; }
134						if($ELEMENT.data("mask")) { RANDOM_STRING = $ELEMENT.data("mask"); }
135
136						$ELEMENT.val(RANDOM_STRING).trigger('keyup');
137
138					}
139
140				}
141
142			});
143
144		}
145
146		// Submit Button Click
147		OPTIONS["nodes"]["submit"].on('click', function(event) {
148
149			event.preventDefault();
150
151			MODULE["validate"]();
152
153		});
154
155		// Toggle radio/checkbox by clicking on label
156		$(".radio-group div, .checkbox-group div").on('click', function(event) {
157
158			if(!$(event.target).is("input")) {
159
160				$("input", this).prop("checked", !$("input", this).prop("checked")).trigger('change');
161
162			}
163
164		});
165
166		// Submit on enter keydown
167		$("input:not([type='checkbox']):not([type='radio'])", $FORM).on('keydown', function(event) {
168
169			if(event && event.keyCode && event.keyCode == 13) {
170				event.preventDefault();
171				MODULE["validate"]();
172			}
173
174		});
175
176		// Clear invalid on change
177		$FORM.on('change keyup', '.form-invalid', function(event) {
178
179			$(this).removeClass("form-invalid");
180
181			if($(".form-invalid", $FORM).length === 0) {
182
183                MESSAGE("", "success");
184
185            }
186
187		});
188
189		// Apply MaskedInput masks
190		$("input[data-mask], textarea[data-mask]", $FORM).each(function(i,v) {
191			var input = $(this);
192			input.mask(input.data("mask").toString());
193		});
194
195	};
196
197	/**
198	 * Check for blanks / unchecked
199	 */
200	var CHECK = {
201
202		"from": function(ON_SUCCESS) {
203
204			if(typeof(ON_SUCCESS) == "undefined") { ON_SUCCESS = function() {}; }
205
206			var $NAME_ELEMENT = $("[data-name='true']", $FORM),
207				$EMAIL_ELEMENT = $("[data-email='true']", $FORM);
208
209			var NAME = "",
210				EMAIL = $EMAIL_ELEMENT.val();
211
212			if($NAME_ELEMENT.length > 1) {
213
214				var MULTI = "";
215
216				$NAME_ELEMENT.each(function(i,v) {
217					MULTI = MULTI + $(this).val();
218					if(i < $NAME_ELEMENT.length - 1) { MULTI = MULTI + " "; }
219				});
220
221				NAME = MULTI;
222
223			} else {
224				NAME = $NAME_ELEMENT.val();
225			}
226
227			ON_SUCCESS({
228				"name": {
229					"element": $NAME_ELEMENT,
230					"string": NAME
231				},
232				"email": {
233					"element": $EMAIL_ELEMENT,
234					"string": EMAIL
235				}
236			});
237
238		},
239
240		"blanks": function(ON_SUCCESS) {
241
242			if(typeof(ON_SUCCESS) == "undefined") { ON_SUCCESS = function() {}; }
243
244			var INVALID_ELEMENTS = [];
245
246			$("[data-required]:visible", $FORM).each(function(i, ELEMENT) {
247
248				var $ELEMENT = $(ELEMENT),
249					INVALID = false;
250
251				if($ELEMENT.is(".checkbox-group")) {
252
253					var REQUIRED = parseInt($ELEMENT.data("required"));
254
255					if(isNaN(REQUIRED)) { REQUIRED = 1; }
256
257					if($("input[type='checkbox']:checked", $ELEMENT).length < REQUIRED) { INVALID = true; }
258
259				} else if($ELEMENT.is(".radio-group")) {
260
261					if($("input[type='radio']:checked", $ELEMENT).length == 0) { INVALID = true; }
262
263				} else if($ELEMENT.is("[type='checkbox']")) {
264
265					if(!$ELEMENT.is(":checked")) { INVALID = true; }
266
267				} else if($ELEMENT.is("select")) {
268
269					if($.trim($ELEMENT.val()) == "" || $.trim($ELEMENT.val()) == "null") { INVALID = true; }
270
271				} else {
272
273					if($.trim($ELEMENT.val()) == "") { INVALID = true; }
274
275				}
276
277				if(INVALID) {
278
279					$ELEMENT.addClass("form-invalid");
280
281					INVALID_ELEMENTS.push($ELEMENT);
282
283				}
284
285			});
286
287			if(INVALID_ELEMENTS.length > 0) {
288
289				MESSAGE(OPTIONS["messages"]["required_fields"], "error");
290				OPTIONS["onInvalid"](INVALID_ELEMENTS, OPTIONS["messages"]["required_fields"]);
291
292			} else {
293
294				ON_SUCCESS();
295
296			}
297
298		},
299
300		"email": function(FROM, ON_SUCCESS) {
301
302			if(typeof(FROM) == "undefined") { FROM = {}; }
303			if(typeof(ON_SUCCESS) == "undefined") { ON_SUCCESS = function() {}; }
304
305			if(FROM["email"]["element"].length > 0 && FROM["email"]["element"].is(":visible")) {
306
307				var REGEX = /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/;
308
309				if(FROM["email"]["string"].match(REGEX)) {
310
311					ON_SUCCESS();
312
313				} else {
314
315					MESSAGE(OPTIONS["messages"]["invalid_email"], "error");
316					FROM["email"]["element"].addClass("form-invalid");
317
318					OPTIONS["onInvalid"]([FROM["email"]["element"]], OPTIONS["messages"]["invalid_email"]);
319
320				}
321
322			} else {
323				ON_SUCCESS();
324			}
325
326		},
327
328	};
329
330	/**
331	 * Conditional Fields
332	 */
333	 var CONDITIONALS = {
334
335 		"init": function() {
336
337 			var $TRIGGERS = $("[data-conditional]", $FORM),
338 				$CONDITIONS = $("[data-condition]", $FORM);
339
340 			$CONDITIONS.hide();
341
342			$TRIGGERS.each(function() {
343
344				var $TRIGGER = $(this);
345
346				if($TRIGGER.is("input[type='radio']")) {
347
348					var $CONDITION = $CONDITIONS.filter("[data-condition='" + $TRIGGER.data("conditional") + "']");
349
350					$("[name='" + $TRIGGER.attr("name") + "']", $FORM).not($TRIGGER).on('change', function() {
351
352						if($(this).is(":checked")) {
353							$CONDITION.slideUp(200, function() {
354		 						$("input,textarea,select", $CONDITION).val(function() {
355		 							return this.defaultValue;
356		 						});
357		 					});
358						}
359
360					});
361
362				}
363
364	 			$TRIGGER.on('change keyup', function(event) {
365
366	 				var $CONDITION = $CONDITIONS.filter("[data-condition='" + $TRIGGER.data("conditional") + "']");
367
368	 				TOGGLE = true;
369
370	 				if($TRIGGER.is("[type='checkbox']") || $TRIGGER.is("[type='radio']")) {
371
372	 					if(!$TRIGGER.is(":checked")) {
373
374	 						TOGGLE = false;
375
376	 					}
377
378	 				} else {
379
380	 					var VAL = $.trim($TRIGGER.val());
381
382	 					if($.inArray(VAL, ["", "null"]) !== -1) {
383
384	 						TOGGLE = false;
385
386	 					}
387
388	 				}
389
390	 				if(TOGGLE) {
391	 					$CONDITION.slideDown(200);
392	 				} else {
393	 					$CONDITION.slideUp(200, function() {
394	 						$("input,textarea,select", $CONDITION).val(function() {
395	 							return this.defaultValue;
396	 						});
397	 					});
398	 				}
399
400	 			});
401
402			});
403
404 		}
405
406 	};
407
408	/**
409	 * Run Validator
410	 */
411	MODULE["validate"] = function() {
412
413		MESSAGE(OPTIONS["messages"]["validating"]);
414
415		$(".form-invalid", $FORM).removeClass("form-invalid");
416
417		CHECK["from"](function(FROM) {
418
419			CHECK["blanks"](function() {
420
421				CHECK["email"](FROM, function() {
422
423					MESSAGE("", "success");
424
425					//$FORM.find("textarea[value=''], input[type='text'][value='']").val("");
426
427					var SERIALIZED = $FORM.serializeArray();
428
429					var TRANSFORM_SERIALIZED = Array();
430
431					$.each(SERIALIZED, function(i, ITEM) {
432
433						if(typeof(ITEM["name"]) != "undefined" && ITEM["name"] != "") {
434							TRANSFORM_SERIALIZED.push(ITEM);
435						}
436
437					});
438
439					SERIALIZED = TRANSFORM_SERIALIZED;
440
441					OPTIONS["onValid"]({
442						"block_id": BLOCK_ID,
443						"from": {
444							"name": FROM["name"]["string"],
445							"email": FROM["email"]["string"]
446						},
447						"serialized": SERIALIZED,
448						"messages": OPTIONS["messages"]
449					}, OPTIONS);
450
451				});
452
453			});
454
455		});
456
457	};
458
459	/**
460	 * Display Custom Success Message (If enabled)
461	 */
462	MODULE["customSuccessMessage"] = function($TARGET) {
463
464		if(typeof($TARGET) == "undefined") { var $TARGET = $FORM; }
465
466		CMS.block.get(BLOCK_ID, function(BLOCK) {
467
468			if(typeof(BLOCK["settings"]["Form Success Message"]) != "undefined") {
469
470				var $SUCCESS = $("<div />");
471					$SUCCESS.hide().addClass("contact-form-success-message");
472
473				$SUCCESS.html(BLOCK["data"][0]["html"]);
474
475				$TARGET.before($SUCCESS);
476				$TARGET.hide();
477
478				$("#footer-contact-title, #footer-contact-submit").fadeOut(200);
479
480				$("html,body").animate({ scrollTop: $FORM.offset().top - 100 }, 200);
481
482				$SUCCESS.slideDown(200, function() {
483
484				});
485
486			}
487
488		});
489
490	};
491
492	/**
493	 * Public message method
494	 */
495	MODULE["message"] = function(MSG, TYPE, TIMEOUT) {
496
497		if(typeof(MSG) == "undefined") { MSG = ""; }
498		if(typeof(TYPE) == "undefined") { TYPE = "loading"; }
499		if(typeof(TIMEOUT) == "undefined") { TIMEOUT = false; }
500
501		MESSAGE(MSG, TYPE, TIMEOUT);
502
503	};
504
505	INIT();
506
507	return MODULE;
508
509}

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.