PageSourceSearch

https://zanzis.com/media/com_rsform/js/script.js?d9318e3edf8eee106330de2f510d678c

js zanzis.com collected 2026-10-08 12:51:42 UTC 53,705 bytes, 1,817 lines download raw bytes

1var RSFormProCalendars = {};
2var RSFormProPrices = {};
3var ajaxExtraValidationScript = {};
4var RSClickedSubmitElement = false;
5
6if (typeof RSFormPro != 'object') {
7	var RSFormPro = {};
8}
9
10RSFormPro.Forms = {};
11RSFormPro.Editors = {};
12RSFormPro.scrollToError = false;
13RSFormPro.usePositioning = false;
14
15/* Handle HTML5 form fields validation for the forms without AjaxValidation enabled */
16RSFormPro.setHTML5Validation = function (formId, isDisabledSubmit, errorClasses, totalPages) {
17	var parentErrorClass = errorClasses.parent;
18	var fieldErrorClass = errorClasses.field;
19	var submitElement = RSFormPro.getElementByType(formId, 'submit');
20	var i, j;
21	for (i = 0; i < submitElement.length; i++) {
22		if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
23			RSFormProUtils.addEvent(submitElement[i], 'click', (function (event) {
24				errorElements = RSFormPro.HTML5.validation(formId);
25				if (errorElements.length) {
26					var errorPagesFound = [];
27					for (j = 0; j < errorElements.length; j++) {
28						RSFormProUtils.addClass(errorElements[j], 'rsform-error');
29
30						if (document.getElementById('component' + errorElements[j].componentId)) {
31							document.getElementById('component' + errorElements[j].componentId).className = 'formError';
32						}
33						if (parentErrorClass) {
34							try {
35								var block = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(errorElements[j].field.getAttribute('id')));
36
37								RSFormProUtils.addClass(block[0], parentErrorClass);
38							} catch (err) {}
39						}
40
41						if (totalPages > 0) {
42							errorPagesFound.push(errorElements[j].page);
43						}
44					}
45
46					if (totalPages > 0 && errorPagesFound.length) {
47						var firstErrorPage = Math.min.apply(null, errorPagesFound);
48						RSFormPro.Pages.change(formId, firstErrorPage, totalPages, false, errorClasses)
49					}
50
51					if (RSFormPro.scrollToError){
52						RSFormPro.gotoErrorElement(formId);
53					}
54
55					if (isDisabledSubmit) {
56						for (j = 0; j < submitElement.length; j++) {
57							submitElement[j].disabled = false;
58						}
59					}
60
61					event.preventDefault();
62				} else {
63					if (isDisabledSubmit) {
64						// if the submit button or any other element has the id submit the form.submit() function is overwritten
65						if (typeof this.form.submit != 'function') {
66							document.createElement('form').submit.call(this.form)
67						} else {
68							this.form.submit();
69						}
70					}
71				}
72			}));
73		}
74	}
75};
76
77/* Disable the submit button when form is submitted functions */
78RSFormPro.setDisabledSubmit = function(formId, ajaxValidation){
79	if (!ajaxValidation) {
80		var i, j;
81		var submitElement = RSFormPro.getElementByType(formId, 'submit');
82		for (i = 0; i < submitElement.length; i++) {
83			if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
84				RSFormProUtils.addEvent(submitElement[i],'click', (function(event) {
85					for (j = 0; j < submitElement.length; j++) {
86						submitElement[j].disabled = true;
87					}
88				}));
89			}
90		}
91	}
92};
93/* Thank You Message in Popup Window functions */
94
95RSFormPro.showThankYouPopup = function (thankYouContainer){
96	var content = thankYouContainer.innerHTML;
97	var gotoUrl = thankYouContainer.querySelector('#rsfp-thankyou-popup-return-link').value;
98
99	// remove the html part from the layout
100	thankYouContainer.parentNode.removeChild( thankYouContainer );
101
102	document.body.className = document.body.className+' rsfp_popup_activated';
103	document.body.innerHTML += '<div class="rsfp_thankyou_popup_outer" onclick="RSFormPro.accessLink(event,\''+gotoUrl+'\')"><div class="rsfp_thankyou_popup_inner" id="rsfp_thankyou_popup_inner"><div class="rsfp_thankou_popup_close_btn">&times;</div>'+content+'</div></div>';
104
105	var popupWindowHeight = document.getElementById('rsfp_thankyou_popup_inner').offsetHeight;
106	var windowHeight = window.innerHeight;
107
108	var marginTop = (windowHeight - popupWindowHeight) / 2;
109	document.getElementById('rsfp_thankyou_popup_inner').style.marginTop = marginTop+'px';
110};
111RSFormPro.accessLink = function(event,link) {
112	var clickedElementClass = event.target.className;
113	if (clickedElementClass == 'rsfp_thankyou_popup_outer' || clickedElementClass == 'rsfp_thankou_popup_close_btn') {
114		if (link.length > 0) {
115			document.location = link;
116		} else {
117			document.location.reload();
118		}
119	}
120};
121
122/* Scroll to first error element */
123RSFormPro.gotoErrorElement = function(formId){
124	var form = RSFormPro.getForm(formId);
125	var errorElements = form.getElementsByClassName('formError');
126	if (errorElements.length) {
127		var block = RSFormPro.findAncestor(errorElements[0], 'rsform-block');
128		if (block) {
129			RSFormPro.scrollToElement(block);
130		} else {
131			RSFormPro.scrollToElement(errorElements[0]);
132		}
133	}
134};
135
136RSFormPro.findAncestor = function(el, cls){
137	while(el = el.parentElement) {
138		var elementClasses = el.className;
139		elementClasses = elementClasses.split(' ');
140		if (elementClasses.indexOf(cls) >= 0) {
141			return el;
142		}
143	}
144
145	return false;
146};
147
148/* ScrollTo functions */
149RSFormPro.scrollToElement = function(element){
150	var to = element.offsetTop;
151	var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
152	var documentView = window.innerHeight + scrollTop;
153
154	// this is more specific for the modern browsers
155	if (typeof element.getBoundingClientRect == 'function') {
156		to = element.getBoundingClientRect().top + scrollTop;
157	}
158
159	if (to < scrollTop || to > documentView) {
160		RSFormPro.scrollTo(to, 300);
161	}
162};
163
164RSFormPro.scrollTo = function(to, duration) {
165	if (duration <= 0) return;
166	var elementScrollTop = window.pageYOffset ?  window.pageYOffset : document.documentElement.scrollTop;
167	var difference = to - elementScrollTop;
168	var perTick = difference / duration * 10;
169	
170	setTimeout(function() {
171		var limitControl;
172		limitControl = window.pageYOffset ?  window.pageYOffset : document.documentElement.scrollTop;
173		limitControl = limitControl + perTick;
174		window.scrollTo(0, limitControl);
175		// if the element has been reached or the scroll is at the bottom of the page no need to continue
176		if (limitControl == to) return;
177
178		RSFormPro.scrollTo(to, duration - 10);
179	}, 10);
180};
181
182/* Field specific functions */
183
184RSFormPro.refreshCaptcha = function(componentId, captchaPath) {
185	if (!captchaPath) {
186		captchaPath = 'index.php?option=com_rsform&task=captcha&format=image&componentId=' + componentId;
187	}
188	document.getElementById('captcha' + componentId).src = captchaPath + '&' + Math.random();
189	document.getElementById('captchaTxt' + componentId).value = '';
190	document.getElementById('captchaTxt' + componentId).focus();
191};
192
193RSFormPro.initGeoLocation = function(term, id, mapid,  map, marker, geocoder, type) {
194	var content = document.getElementById('rsform_geolocation'+id);
195	var address	= document.getElementById(mapid).clientWidth;
196
197	document.getElementById('rsform_geolocation'+id).style.width = address+'px';
198	document.getElementById('rsform_geolocation'+id).style.display = 'none';
199	document.getElementById('rsform_geolocation'+id).innerHTML = '';
200
201	if (term != '') {
202		geocoder.geocode( {'address': term }, function(results, status) {
203			if (status == 'OK') {
204				for (var i=0; i<results.length; i++) {
205					var item	= results[i];
206					var theli	= document.createElement('li');
207					var thea	= document.createElement('a');
208
209					thea.setAttribute('href','javascript:void(0)');
210					thea.innerHTML = item.formatted_address;
211
212					RSFormProUtils.addEvent(thea,'click', (function() {
213						var mapValue = type ? item.formatted_address : item.geometry.location.lat().toFixed(5) + ',' + item.geometry.location.lng().toFixed(5);
214						var mapId	 = mapid;
215						var location = new google.maps.LatLng(item.geometry.location.lat().toFixed(5), item.geometry.location.lng().toFixed(5));
216
217						return function() {
218							document.getElementById(mapId).value = mapValue;
219							marker.setPosition(location);
220							map.setCenter(location);
221							document.getElementById('rsform_geolocation'+id).style.display = 'none';
222						}
223					})());
224
225					theli.appendChild(thea);
226					content.appendChild(theli);
227				}
228
229				document.getElementById('rsform_geolocation'+id).style.display = '';
230			}
231		});
232	}
233};
234
235RSFormPro.disableInvalidDates = function(fieldName) {
236	var theDate = new Date(),
237		day,
238		index;
239
240	for (day = 1; day <= 31; day++) {
241		var year 	= parseInt(document.getElementById(fieldName + 'y').value);
242		var month 	= parseInt(document.getElementById(fieldName + 'm').value) - 1;
243
244		index = day - 1;
245		if (document.getElementById(fieldName + 'd').options[0].value == '') {
246			index++;
247		}
248		document.getElementById(fieldName + 'd').options[index].disabled = false;
249		if (!isNaN(year) && !isNaN(month)) {
250			if (typeof theDate.__msh_oldSetFullYear == 'function') {
251				theDate.__msh_oldSetFullYear(year, month, day);
252			} else {
253				theDate.setFullYear(year, month, day);
254			}
255
256			if (theDate.getDate() != day || theDate.getMonth() != month) {
257				document.getElementById(fieldName + 'd').options[index].disabled = true;
258			}
259		}
260	}
261	if (document.getElementById(fieldName + 'd').options[document.getElementById(fieldName + 'd').selectedIndex].disabled == true) {
262		for (day = 31; day >= 28; day--) {
263			index = day - 1;
264			if (document.getElementById(fieldName + 'd').options[0].value == '') {
265				index++;
266			}
267			if (document.getElementById(fieldName + 'd').options[index].disabled == false) {
268				document.getElementById(fieldName + 'd').value = day;
269				break;
270			}
271		}
272	}
273};
274
275/* Number functions */
276
277RSFormPro.formatNumber = function(number, decimals, dec_point, thousands_sep) {
278	var n = number, prec = decimals;
279	n = !isFinite(+n) ? 0 : +n;
280	prec = !isFinite(+prec) ? 0 : Math.abs(prec);
281	var sep = (typeof thousands_sep == "undefined") ? ',' : thousands_sep;
282	var dec = (typeof dec_point == "undefined") ? '.' : dec_point;
283
284	var s = (prec > 0) ? n.toFixed(prec) : Math.round(n).toFixed(prec); //fix for IE parseFloat(0.55).toFixed(0) = 0;
285
286	var abs = Math.abs(n).toFixed(prec);
287	var _, i;
288
289	if (abs >= 1000) {
290		_ = abs.split(/\D/);
291		i = _[0].length % 3 || 3;
292
293		_[0] = s.slice(0,i + (n < 0)) +
294			_[0].slice(i).replace(/(\d{3})/g, sep+'$1');
295
296		s = _.join(dec);
297	} else {
298		s = s.replace('.', dec);
299	}
300
301	return s;
302};
303
304RSFormPro.toNumber = function(number, decimal, thousands, decimals) {
305	// Remove decimals first
306	if (parseInt(decimals) > 0 && number.lastIndexOf(decimal) > -1) {
307		var index = number.lastIndexOf(decimal);
308		number = number.substring(0, index) + 'DECIMALS' + number.substring(index + 1);
309	}
310
311	// Remove thousands separator
312	if (number.indexOf(thousands) > -1) {
313		number = number.split(thousands).join('');
314	}
315
316	number = number.split('DECIMALS').join('.');
317	return parseFloat(number);
318};
319
320/* Form and element functions */
321
322RSFormPro.getForm = function(formId) {
323	if (typeof RSFormPro.Forms[formId] == 'undefined') {
324		var formIds = document.getElementsByName('form[formId]');
325		for (var i=0; i<formIds.length; i++)
326		{
327			if (parseInt(formIds[i].value) != parseInt(formId))
328				continue;
329
330			var form = formIds[i].parentNode;
331			if (form.tagName == 'FORM' || form.nodeName == 'FORM') {
332				RSFormPro.Forms[formId] = form;
333				return form;
334			}
335
336			while (form.parentNode)
337			{
338				form = form.parentNode;
339				if (form.tagName == 'FORM' || form.nodeName == 'FORM') {
340					RSFormPro.Forms[formId] = form;
341					return form;
342				}
343			}
344		}
345	}
346
347	return RSFormPro.Forms[formId];
348};
349
350RSFormPro.getValue = function(formId, name) {
351	var form	= RSFormPro.getForm(formId);
352	var values	= [];
353
354	if (typeof form != 'undefined')
355	{
356		for (var i = 0; i < form.elements.length; i++)
357		{
358			var element = form.elements[i];
359			var tagName = element.tagName || element.nodeName;
360
361			switch (tagName)
362			{
363				case 'INPUT':
364					if (element.type)
365						switch (element.type.toUpperCase())
366						{
367							case 'TEXT':
368							case 'NUMBER':
369							case 'HIDDEN':
370								if (!element.name || element.name != 'form[' + name + ']') continue;
371								
372								if (typeof RSFormPro.YUICalendar != 'undefined' &&
373									typeof RSFormPro.YUICalendar.calendars[formId] != 'undefined' &&
374									typeof RSFormPro.YUICalendar.calendars[formId][name] != 'undefined')
375									{
376										var selectedDate = new Date(RSFormPro.YUICalendar.calendars[formId][name].getSelectedDates()[0]);
377										return (selectedDate.getTime() / 1000).toString();
378									}
379								
380								if (typeof RSFormPro.jQueryCalendar != 'undefined' &&
381									typeof RSFormPro.jQueryCalendar.calendars[formId] != 'undefined' &&
382									typeof RSFormPro.jQueryCalendar.calendars[formId][name] != 'undefined')
383									{
384										var selectedDate = Date.parseDate(RSFormPro.jQueryCalendar.calendars[formId][name].currentDate, RSFormPro.jQueryCalendar.calendars[formId][name].hiddenFormat);
385										return (selectedDate.getTime() / 1000).toString();
386									}
387								
388								return element.value;
389								break;
390
391							case 'RADIO':
392								if (!element.name || element.name != 'form[' + name + ']') continue;
393
394								if (element.checked == true) {
395									values.push(element.value);
396								}
397								break;
398
399							case 'CHECKBOX':
400								if (!element.name || element.name != 'form[' + name + '][]') continue;
401								if (element.checked == true) {
402									values.push(element.value);
403								}
404								break;
405						}
406					break;
407
408				case 'SELECT':
409					if (!element.name || element.name != 'form[' + name + '][]') continue;
410
411					if (element.options)
412						for (var o=0; o<element.options.length; o++)
413							if (element.options[o].selected)
414							{
415								values.push(element.options[o].value);
416							}
417					break;
418			}
419		}
420	}
421
422	return values;
423};
424
425RSFormPro.getElementByType = function(formId, type) {
426	var form	= RSFormPro.getForm(formId);
427	type = type.toUpperCase();
428	var elements	= [];
429
430	if (typeof form != 'undefined')
431	{
432		for (var i = 0; i < form.elements.length; i++)
433		{
434			var element = form.elements[i];
435			var tagName = element.tagName || element.nodeName;
436			switch (tagName)
437			{
438				case 'INPUT':
439				case 'BUTTON':
440					if (element.type.toUpperCase() == type) {
441						elements.push(element);
442					}
443					break;
444
445				case 'SELECT':
446				case 'TEXTAREA':
447					if (type == 'SELECT' || type == 'TEXTAREA') {
448						elements.push(element);
449					}
450					break;
451			}
452		}
453	}
454
455	return elements;
456};
457
458RSFormPro.resettingValues = false;
459
460RSFormPro.resetValues = function(items) {
461	if (RSFormPro.resettingValues)
462	{
463		return;
464	}
465
466	RSFormPro.resettingValues = true;
467	var element, tagName;
468	try
469	{
470		for (var i = 0; i < items.length; i++)
471		{
472			element = items[i];
473			tagName = element.tagName || element.nodeName;
474
475			switch (tagName)
476			{
477				case 'INPUT':
478					if (element.type)
479					{
480						switch (element.type.toUpperCase())
481						{
482							case 'CHECKBOX':
483							case 'RADIO':
484								element.checked = element.defaultChecked;
485								
486								RSFormPro.triggerEvent(element, 'change');
487							break;
488							
489							case 'NUMBER':
490							case 'TEXT':
491								element.value = element.defaultValue;
492								
493								RSFormPro.triggerEvent(element, 'change');
494								RSFormPro.triggerEvent(element, 'input');
495
496                                if (element.id && element.id.indexOf('rs-range-slider') == 0 && typeof jQuery != 'undefined')
497                                {
498                                    jQuery(element).data('ionRangeSlider').reset();
499                                }
500							break;
501						}
502					}
503				break;
504				
505				case 'TEXTAREA':
506					element.value = element.defaultValue;
507					
508					RSFormPro.triggerEvent(element, 'change');
509					RSFormPro.triggerEvent(element, 'input');
510				break;
511
512				case 'SELECT':
513					if (element.options)
514					{
515						for (var o = 0; o < element.options.length; o++)
516						{
517							element.options[o].selected = element.options[o].defaultSelected;
518						}
519					}
520					
521					RSFormPro.triggerEvent(element, 'change');
522				break;
523			}
524		}
525	}
526	catch (err) {}
527
528	RSFormPro.resettingValues = false;
529};
530
531RSFormPro.triggerEvent = function(element, type) {
532	try {
533		var event;
534		if (document.createEvent) {
535			event = document.createEvent("HTMLEvents");
536			event.initEvent(type, true, true);
537		} else {
538			event = document.createEventObject();
539			event.eventType = type;
540		}
541
542		event.eventName = type;
543
544		if (document.createEvent) {
545			element.dispatchEvent(event);
546		} else {
547			element.fireEvent("on" + event.eventType, event);
548		}
549	} catch (e) {}
550};
551
552RSFormPro.isChecked = function(formId, name, value) {
553	var isChecked 	= false;
554	var form 		= RSFormPro.getForm(formId);
555
556	if (typeof form != 'undefined')
557	{
558		primary_loop:
559			for (var i=0; i<form.elements.length; i++)
560			{
561				var element = form.elements[i];
562				var tagName = element.tagName || element.nodeName;
563
564				switch (tagName)
565				{
566					case 'INPUT':
567						if (element.type)
568							switch (element.type.toUpperCase())
569							{
570								case 'RADIO':
571									if (!element.name || element.name != 'form[' + name + ']') continue;
572									if (element.checked == true && element.value == value)
573									{
574										isChecked = true;
575										break primary_loop;
576									}
577									break;
578
579								case 'CHECKBOX':
580									if (!element.name || element.name != 'form[' + name + '][]') continue;
581									if (element.checked == true && element.value == value)
582									{
583										isChecked = true;
584										break primary_loop;
585									}
586									break;
587							}
588						break;
589
590					case 'SELECT':
591						if (!element.name || element.name != 'form[' + name + '][]') continue;
592
593						if (element.options)
594							for (var o=0; o<element.options.length; o++)
595								if (element.options[o].selected && element.options[o].value == value)
596								{
597									isChecked = true;
598									break primary_loop;
599								}
600						break;
601				}
602			}
603	}
604
605	return isChecked;
606};
607
608RSFormPro.getBlock = function(formId, block) {
609	var form 	 = RSFormPro.getForm(formId);
610	var possible = false;
611	var blocks, current_block;
612
613	if (typeof form != 'undefined') {
614		if (blocks = getElementsByClassName('rsform-block')) {
615			for (i=0; i<blocks.length; i++) {
616				var classes = blocks[i].className.split(' ');
617				for (c=0; c<classes.length; c++) {
618					if (classes[c] == 'rsform-block-' + block) {
619						if (blocks[i].parentNode) {
620							current_block = blocks[i];
621							if (current_block == form)
622								return [ blocks[i] ];
623
624							while (current_block.parentNode) {
625								current_block = current_block.parentNode;
626								if (current_block == form)
627									return [ blocks[i] ];
628							}
629						}
630
631						possible = [ blocks[i] ];
632					}
633				}
634			}
635		}
636	}
637
638	return possible;
639};
640
641RSFormPro.getFieldsByName = function(formId, name) {
642	var form 	= RSFormPro.getForm(formId);
643	var results = [];
644	var pushed  = false;
645
646	if (typeof form != 'undefined') {
647		for (var i=0; i<form.elements.length; i++) {
648			var element = form.elements[i];
649			pushed = false;
650			if (element.name && (
651					// single fields
652					element.name == 'form[' + name + ']' ||
653					// multiple fields
654					element.name == 'form[' + name + '][]' ||
655					// new field - Birthday field
656					element.name == 'form[' + name + '][d]' ||
657					element.name == 'form[' + name + '][m]' ||
658					element.name == 'form[' + name + '][y]'
659				)) {
660				results.push(element);
661				pushed = true;
662			}
663
664			if (pushed) {
665				// for calendar
666				if (element.id && element.id.indexOf('txtcal') > -1) {
667					var suffix = element.id.replace('txtcal', '');
668					if (document.getElementById('btn' + suffix))
669					{
670						results.push(document.getElementById('btn' + suffix));
671					}
672				}
673				// for labels (radio, checkbox)
674				var labels = form.getElementsByTagName('label');
675				for (var l=0; l<labels.length; l++) {
676					if (labels[l].htmlFor && labels[l].htmlFor == element.id)
677						results.push(labels[l]);
678				}
679			}
680		}
681	}
682
683	return results;
684};
685
686RSFormPro.showCounter = function(element, id) {
687	var current = element.value.length;
688	var result;
689	if (element.maxLength > 0)
690	{
691		result = current + '/' + element.maxLength;
692	}
693	else
694	{
695		result = current;
696	}
697	
698	document.getElementById('rsfp-counter-' + id).innerText = result;
699};
700
701RSFormPro.limitSelections = function(formId, field, max) {
702    RSFormProUtils.addEvent(window, 'load', function() {
703        var fields = RSFormPro.getFieldsByName(formId, field);
704        var objects = [];
705        var i;
706        var tagName;
707
708        if (!fields || !fields.length) {
709            return;
710        }
711
712        for (i = 0; i < fields.length; i++) {
713            tagName = fields[i].tagName || fields[i].nodeName;
714            tagName = tagName.toUpperCase();
715
716            if (tagName === 'INPUT' && fields[i].type && fields[i].type.toUpperCase() === 'CHECKBOX' && !fields[i].disabled) {
717                objects.push(fields[i]);
718            }
719        }
720
721        if (!objects.length) {
722            return;
723        }
724
725        function limitSelections() {
726            var values = RSFormProUtils.getChecked(objects);
727            RSFormProUtils.remAttr(objects, 'disabled');
728            if (values && values.length > 0 && values.length >= max) {
729                RSFormProUtils.setAttr(RSFormProUtils.getUnchecked(objects), 'disabled', true);
730            }
731		}
732
733        for (i = 0; i < objects.length; i++) {
734            RSFormProUtils.addEvent(objects[i], 'change', limitSelections);
735        }
736
737        limitSelections();
738    });
739};
740
741/*HTML5 simulators*/
742
743RSFormPro.HTML5 = {
744	validation: function(formId){
745		var form = RSFormPro.getForm(formId);
746		var errorElements = [];
747		var html5types = ['number', 'email', 'range', 'url', 'tel'];
748
749		var checkValidityExists = true;
750		var page = 0;
751		if (form.elements.length) {
752			for (i=0; i<form.elements.length; i++) {
753				if (!checkValidityExists) {
754					break;
755				}
756
757				// if the multiple form is present and also validation we will need to find in which page the element is located
758				if (form.elements[i].type == 'button') {
759					var onclick = form.elements[i].getAttribute('onclick');
760					if (typeof onclick == 'string' && onclick.indexOf('rsfp_changePage') >= 0){
761						var countCommas = 0;
762						var pos = onclick.indexOf(',');
763						while (pos > -1) {
764							++countCommas;
765							pos = onclick.indexOf(',', ++pos);
766						}
767
768
769						if (countCommas > 2) {
770							page++;
771						}
772					}
773				}
774				if (html5types.indexOf(form.elements[i].type) >= 0) {
775					if ( typeof(form.elements[i].checkValidity) == "function" && checkValidityExists) {
776						if (!form.elements[i].checkValidity()) {
777							var elementObj = {
778								field: form.elements[i],
779								page: page
780							};
781							// try to get the componentId
782							var componentId = RSFormPro.HTML5.getComponentId(formId, form.elements[i].getAttribute('id'));
783							if (componentId) {
784								elementObj.componentId = componentId;
785							}
786
787							errorElements.push(elementObj);
788						}
789					} else {
790						checkValidityExists = false;
791					}
792				}
793			}
794		}
795		return errorElements;
796	},
797
798	componentIds: {},
799
800	getComponentId: function(formId, elementAlias) {
801		if (typeof RSFormPro.HTML5.componentIds[formId] == 'undefined') {
802			RSFormPro.HTML5.componentIds[formId] = {};
803		}
804
805		if (typeof RSFormPro.HTML5.componentIds[formId][elementAlias] == 'undefined') {
806			var block = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(elementAlias));
807			var componentIdBlock = RSFormProUtils.getElementsByClassName('formNoError', 'span', block[0]);
808			if (componentIdBlock.length) {
809				var componentId = componentIdBlock[0].getAttribute('id');
810				RSFormPro.HTML5.componentIds[formId][elementAlias] = componentId.replace('component', '');
811			} else {
812				RSFormPro.HTML5.componentIds[formId][elementAlias] = false;
813			}
814		}
815
816		return RSFormPro.HTML5.componentIds[formId][elementAlias];
817	}
818};
819
820/* Pagination functions */
821
822RSFormPro.Pages = {
823	change: function(formId, page, totalPages, validate, errorClasses) {
824		// callback functions if next page is clicked
825		var direction = RSFormPro.Pages.checkDirection(formId, page);
826		if (direction == 'next') {
827			RSFormPro.callbacks.runCallback(formId, 'nextPage');
828		}
829		RSFormPro.callbacks.runCallback(formId, 'changePage');
830		
831		var thePage;
832
833		if (validate) {
834			var form = RSFormPro.getForm(formId);
835			if (!RSFormPro.Ajax.validate(form, page, errorClasses, totalPages)) {
836				return false;
837			}
838		}
839
840		for (var i = 0; i <= totalPages; i++) {
841			thePage = document.getElementById('rsform_' + formId + '_page_' + i);
842			if (thePage) {
843				rsfp_hidePage(thePage);
844			}
845		}
846
847		thePage = document.getElementById('rsform_' + formId + '_page_' + page);
848		if (thePage) {
849			rsfp_showPage(thePage);
850			try {
851				var func = window["rsfp_showProgress_" + formId];
852				if (typeof func == "function") {
853					func(page);
854				}
855			}
856			catch (err) {}
857		}
858	},
859	hide: function(thePage) {
860		RSFormProUtils.addClass(thePage, 'formHidden');
861	},
862	show: function(thePage) {
863		RSFormProUtils.removeClass(thePage, 'formHidden');
864	},
865	
866	checkDirection : function(formId, page) {
867		var base = RSFormPro.Pages;
868		if (typeof base.history[formId] == 'undefined') {
869			base.history[formId] = page;
870			return 'next';
871		} else {
872			var direction;
873			if (base.history[formId] <= page ) { 
874				direction = 'next';
875			} else {
876				direction = 'prev';
877			}
878			base.history[formId] = page;
879			
880			return direction;
881		}
882	},	
883	history: {}
884};
885
886/* Condition functions */
887RSFormPro.Conditions = {
888	add: function(formId, name, fnCondition) {
889		var form = RSFormPro.getForm(formId);
890
891		if (typeof form != 'undefined') {
892			for (var i = 0; i < form.elements.length; i++) {
893				var element = form.elements[i];
894				if (element.name && (element.name == 'form[' + name + ']' || element.name == 'form[' + name + '][]')) {
895					RSFormProUtils.addEvent(element, 'change', function() {
896						fnCondition();
897					});
898				}
899			}
900		}
901	},
902	run: function(condition) {
903		var formId = condition.form_id,
904            conditions = [],
905            items = [],
906			detail, isChecked, displayValue, match;
907
908		if (typeof condition.details === 'object')
909		{
910			for (var i = 0; i < condition.details.length; i++)
911			{
912				detail = condition.details[i];
913                isChecked = RSFormPro.isChecked(formId, detail.ComponentName, detail.value);
914                conditions.push(isChecked === (detail.operator === 'is'));
915			}
916
917			if (parseInt(condition.block) === 1)
918			{
919				items = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(condition.ComponentName));
920			}
921			else
922			{
923				items = RSFormPro.getFieldsByName(formId, condition.ComponentName);
924			}
925
926			if (items.length > 0)
927			{
928				if (condition.condition === 'all')
929				{
930                    // && conditions need all elements of the Array to be true -> no false in Array
931                    match = conditions.indexOf(false) === -1;
932				}
933				else
934				{
935                    // || conditions need only one element to be true -> one true in array
936					match = conditions.indexOf(true) > -1;
937				}
938
939                if (match)
940                {
941                    displayValue = condition.action === 'show' ? '' : 'none';
942                }
943                else
944                {
945                    displayValue = condition.action === 'show' ? 'none' : '';
946                }
947
948				RSFormProUtils.setDisplay(items, displayValue);
949                if (displayValue === 'none')
950				{
951					RSFormPro.resetValues(RSFormPro.getFieldsByName(formId, condition.ComponentName));
952				}
953			}
954		}
955	},
956	runAll: function(formId) {
957		var func = window["rsfp_runAllConditions" + formId];
958		if (typeof func == "function") {
959			func();
960		}
961	},
962	addReset: function(formId) {
963		var resetElements = RSFormPro.getElementByType(formId, 'reset');
964		if (resetElements.length > 0)
965		{
966			for (var i = 0; i < resetElements.length; i++)
967			{
968				RSFormProUtils.addEvent(resetElements[i], 'click', function() {
969					window.setTimeout(function() {
970						RSFormPro.Conditions.runAll(formId);
971					}, 1);
972				});
973			}
974		}
975	}
976};
977
978/* Calculation functions */
979
980RSFormPro.Calculations = {
981	toDays: function(seconds) {
982		return Math.round(parseFloat(seconds) / 86400);
983	},
984	toHours: function(seconds) {
985		return Math.round(parseFloat(seconds) / 86400 * 24);
986	},
987	addEvents: function(formId, fields) {
988		RSFormProUtils.addEvent(window, 'load', function(){
989			RSFormPro.Calculations._addEvents(formId, fields);
990		});
991	},
992	_addEvents: function(formId, fields) {
993		var func 		= window["rsfp_Calculations" + formId];
994		var thefields	= fields ? fields : RSFormProPrices;
995		var event 		= 'change';
996		
997		var resetElements = RSFormPro.getElementByType(formId, 'reset');
998		if (resetElements.length > 0)
999		{
1000			for (var i = 0; i < resetElements.length; i++)
1001			{
1002				RSFormProUtils.addEvent(resetElements[i], 'click', function() {
1003					if (typeof func == "function") {
1004						window.setTimeout(func, 1);
1005					}
1006				});
1007			}
1008		}
1009
1010		for (var field in thefields) {
1011			if (!thefields.hasOwnProperty(field)) {
1012				continue;
1013			}
1014			field = field.replace(formId+'_','');
1015			objects = RSFormPro.getFieldsByName(formId,field);
1016			for(i = 0; i < objects.length;i++) {
1017				tagName = objects[i].tagName || objects[i].nodeName;
1018
1019				if (tagName == 'INPUT' || tagName == 'SELECT') {
1020					event = 'change';
1021					if (tagName == 'INPUT' && typeof objects[i].type == 'string') {
1022						switch (objects[i].type.toUpperCase())
1023						{
1024							default:
1025								event = 'change';
1026							break;
1027							
1028							case 'NUMBER':
1029							case 'TEXT':
1030								event = 'input';
1031								
1032								if (typeof RSFormPro.jQueryCalendar != 'undefined' &&
1033									typeof RSFormPro.jQueryCalendar.calendars[formId] != 'undefined' &&
1034									typeof RSFormPro.jQueryCalendar.calendars[formId][field] != 'undefined')
1035									{
1036										RSFormPro.jQueryCalendar.calendars[formId][field].calendarInstance.setOptions({onChangeDateTime: function() {
1037											if (typeof func == "function") {
1038												func();
1039											}
1040										}});
1041									}
1042								
1043								if (typeof RSFormPro.YUICalendar != 'undefined' &&
1044									typeof RSFormPro.YUICalendar.calendars[formId] != 'undefined' &&
1045									typeof RSFormPro.YUICalendar.calendars[formId][field] != 'undefined')
1046									{
1047										RSFormPro.YUICalendar.calendars[formId][field].selectEvent.subscribe(function() {
1048											if (typeof func == "function") {
1049												func();
1050											}
1051										}, RSFormPro.YUICalendar.calendars[formId][field], true);
1052									}
1053							break;
1054						}
1055					}
1056
1057					RSFormProUtils.addEvent(objects[i], event, function() {
1058						if (typeof func == "function") {
1059							func();
1060						}
1061					});
1062				}
1063			}
1064		}
1065	}
1066};
1067
1068/* AJAX functions */
1069RSFormPro.Ajax = {
1070	Wait: false,
1071	URL: false,
1072	Params: {},
1073	getParamsObject: function() {
1074		return {
1075			vars: [],
1076			push: function(str) {
1077				return this.vars.push(str);
1078			},
1079			
1080			indexOf: function(str) {
1081				return this.vars.join('&').indexOf(str);
1082			},
1083			
1084			replace: function(r, w) {
1085				this.vars = this.vars.join('&').replace(r, w).split('&');
1086				
1087				return this.vars.join('&');
1088			},
1089			
1090			toString: function() {
1091				return this.vars.join('&');
1092			}
1093		};
1094	},
1095	getXHR: function() {
1096		try {
1097			return new window.XMLHttpRequest();
1098		} catch ( e ) {}
1099	},
1100	getXHRLegacy: function() {
1101		return {
1102			send: function(data)
1103			{
1104				if (data === RSFormPro.Ajax.Params)
1105				{
1106					data = data.toString();
1107				}
1108				
1109				return RSFormPro.Ajax.xhr.send(data);
1110			}
1111		}
1112	},
1113	displayValidationErrors: function(formComponents, task, formId, data) {
1114		if (task == 'afterSend') {
1115			var ids,
1116				i,
1117				j,
1118				id,
1119				formComponent,
1120				firstErrorElement,
1121				elementBlock;
1122
1123			ids = data.response[0].split(',');
1124			for (i = 0; i < ids.length; i++) {
1125				id = parseInt(ids[i]);
1126				if (!isNaN(id) && typeof formComponents[id] != 'undefined') {
1127					formComponent = RSFormPro.getFieldsByName(formId, formComponents[id]);
1128					if (formComponent && formComponent.length > 0) {
1129						for (j = 0; j < formComponent.length; j++) {
1130							if (formComponent[j]) {
1131								RSFormProUtils.removeClass(formComponent[j], 'rsform-error');
1132								if (typeof data.parentErrorClass != 'undefined' && data.parentErrorClass.length > 0) {
1133									try {
1134										elementBlock = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(formComponents[id]));
1135										RSFormProUtils.removeClass(elementBlock[0], data.parentErrorClass);
1136									} catch (err) {}
1137								}
1138								if (typeof data.fieldErrorClass != 'undefined' && data.fieldErrorClass.length > 0) {
1139									try {
1140										results = RSFormPro.getFieldsByName(formId, formComponents[id]);
1141										if (results.length > 0)
1142										{
1143											for (var r = 0; r < results.length; r++)
1144											{
1145												RSFormProUtils.removeClass(results[r], data.fieldErrorClass);
1146											}
1147										}
1148									} catch (err) {}
1149								}
1150							}
1151						}
1152					}
1153				}
1154			}
1155
1156			ids = data.response[1].split(',');
1157			var doScroll = false;
1158			var doFocus = false;
1159			for (i = 0; i < ids.length; i++)
1160			{
1161				id = parseInt(ids[i]);
1162				
1163				if (isNaN(id))
1164				{
1165					continue;
1166				}
1167				
1168				if (typeof formComponents[id] == 'undefined')
1169				{
1170					continue;
1171				}
1172				
1173				formComponent = RSFormPro.getFieldsByName(formId, formComponents[id]);
1174				if (!formComponent || formComponent.length < 1)
1175				{
1176					continue;
1177				}
1178				
1179				for (j = 0; j < formComponent.length; j++)
1180				{
1181					if (formComponent[j])
1182					{
1183						RSFormProUtils.addClass(formComponent[j], 'rsform-error');
1184
1185						if (!doScroll)
1186						{
1187							doScroll = true;
1188						}
1189						
1190						if (typeof data.parentErrorClass != 'undefined' && data.parentErrorClass.length > 0)
1191						{
1192							try
1193							{
1194								elementBlock = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(formComponents[id]));
1195								RSFormProUtils.addClass(elementBlock[0], data.parentErrorClass);
1196							}
1197							catch (err) {}
1198						}
1199						try
1200						{
1201							results = RSFormPro.getFieldsByName(formId, formComponents[id]);
1202							if (results.length > 0)
1203							{
1204								for (var r = 0; r < results.length; r++)
1205								{									
1206									if (typeof data.fieldErrorClass != 'undefined' && data.fieldErrorClass.length > 0)
1207									{
1208										RSFormProUtils.addClass(results[r], data.fieldErrorClass);
1209									}
1210									
1211									if (!doFocus)
1212									{
1213										results[r].focus();
1214										doFocus = true;
1215									}
1216								}
1217							}
1218						}
1219						catch (err) {}
1220					}
1221				}
1222			}
1223			
1224			// scroll to first error elment
1225			if (RSFormPro.scrollToError && doScroll){
1226				RSFormPro.gotoErrorElement(formId);
1227			}
1228		}
1229	},
1230	validate: function(form, page, errorClasses, totalPages) {
1231		try {
1232			var el = form.elements.length;
1233		} catch (err) {
1234			form = this;
1235		}
1236
1237		RSFormPro.Ajax.xhr = RSFormPro.Ajax.getXHR();
1238		RSFormPro.Ajax.xmlHttp = RSFormPro.Ajax.getXHRLegacy();
1239		var url = 'index.php?option=com_rsform&task=ajaxValidate';
1240		if (typeof RSFormPro.Ajax.URL == 'string') {
1241			url = RSFormPro.Ajax.URL;
1242		}
1243		
1244		RSFormPro.Ajax.Params = RSFormPro.Ajax.getParamsObject();
1245
1246		var submits = [],
1247			errorFields = [],
1248			success = false,
1249			formId = 0,
1250			ids,
1251			totalJSDetectedPages = 0,
1252			lastClickedElement,
1253			i,
1254			j;
1255		
1256		if (typeof errorClasses != 'object')
1257		{
1258			errorClasses = {'parent': '', 'field': ''}
1259		}
1260
1261		for (i=0; i<form.elements.length; i++)
1262		{
1263			// try and detect total pages of the form
1264			if (form.elements[i].type == 'button') {
1265				var onclick = form.elements[i].getAttribute('onclick');
1266				if (typeof onclick == 'string' && onclick.indexOf('rsfp_changePage') >= 0) {
1267					var countCommas = 0;
1268					var pos = onclick.indexOf(',');
1269					while (pos > -1) {
1270						++countCommas;
1271						pos = onclick.indexOf(',', ++pos);
1272					}
1273
1274					if (countCommas > 2) {
1275						totalJSDetectedPages++;
1276					}
1277				}
1278			}
1279
1280			// don't send an empty value
1281			if (!form.elements[i].name) continue;
1282			if (form.elements[i].name.length == 0) continue;
1283			// check if the checkbox is checked
1284			if (form.elements[i].type == 'checkbox' && form.elements[i].checked == false) continue;
1285			// check if the radio is selected
1286			if (form.elements[i].type == 'radio' && form.elements[i].checked == false) continue;
1287
1288			if (form.elements[i].type == 'submit' && form.elements[i].getAttribute('data-disableonsubmit') == '1') {
1289				submits.push(form.elements[i]);
1290				form.elements[i].disabled = true;
1291			}
1292
1293			// check if form is a dropdown with multiple selections
1294			if (form.elements[i].type == 'select-multiple')
1295			{
1296				for (j = 0; j < form.elements[i].options.length; j++) {
1297					if (form.elements[i].options[j].selected) {
1298						RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].options[j].value));
1299					}
1300				}
1301
1302				continue;
1303			}
1304
1305			if (form.elements[i].name == 'form[formId]') {
1306				formId = form.elements[i].value;
1307			}
1308
1309			if (typeof RSFormPro.Editors[form.elements[i].name] == 'function') {
1310				RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(RSFormPro.Editors[form.elements[i].name]()));
1311			} else {
1312				RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].value));
1313			}
1314		}
1315
1316		errorFields = RSFormPro.HTML5.validation(formId);
1317
1318		if (page) {
1319			RSFormPro.Ajax.Params.push('page=' + page);
1320		}
1321
1322		RSFormPro.Ajax.xhr.open("POST", url, true);
1323
1324		//Send the proper header information along with the request
1325		RSFormPro.Ajax.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
1326		
1327		if (typeof ajaxExtraValidationScript[formId] == 'function') {
1328			ajaxExtraValidationScript[formId]('beforeSend', formId, {'url': url, 'params': RSFormPro.Ajax.Params});
1329		}
1330
1331		if (!RSFormPro.Ajax.Wait)
1332		{
1333			// B/C layer
1334			RSFormPro.Ajax.xmlHttp.send(RSFormPro.Ajax.Params);
1335		}
1336		success = true;
1337		
1338		RSFormPro.Ajax.xhr.onreadystatechange = function() {
1339			if (RSFormPro.Ajax.xhr.readyState == 4 && RSFormPro.Ajax.xhr.status == 200) {
1340				if (RSFormPro.Ajax.xhr.responseText.indexOf("\n") != -1)
1341				{
1342
1343					var response = RSFormPro.Ajax.xhr.responseText.split("\n");
1344					// All spans set to no error
1345					ids = response[0].split(',');
1346					for (i = 0; i < ids.length; i++)
1347						if (!isNaN(parseInt(ids[i])) && document.getElementById('component'+ids[i])) {
1348							document.getElementById('component'+ids[i]).className = 'formNoError';
1349						}
1350
1351					// Show errors
1352					ids = response[1].split(',');
1353
1354					// add the HTML5 elements with errors
1355					var errorOnPage;
1356					if (errorFields.length) {
1357						for (i = 0; i < errorFields.length; i++) {
1358							if (typeof errorFields[i].componentId != 'undefined') {
1359								if (typeof page == 'undefined' || (page - 1) == errorFields[i].page) {
1360									ids.push(errorFields[i].componentId);
1361									if (typeof errorOnPage != 'undefined') {
1362										errorOnPage = errorFields[i].page < errorOnPage ? errorFields[i].page : errorOnPage;
1363									} else {
1364										errorOnPage = errorFields[i].page;
1365									}
1366								}
1367							}
1368						}
1369					}
1370
1371
1372					var errorComponents = [];
1373					for (i = 0; i < ids.length; i++) {
1374						if (!isNaN(parseInt(ids[i])))
1375						{
1376							if (document.getElementById('component' + ids[i]))
1377							{
1378								document.getElementById('component' + ids[i]).className = 'formError';
1379							}
1380							errorComponents.push(ids[i]);
1381							success = false;
1382						}
1383					}
1384
1385					// lets detect if the multiple page form is submitted
1386
1387					var changePageHTML5Errors = false;
1388					if (totalJSDetectedPages > 0 && RSClickedSubmitElement && submits.indexOf(RSClickedSubmitElement) >= 0 && typeof errorOnPage != 'undefined') {
1389						changePageHTML5Errors = true;
1390					}
1391					//return false;
1392					if (response.length == 4 || changePageHTML5Errors)
1393					{
1394						if (response.length == 4) {
1395							page = parseInt(response[2]) - 1;
1396							totalPages = parseInt(response[3]);
1397							if (changePageHTML5Errors) {
1398								page = page > errorOnPage ? errorOnPage : page;
1399							}
1400						} else {
1401							if (changePageHTML5Errors) {
1402								page = errorOnPage;
1403								totalPages = totalJSDetectedPages;
1404							}
1405						}
1406
1407						rsfp_changePage(formId, page, totalPages, false);
1408					}
1409
1410					if (typeof ajaxExtraValidationScript[formId] == 'function') {
1411						// rewrite the response so that all the error components are added (that includes HTML5 fields)
1412						if (errorComponents.length) {
1413							response[1] = errorComponents.join();
1414						}
1415						ajaxExtraValidationScript[formId]('afterSend', formId, {'url': url, 'params': RSFormPro.Ajax.Params, 'response': response, 'parentErrorClass': errorClasses.parent, 'fieldErrorClass': errorClasses.field});
1416					}
1417				}
1418				
1419				if (success == false)
1420				{
1421					// The submits must be clickable again
1422					for (i = 0; i < submits.length; i++) {
1423						submits[i].disabled = false;
1424					}
1425
1426					try {
1427						if (typeof page == 'undefined' || page == 0) {
1428							RSFormPro.callbacks.runCallback(formId, 'afterValidationFailed'); // callback functions if validation fails when form is submitted
1429						} else {
1430							RSFormPro.callbacks.runCallback(formId, 'nextPageFailed'); // callback functions if validation fails when a specific page of the form is checked
1431						}
1432						if (document.getElementById('rsform_error_' + formId)) {
1433							document.getElementById('rsform_error_' + formId).style.display = 'block';
1434						}
1435					}
1436					catch (err) { }
1437				}
1438
1439				if (success == true) {
1440					// Change the page if the validation passes
1441					if (page) {
1442						rsfp_changePage(formId, page, totalPages, false);
1443						// The submits must be clickable again
1444						for (i = 0; i < submits.length; i++) {
1445							submits[i].disabled = false;
1446						}
1447					} else {
1448						// the submit button has been presed so we need to submit the form
1449						// if the submit button or any other element has the id submit the form.submit() function is overwritten
1450						if (typeof form.submit != 'function') {
1451							document.createElement('form').submit.call(form)
1452						} else {
1453							form.submit();
1454						}
1455					}
1456
1457					try {
1458						if (typeof page == 'undefined' || page == 0) {
1459							RSFormPro.callbacks.runCallback(formId, 'afterValidationSuccess'); // callback functions if validation succeeds
1460						} else {
1461							RSFormPro.callbacks.runCallback(formId, 'nextPageSuccess'); // callback functions if validation succeeds when a specific page of the form is checked
1462						}
1463						document.getElementById('rsform_error_' + formId).style.display = 'none';
1464					}
1465					catch (err) { }
1466				}
1467				return success;
1468			}
1469		};
1470
1471		return false;
1472	},
1473	overrideSubmit: function(formId, validationParams) {
1474        var form = RSFormPro.getForm(formId);
1475        var submitElement = RSFormPro.getElementByType(formId, 'submit');
1476		var i, j;
1477        for (i = 0; i < submitElement.length; i++) {
1478			if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
1479				RSFormProUtils.addEvent(submitElement[i],'click', (function(event) {
1480					event.preventDefault();
1481					RSClickedSubmitElement = this;
1482					for (j = 0; j < submitElement.length; j++) {
1483						submitElement[j].setAttribute('data-disableonsubmit','1');
1484					}
1485					RSFormPro.Ajax.validate(form, undefined, validationParams);
1486				}));
1487			}
1488		}
1489	}
1490};
1491
1492RSFormPro.callbacks = {
1493	allCallbacks: {},
1494	
1495	addCallback: function(formId, callbackName, args) {
1496		var base = RSFormPro.callbacks;
1497		
1498		if (typeof base.allCallbacks[formId] == 'undefined') {
1499			base.allCallbacks[formId] = {}
1500		}
1501		
1502		if (typeof base.allCallbacks[formId][callbackName] == 'undefined') {
1503			base.allCallbacks[formId][callbackName] = [];
1504		}
1505		
1506		base.allCallbacks[formId][callbackName].push(args);
1507	},
1508	
1509	runCallback: function(formId, callbackName) {
1510		var base = RSFormPro.callbacks;
1511		if (typeof base.allCallbacks[formId] != 'undefined' && typeof base.allCallbacks[formId][callbackName] != 'undefined' && base.allCallbacks[formId][callbackName].length > 0) {
1512			for (var i = 0; i < base.allCallbacks[formId][callbackName].length; i++) {
1513				var args = base.allCallbacks[formId][callbackName][i];
1514				var functionName = args[0];
1515				
1516				var functionArgs =  [];
1517				for (var j = 1; j < args.length; j++) {
1518					functionArgs.push(args[j]);
1519				}
1520				
1521				// execute the callback function set for this trigger
1522				functionName.apply(self, functionArgs);
1523			}
1524		}
1525	}
1526};
1527
1528/* Helper functions */
1529
1530var RSFormProUtils = {
1531	addEvent: function(obj, evType, fn) {
1532		if (obj.addEventListener)
1533		{
1534			obj.addEventListener(evType, fn, false);
1535			return true;
1536		}
1537		else if (obj.attachEvent)
1538		{
1539			var r = obj.attachEvent("on"+evType, fn);
1540			return r;
1541		}
1542		else
1543		{
1544			return false;
1545		}
1546	},
1547	hasClass: function (el, name) {
1548		return new RegExp('(\\s|^)' + name + '(\\s|$)').test(el.className);
1549	},
1550	addClass: function(el, name) {
1551		if (!RSFormProUtils.hasClass(el, name)) {
1552			el.className += (el.className ? ' ' : '') + name;
1553		}
1554	},
1555	removeClass: function(el, name) {
1556		if (RSFormProUtils.hasClass(el, name)) {
1557			el.className = el.className.replace(new RegExp('(\\s|^)' + name + '(\\s|$)'),' ').replace(/^\s+|\s+$/g, '');
1558		}
1559	},
1560	setDisplay: function (items, value) {
1561		for (var i = 0; i < items.length; i++) {
1562			if (!RSFormPro.usePositioning) {
1563				items[i].style.display = value;
1564			} else {
1565				value === 'none' ? RSFormProUtils.addClass(items[i], 'formHidden') : RSFormProUtils.removeClass(items[i], 'formHidden');
1566			}
1567		}
1568	},
1569	setAttr: function (items, attr, value) {
1570        for (var i = 0; i < items.length; i++) {
1571            items[i].setAttribute(attr, value);
1572        }
1573	},
1574    remAttr: function (items, attr) {
1575        for (var i = 0; i < items.length; i++) {
1576            items[i].removeAttribute(attr);
1577        }
1578    },
1579	getChecked: function (items) {
1580		var elements = [];
1581		var element, tagName;
1582        for (var i = 0; i < items.length; i++) {
1583        	element = items[i];
1584            tagName = element.tagName || element.nodeName;
1585
1586            if (tagName == 'INPUT' && element.type && element.type.toUpperCase() == 'CHECKBOX' && element.checked == true) {
1587				elements.push(element);
1588			}
1589        }
1590
1591        return elements;
1592	},
1593    getUnchecked: function (items) {
1594        var elements = [];
1595        var element, tagName;
1596        for (var i = 0; i < items.length; i++) {
1597            element = items[i];
1598            tagName = element.tagName || element.nodeName;
1599
1600            if (tagName == 'INPUT' && element.type && element.type.toUpperCase() == 'CHECKBOX' && !element.checked) {
1601                elements.push(element);
1602            }
1603        }
1604
1605        return elements;
1606    },
1607	getAlias: function(str) {
1608		str = str.replace(/\-/g, ' ');
1609
1610		if (!String.prototype.trim) {
1611			str = str.replace(/^\s+|\s+$/g, '');
1612		} else {
1613			str = str.trim();
1614		}
1615
1616		str = str.toLowerCase();
1617		str = str.replace(/(\s|[^A-Za-z0-9\-])+/g, '-');
1618		str = str.replace(/^\-+|\-+$/g, '');
1619
1620		return str;
1621	},
1622	getElementsByClassName: function (className, tag, elm) {
1623		if (document.getElementsByClassName) {
1624			getElementsByClassName = function (className, tag, elm) {
1625				elm = elm || document;
1626				var elements = elm.getElementsByClassName(className),
1627					nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
1628					returnElements = [],
1629					current;
1630				for(var i=0, il=elements.length; i<il; i+=1){
1631					current = elements[i];
1632					if(!nodeName || nodeName.test(current.nodeName)) {
1633						returnElements.push(current);
1634					}
1635				}
1636				return returnElements;
1637			};
1638		} else if (document.evaluate) {
1639			getElementsByClassName = function (className, tag, elm) {
1640				tag = tag || "*";
1641				elm = elm || document;
1642				var classes = className.split(" "),
1643					classesToCheck = "",
1644					xhtmlNamespace = "http://www.w3.org/1999/xhtml",
1645					namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
1646					returnElements = [],
1647					elements,
1648					node;
1649				for(var j=0, jl=classes.length; j<jl; j+=1){
1650					classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
1651				}
1652				try	{
1653					elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
1654				}
1655				catch (e) {
1656					elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
1657				}
1658				while ((node = elements.iterateNext())) {
1659					returnElements.push(node);
1660				}
1661				return returnElements;
1662			};
1663		} else {
1664			getElementsByClassName = function (className, tag, elm) {
1665				tag = tag || "*";
1666				elm = elm || document;
1667				var classes = className.split(" "),
1668					classesToCheck = [],
1669					elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
1670					current,
1671					returnElements = [],
1672					match;
1673				for(var k=0, kl=classes.length; k<kl; k+=1){
1674					classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
1675				}
1676				for(var l=0, ll=elements.length; l<ll; l+=1){
1677					current = elements[l];
1678					match = false;
1679					for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
1680						match = classesToCheck[m].test(current.className);
1681						if (!match) {
1682							break;
1683						}
1684					}
1685					if (match) {
1686						returnElements.push(current);
1687					}
1688				}
1689				return returnElements;
1690			};
1691		}
1692
1693		return getElementsByClassName(className, tag, elm);
1694	}
1695};
1696
1697function isset() {
1698  // http://kevin.vanzonneveld.net
1699  // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
1700  // +   improved by: FremyCompany
1701  // +   improved by: Onno Marsman
1702  // +   improved by: Rafał Kukawski
1703  // *     example 1: isset( undefined, true);
1704  // *     returns 1: false
1705  // *     example 2: isset( 'Kevin van Zonneveld' );
1706  // *     returns 2: true
1707  var a = arguments,
1708    l = a.length,
1709    i = 0,
1710    undef;
1711
1712  if (l === 0) {
1713    throw new Error('Empty isset');
1714  }
1715
1716  while (i !== l) {
1717    if (a[i] === undef || a[i] === null) {
1718      return false;
1719    }
1720    i++;
1721  }
1722  return true;
1723}
1724
1725/* Legacy functions */
1726
1727function rsfp_geolocation(term, id, mapid,  map, marker, geocoder, type) {
1728	return RSFormPro.initGeoLocation(term, id, mapid, map, marker, geocoder, type);
1729}
1730
1731function refreshCaptcha(componentId, captchaPath) {
1732	return RSFormPro.refreshCaptcha(componentId, captchaPath);
1733}
1734
1735function number_format(number, decimals, dec_point, thousands_sep) {
1736	return RSFormPro.formatNumber(number, decimals, dec_point, thousands_sep);
1737}
1738
1739function rsfp_toNumber(number, decimal, thousands, decimals) {
1740	return RSFormPro.toNumber(number, decimal, thousands, decimals);
1741}
1742
1743function rsfp_getForm(formId) {
1744	return RSFormPro.getForm(formId);
1745}
1746
1747function rsfp_getValue(formId, name) {
1748	return RSFormPro.getValue(formId, name);
1749}
1750
1751function rsfp_verifyChecked(formId, name, value) {
1752	return RSFormPro.isChecked(formId, name, value);
1753}
1754
1755function rsfp_getBlock(formId, block) {
1756	return RSFormPro.getBlock(formId, block);
1757}
1758
1759function rsfp_getFieldsByName(formId, name) {
1760	return RSFormPro.getFieldsByName(formId, name);
1761}
1762
1763function rsfp_addEvent(obj, evType, fn) {
1764	return RSFormProUtils.addEvent(obj, evType, fn);
1765}
1766
1767function rsfp_setDisplay(items, value) {
1768	return RSFormProUtils.setDisplay(items, value);
1769}
1770
1771function stringURLSafe(str) {
1772	return RSFormProUtils.getAlias(str);
1773}
1774
1775function rsfp_changePage(formId, page, totalPages, validate, errorClasses) {
1776	return RSFormPro.Pages.change(formId, page, totalPages, validate, errorClasses);
1777}
1778
1779function rsfp_hidePage(thePage) {
1780	return RSFormPro.Pages.hide(thePage);
1781}
1782
1783function rsfp_showPage(thePage) {
1784	return RSFormPro.Pages.show(thePage);
1785}
1786
1787function rsfp_checkValidDate(fieldName) {
1788	return RSFormPro.disableInvalidDates(fieldName);
1789}
1790
1791function rsfp_addCondition(formId, name, fnCondition) {
1792	return RSFormPro.Conditions.add(formId, name, fnCondition);
1793}
1794
1795function rsfp_runAllConditions(formId) {
1796	return RSFormPro.Conditions.runAll(formId);
1797}
1798
1799function rsfp_setCalculationsEvents(formId, fields) {
1800	return RSFormPro.Calculations.addEvents(formId, fields);
1801}
1802
1803function getElementsByClassName(className, tag, elm) {
1804	return RSFormProUtils.getElementsByClassName(className, tag, elm);
1805}
1806
1807function buildXmlHttp() {
1808	return RSFormPro.Ajax.getXHR();
1809}
1810
1811function ajaxDisplayValidationErrors(formComponents, task, formId, data) {
1812	return RSFormPro.Ajax.displayValidationErrors(formComponents, task, formId, data);
1813}
1814
1815function ajaxValidation(form, page, errorClasses) {
1816	return RSFormPro.Ajax.validate(form, page, errorClasses);
1817}

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.