PageSourceSearch

https://ville-saintjeandelaruelle.fr/media/com_rsform/js/script.js?b0b3fd3c143b6d88344f507be2e497e8

js ville-saintjeandelaruelle.fr collected 2026-09-24 20:04:44 UTC 91,724 bytes, 3,049 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				var 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						RSFormPro.submitForm(this.form);
65					}
66				}
67			}));
68		}
69	}
70};
71
72RSFormPro.formEvents = {};
73
74RSFormPro.addFormEvent = function(formId, func) {
75	if (typeof RSFormPro.formEvents[formId] !== 'object') {
76		RSFormPro.formEvents[formId] = [];
77	}
78
79	RSFormPro.formEvents[formId].push(func);
80};
81
82RSFormPro.submitForm = function(form) {
83	var formId = form.elements['form[formId]'].value;
84	var func;
85
86	if (typeof RSFormPro.formEvents[formId] === 'object' && RSFormPro.formEvents[formId].length > 0) {
87		func = RSFormPro.formEvents[formId].shift()
88		if (typeof func === 'function') {
89			func();
90
91			return false;
92		}
93	}
94
95	// if the submit button or any other element has the id submit the form.submit() function is overwritten
96	RSFormPro.triggerEvent(form, 'submit');
97	if (typeof form.submit === 'function') {
98		form.submit();
99	} else {
100		document.createElement('form').submit.call(form)
101	}
102};
103
104/* Disable the submit button when form is submitted functions */
105RSFormPro.setDisabledSubmit = function(formId, ajaxValidation){
106	if (!ajaxValidation) {
107		var i, j;
108		var submitElement = RSFormPro.getElementByType(formId, 'submit');
109		for (i = 0; i < submitElement.length; i++) {
110			if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
111				RSFormProUtils.addEvent(submitElement[i],'click', (function(event) {
112					event.preventDefault();
113					for (j = 0; j < submitElement.length; j++) {
114						submitElement[j].disabled = true;
115					}
116				}));
117			}
118		}
119	}
120};
121/* Thank You Message in Popup Window functions */
122
123RSFormPro.showThankYouPopup = function (thankYouContainer){
124	var content = thankYouContainer.innerHTML;
125	var gotoUrl = thankYouContainer.querySelector('#rsfp-thankyou-popup-return-link').value;
126
127	// remove the html part from the layout
128	thankYouContainer.parentNode.removeChild(thankYouContainer);
129
130	RSFormProUtils.addClass(document.body, 'rsfp_popup_activated');
131
132	var outer = document.createElement('div');
133	outer.setAttribute('class', 'rsfp_thankyou_popup_outer');
134	outer.onclick = function() {
135		if (event && event.target && (RSFormProUtils.hasClass(event.target, 'rsfp_thankyou_popup_outer') || RSFormProUtils.hasClass(event.target, 'rsfp_thankou_popup_close_btn'))) {
136            destroyPopup();
137            redirectUrl();
138		}
139	};
140
141	var inner = document.createElement('div');
142	inner.setAttribute('class', 'rsfp_thankyou_popup_inner');
143	inner.setAttribute('id', 'rsfp_thankyou_popup_inner');
144	inner.innerHTML = content;
145
146	var close = document.createElement('div');
147	close.setAttribute('class', 'rsfp_thankou_popup_close_btn');
148	close.innerHTML = '&times;';
149
150	outer.appendChild(inner);
151	inner.appendChild(close);
152
153	document.body.appendChild(outer);
154
155	document.getElementById('rsfp_thankyou_popup_inner').style.marginTop = (window.innerHeight - document.getElementById('rsfp_thankyou_popup_inner').offsetHeight) / 2 + 'px';
156
157	var continueButton = outer.querySelector('[name=continue]');
158	if (continueButton) {
159		continueButton.removeAttribute('onclick');
160		continueButton.onclick = function() {
161			destroyPopup();
162			redirectUrl();
163		}
164	}
165
166	var redirectUrl = function() {
167        if (gotoUrl.length > 0) {
168            document.location = gotoUrl;
169        } else {
170            document.location.reload(true);
171        }
172	};
173
174	var destroyPopup = function() {
175        RSFormProUtils.removeClass(document.body, 'rsfp_popup_activated');
176
177        document.body.removeChild(outer);
178	};
179};
180
181/* Scroll to first error element */
182RSFormPro.gotoErrorElement = function(formId){
183	var form = RSFormPro.getForm(formId);
184	var errorElements = form.getElementsByClassName('formError');
185	if (errorElements.length) {
186		var block = RSFormPro.findAncestor(errorElements[0], 'rsform-block');
187		if (block) {
188			RSFormPro.scrollToElement(block);
189		} else {
190			RSFormPro.scrollToElement(errorElements[0]);
191		}
192	}
193};
194
195RSFormPro.findAncestor = function(el, cls){
196	while(el = el.parentElement) {
197		var elementClasses = el.className;
198		elementClasses = elementClasses.split(' ');
199		if (elementClasses.indexOf(cls) > -1) {
200			return el;
201		}
202	}
203
204	return false;
205};
206
207/* Reset all values, used with reset button for the submit */
208RSFormPro.resetElements = function(formId) {
209	var form 	= RSFormPro.getForm(formId);
210
211	if (form && form.elements.length) {
212		RSFormPro.resetValues(form.elements);
213	}
214};
215
216/* ScrollTo functions */
217RSFormPro.scrollToElement = function(element){
218	var to = element.offsetTop;
219	var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
220	var documentView = window.innerHeight + scrollTop;
221
222	// this is more specific for the modern browsers
223	if (typeof element.getBoundingClientRect === 'function') {
224		to = element.getBoundingClientRect().top + scrollTop;
225	}
226
227	if (to < scrollTop || to > documentView) {
228		RSFormPro.scrollTo(to, 300);
229	}
230};
231
232RSFormPro.scrollTo = function(to, duration) {
233	if (duration <= 0) return;
234	var elementScrollTop = window.pageYOffset ?  window.pageYOffset : document.documentElement.scrollTop;
235	var difference = to - elementScrollTop;
236	var perTick = difference / duration * 10;
237	
238	window.setTimeout(function() {
239		var limitControl;
240		limitControl = window.pageYOffset ?  window.pageYOffset : document.documentElement.scrollTop;
241		limitControl = limitControl + perTick;
242		window.scrollTo(0, limitControl);
243		// if the element has been reached or the scroll is at the bottom of the page no need to continue
244		if (limitControl == to) return;
245
246		RSFormPro.scrollTo(to, duration - 10);
247	}, 10);
248};
249
250/* Field specific functions */
251
252RSFormPro.refreshCaptcha = function(componentId, captchaPath) {
253	if (!captchaPath) {
254		captchaPath = 'index.php?option=com_rsform&task=captcha&format=image&componentId=' + componentId;
255	}
256	document.getElementById('captcha' + componentId).src = captchaPath + '&' + Math.random();
257	document.getElementById('captchaTxt' + componentId).value = '';
258	document.getElementById('captchaTxt' + componentId).focus();
259};
260
261RSFormPro.geoLocationTimeouts = {};
262
263RSFormPro.initGeoLocation = function(term, id, mapid, map, marker, geocoder, type) {
264	var content = document.getElementById('rsform_geolocation'+id);
265	var address	= document.getElementById(mapid).clientWidth;
266
267	document.getElementById('rsform_geolocation'+id).style.width = address+'px';
268	document.getElementById('rsform_geolocation'+id).style.display = 'none';
269	document.getElementById('rsform_geolocation'+id).innerHTML = '';
270
271	if (typeof RSFormPro.geoLocationTimeouts[id] !== 'undefined')
272	{
273		window.clearTimeout(RSFormPro.geoLocationTimeouts[id]);
274	}
275
276	if (term != '') {
277		RSFormPro.geoLocationTimeouts[id] = window.setTimeout(function(){
278			geocoder.geocode( {'address': term }, function(results, status) {
279				if (status == 'OK') {
280					for (var i=0; i<results.length; i++) {
281						var item	= results[i];
282						var theli	= document.createElement('li');
283						var thea	= document.createElement('a');
284
285						thea.setAttribute('href','javascript:void(0)');
286						thea.innerHTML = item.formatted_address;
287
288						RSFormProUtils.addEvent(thea,'click', (function() {
289							var mapValue = type ? item.formatted_address : item.geometry.location.lat().toFixed(5) + ',' + item.geometry.location.lng().toFixed(5);
290							var mapId	 = mapid;
291							var location = new google.maps.LatLng(item.geometry.location.lat().toFixed(5), item.geometry.location.lng().toFixed(5));
292
293							return function() {
294								document.getElementById(mapId).value = mapValue;
295								marker.setPosition(location);
296								map.setCenter(location);
297								document.getElementById('rsform_geolocation'+id).style.display = 'none';
298							}
299						})());
300
301						theli.appendChild(thea);
302						content.appendChild(theli);
303					}
304
305					document.getElementById('rsform_geolocation'+id).style.display = '';
306				}
307			});
308		}, 500);
309	}
310};
311
312RSFormPro.initGoogleMaps = function() {
313
314}
315RSFormPro.googleMapIds = [];
316
317RSFormPro.requestLocation = function() {
318	if (navigator && navigator.geolocation && navigator.geolocation.getCurrentPosition) {
319		navigator.geolocation.getCurrentPosition(function(position){
320			var id, map, marker;
321
322			for (var i = 0; i < RSFormPro.googleMapIds.length; i++)
323			{
324				id = RSFormPro.googleMapIds[i];
325				map = window['rsformmap' + id];
326				marker = window['rsformmarker' + id];
327
328				map.setCenter({lat: position.coords.latitude, lng: position.coords.longitude});
329				marker.setPosition({lat: position.coords.latitude, lng: position.coords.longitude});
330				google.maps.event.trigger(marker, 'drag');
331			}
332		});
333	}
334};
335
336RSFormPro.disableInvalidDates = function(fieldName) {
337	var theDate = new Date(),
338		day,
339		index;
340
341	for (day = 1; day <= 31; day++) {
342		var year 	= parseInt(document.getElementById(fieldName + 'y').value);
343		var month 	= parseInt(document.getElementById(fieldName + 'm').value) - 1;
344
345		index = day - 1;
346		if (document.getElementById(fieldName + 'd').options[0].value == '') {
347			index++;
348		}
349		document.getElementById(fieldName + 'd').options[index].disabled = false;
350		if (!isNaN(year) && !isNaN(month)) {
351			if (typeof theDate.__msh_oldSetFullYear == 'function') {
352				theDate.__msh_oldSetFullYear(year, month, day);
353			} else {
354				theDate.setFullYear(year, month, day);
355			}
356
357			if (theDate.getDate() != day || theDate.getMonth() != month) {
358				document.getElementById(fieldName + 'd').options[index].disabled = true;
359			}
360		}
361	}
362	if (document.getElementById(fieldName + 'd').options[document.getElementById(fieldName + 'd').selectedIndex].disabled == true) {
363		for (day = 31; day >= 28; day--) {
364			index = day - 1;
365			if (document.getElementById(fieldName + 'd').options[0].value == '') {
366				index++;
367			}
368			if (document.getElementById(fieldName + 'd').options[index].disabled == false) {
369				document.getElementById(fieldName + 'd').value = day;
370				break;
371			}
372		}
373	}
374};
375
376RSFormPro.addMoreFiles = function(button) {
377	var previousElement = button.previousElementSibling;
378	var previousInputs = previousElement.getElementsByTagName('input');
379	var originalInput;
380	if (previousInputs.length)
381	{
382		for (var k = 0; k < previousInputs.length; k++)
383		{
384			if (previousInputs[k].type && previousInputs[k].type.toUpperCase() === 'FILE')
385			{
386				originalInput = previousInputs[k];
387				break;
388			}
389		}
390	}
391
392	var clone = previousElement.cloneNode(true);
393	var inputs = clone.getElementsByTagName('input');
394	if (inputs.length)
395	{
396		for (var i = 0; i < inputs.length; i++)
397		{
398			if (inputs[i].type && inputs[i].type.toUpperCase() === 'FILE')
399			{
400				var fieldName = inputs[i].getAttribute('id');
401				inputs[i].value = '';
402
403				if (originalInput)
404				{
405					RSFormProUtils.addEvent(inputs[i], 'change', function() {
406						RSFormPro.triggerEvent(originalInput, 'change');
407					});
408				}
409			}
410		}
411	}
412
413	var images = clone.getElementsByTagName('img');
414	if (images.length)
415	{
416		for (var j = 0; j < images.length; j++)
417		{
418			if (RSFormProUtils.hasClass(images[j], 'rsfp-image-polaroid'))
419			{
420				images[j].parentNode.parentNode.removeChild(images[j].parentNode);
421			}
422		}
423	}
424
425	button.parentNode.appendChild(clone);
426
427	var maxFiles = parseInt(button.getAttribute('data-rsfp-maxfiles'));
428	if (maxFiles > 0)
429	{
430		if (RSFormPro.getFieldsByName(button.getAttribute('data-rsfp-formid'), fieldName).length / 2 >= maxFiles)
431		{
432			button.disabled = true;
433		}
434	}
435};
436
437RSFormPro.openImageModal = function(element) {
438	var modal = document.createElement('div');
439	modal.setAttribute('class', 'rsfp-modal');
440
441	var close = document.createElement('span');
442	close.innerHTML = '&times;';
443	close.setAttribute('class', 'rsfp-modal-close-button');
444	modal.onclick = close.onclick = function() {
445		modal.parentNode.removeChild(modal);
446	};
447
448	var img = document.createElement('img');
449	img.setAttribute('class', 'rsfp-modal-image');
450	img.setAttribute('src', element.getAttribute('src'));
451
452	var caption = document.createElement('div');
453	caption.setAttribute('class', 'rsfp-modal-caption');
454	caption.innerHTML = element.getAttribute('alt');
455
456	modal.appendChild(close);
457	modal.appendChild(img);
458	modal.appendChild(caption);
459
460	document.getElementsByTagName('body')[0].appendChild(modal);
461
462	modal.style.display = 'block';
463}
464
465RSFormPro.loadImage = function(input) {
466	if ('files' in input && typeof FileReader === 'function')
467	{
468		var file, reader;
469
470		var images = input.parentNode.querySelectorAll('.rsfp-image-container');
471
472		for (var j = 0; j < images.length; j++)
473		{
474			images[j].parentNode.removeChild(images[j]);
475		}
476
477		for (var i = 0; i < input.files.length; i++)
478		{
479			file = input.files[i];
480
481			reader = new FileReader();
482			reader.onload = function(e) {
483				var div = document.createElement('div');
484				div.setAttribute('class', 'rsfp-image-container');
485
486				var img = document.createElement('img');
487				img.setAttribute('src', e.target.result);
488				img.setAttribute('alt', file.name);
489				img.setAttribute('title', file.name);
490				img.setAttribute('class', 'rsfp-image-polaroid');
491				img.onerror = function() {
492					img.src = "data:image/svg+xml,%3Csvg role='img' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='currentColor' d='M256 8C119.034 8 8 119.033 8 256s111.034 248 248 248 248-111.034 248-248S392.967 8 256 8zm130.108 117.892c65.448 65.448 70 165.481 20.677 235.637L150.47 105.216c70.204-49.356 170.226-44.735 235.638 20.676zM125.892 386.108c-65.448-65.448-70-165.481-20.677-235.637L361.53 406.784c-70.203 49.356-170.226 44.736-235.638-20.676z'%3E%3C/path%3E%3C/svg%3E";
493					img.onclick = false;
494				};
495				img.onclick = function() {
496					RSFormPro.openImageModal(this);
497				};
498
499				div.appendChild(img);
500
501				input.parentNode.insertBefore(div, input.nextSibling);
502			};
503
504			reader.readAsDataURL(file);
505		}
506	}
507};
508
509/* Number functions */
510
511RSFormPro.formatNumber = function(number, decimals, dec_point, thousands_sep) {
512	var n = number, prec = decimals;
513	n = !isFinite(+n) ? 0 : +n;
514	prec = !isFinite(+prec) ? 0 : Math.abs(prec);
515	var sep = (typeof thousands_sep == "undefined") ? ',' : thousands_sep;
516	var dec = (typeof dec_point == "undefined") ? '.' : dec_point;
517
518	var s = (prec > 0) ? n.toFixed(prec) : Math.round(n).toFixed(prec); //fix for IE parseFloat(0.55).toFixed(0) = 0;
519
520	var abs = Math.abs(n).toFixed(prec);
521	var _, i;
522
523	if (abs >= 1000) {
524		_ = abs.split(/\D/);
525		i = _[0].length % 3 || 3;
526
527		_[0] = s.slice(0,i + (n < 0)) +
528			_[0].slice(i).replace(/(\d{3})/g, sep+'$1');
529
530		s = _.join(dec);
531	} else {
532		s = s.replace('.', dec);
533	}
534
535	return s;
536};
537
538RSFormPro.toNumber = function(number, decimal, thousands, decimals) {
539	// Remove decimals first
540	if (parseInt(decimals) > 0 && number.lastIndexOf(decimal) > -1) {
541		var index = number.lastIndexOf(decimal);
542		number = number.substring(0, index) + 'DECIMALS' + number.substring(index + 1);
543	}
544
545	// Remove thousands separator
546	if (number.indexOf(thousands) > -1) {
547		number = number.split(thousands).join('');
548	}
549
550	number = number.split('DECIMALS').join('.');
551	return parseFloat(number);
552};
553
554/* Form and element functions */
555
556RSFormPro.getForm = function(formId) {
557	if (typeof RSFormPro.Forms[formId] == 'undefined') {
558		var formIds = document.getElementsByName('form[formId]');
559		for (var i=0; i<formIds.length; i++)
560		{
561			if (parseInt(formIds[i].value) != parseInt(formId))
562				continue;
563
564			var form = formIds[i].parentNode;
565			if (form.tagName == 'FORM' || form.nodeName == 'FORM') {
566				RSFormPro.Forms[formId] = form;
567				return form;
568			}
569
570			while (form.parentNode)
571			{
572				form = form.parentNode;
573				if (form.tagName == 'FORM' || form.nodeName == 'FORM') {
574					RSFormPro.Forms[formId] = form;
575					return form;
576				}
577			}
578		}
579	}
580
581	return RSFormPro.Forms[formId];
582};
583
584RSFormPro.getValue = function(formId, name) {
585	var form	= RSFormPro.getForm(formId);
586	var values	= [];
587
588	if (typeof form != 'undefined')
589	{
590		for (var i = 0; i < form.elements.length; i++)
591		{
592			var element = form.elements[i];
593			var tagName = element.tagName || element.nodeName;
594
595			switch (tagName)
596			{
597				case 'INPUT':
598					if (element.type)
599						switch (element.type.toUpperCase())
600						{
601							case 'TEXT':
602							case 'NUMBER':
603							case 'HIDDEN':
604								if (!element.name || element.name != 'form[' + name + ']') continue;
605								
606								if (typeof RSFormPro.YUICalendar != 'undefined' &&
607									typeof RSFormPro.YUICalendar.calendars[formId] != 'undefined' &&
608									typeof RSFormPro.YUICalendar.calendars[formId][name] != 'undefined')
609									{
610										var selectedDate = new Date(RSFormPro.YUICalendar.calendars[formId][name].getSelectedDates()[0]);
611										return (selectedDate.getTime() / 1000).toString();
612									}
613								
614								if (typeof RSFormPro.jQueryCalendar != 'undefined' &&
615									typeof RSFormPro.jQueryCalendar.calendars[formId] != 'undefined' &&
616									typeof RSFormPro.jQueryCalendar.calendars[formId][name] != 'undefined')
617									{
618										var tmpDate = RSFormPro.jQueryCalendar.calendars[formId][name].calendarInstance.getValue();
619
620										if (RSFormPro.jQueryCalendar.calendars[formId][name].hiddenFormat.indexOf('HH:mm') === -1)
621										{
622											tmpDate.setHours(0, 0, 0, 0);
623										}
624
625										return parseInt(tmpDate.getTime() / 1000).toString();
626									}
627
628                                if (element.hasOwnProperty('rsfpGetValue'))
629                                {
630                                    return element.rsfpGetValue();
631                                }
632								
633								return element.value;
634								break;
635
636							case 'RADIO':
637								if (!element.name || (element.name !== 'form[' + name + ']' && element.name.substring(0, ('form[' + name + ']').length) !== 'form[' + name + ']')) continue;
638
639								if (element.checked) {
640									values.push(element.value);
641								}
642								break;
643
644							case 'CHECKBOX':
645								if (!element.name || element.name != 'form[' + name + '][]') continue;
646								if (element.checked == true) {
647									values.push(element.value);
648								}
649								break;
650						}
651					break;
652
653				case 'SELECT':
654					if (!element.name || element.name != 'form[' + name + '][]') continue;
655
656					if (element.options)
657						for (var o=0; o<element.options.length; o++)
658							if (element.options[o].selected)
659							{
660								values.push(element.options[o].value);
661							}
662					break;
663			}
664		}
665	}
666
667	return values;
668};
669
670RSFormPro.getElementByType = function(formId, type) {
671	var form	= RSFormPro.getForm(formId);
672	type = type.toUpperCase();
673	var elements	= [];
674
675	if (typeof form != 'undefined')
676	{
677		for (var i = 0; i < form.elements.length; i++)
678		{
679			var element = form.elements[i];
680			var tagName = element.tagName || element.nodeName;
681			switch (tagName)
682			{
683				case 'INPUT':
684				case 'BUTTON':
685					if (element.type.toUpperCase() == type) {
686						elements.push(element);
687					}
688					break;
689
690				case 'SELECT':
691				case 'TEXTAREA':
692					if (type == 'SELECT' || type == 'TEXTAREA') {
693						elements.push(element);
694					}
695					break;
696			}
697		}
698	}
699
700	return elements;
701};
702
703RSFormPro.resettingValues = false;
704
705RSFormPro.resetValues = function(items) {
706	if (RSFormPro.resettingValues)
707	{
708		return true;
709	}
710
711	var element, tagName;
712	try
713	{
714		for (var i = 0; i < items.length; i++)
715		{
716			element = items[i];
717			tagName = element.tagName || element.nodeName;
718
719			switch (tagName)
720			{
721				case 'INPUT':
722					if (element.type)
723					{
724						switch (element.type.toUpperCase())
725						{
726							case 'CHECKBOX':
727							case 'RADIO':
728								if (element.defaultChecked !== element.checked)
729								{
730									element.checked = element.defaultChecked;
731									RSFormPro.triggerEvent(element, 'change');
732								}
733							break;
734							
735							case 'NUMBER':
736							case 'TEXT':
737								if (element.defaultValue !== element.value)
738								{
739									element.value = element.defaultValue;
740
741									if (element.id)
742									{
743										// Range Slider
744										if (element.id.indexOf('rs-range-slider') === 0 && typeof jQuery !== 'undefined')
745										{
746											jQuery(element).data('ionRangeSlider').reset();
747										}
748
749										// Date and Time Picker
750										if (element.id.indexOf('txtjQcal') === 0 && typeof jQuery !== 'undefined' && typeof RSFormPro.jQueryCalendar !== 'undefined')
751										{
752											jQuery(element).datetimepicker('reset');
753										}
754
755										// Calendar
756										if (element.id.indexOf('txtcal') === 0 && typeof RSFormPro.YUICalendar !== 'undefined')
757										{
758											var match = element.id.match(/^txtcal([0-9]+)_[0-9]+$/);
759											if (match.length === 2)
760											{
761												var formId = match[1];
762												var calendarName = element.name.match(/^form\[(.*)\]$/)[1];
763
764												if (typeof RSFormPro.YUICalendar.calendars[formId][calendarName] !== 'undefined')
765												{
766													RSFormPro.YUICalendar.calendars[formId][calendarName].reset();
767												}
768											}
769										}
770									}
771
772									RSFormPro.triggerEvent(element, 'change');
773									RSFormPro.triggerEvent(element, 'input');
774								}
775							break;
776						}
777					}
778				break;
779				
780				case 'TEXTAREA':
781					if (element.defaultValue !== element.value)
782					{
783						element.value = element.defaultValue;
784
785						RSFormPro.triggerEvent(element, 'change');
786						RSFormPro.triggerEvent(element, 'input');
787					}
788				break;
789
790				case 'SELECT':
791					if (element.options)
792					{
793						var needsChange = false;
794						var unselected = [];
795						for (var o = 0; o < element.options.length; o++) {
796							if (element.options[o].defaultSelected !== element.options[o].selected)
797							{
798								needsChange = true;
799								element.options[o].selected = element.options[o].defaultSelected;
800							}
801
802							if (!element.options[o].defaultSelected) {
803								unselected.push(o);
804							}
805						}
806						
807						// in safari something must be selected
808						if (element.options.length === unselected.length) {
809							element.selectedIndex = 0;
810						}
811
812						if (needsChange)
813						{
814							RSFormPro.triggerEvent(element, 'change');
815						}
816					}
817				break;
818			}
819		}
820	}
821	catch (err) {}
822};
823
824RSFormPro.triggerEvent = function(element, type) {
825	try {
826		element.dispatchEvent(new Event(type));
827	} catch (e) {}
828};
829
830RSFormPro.isChecked = function(formId, name, value) {
831	var isChecked 	= false;
832	var form 		= RSFormPro.getForm(formId);
833
834	if (typeof form != 'undefined')
835	{
836		primary_loop:
837			for (var i=0; i<form.elements.length; i++)
838			{
839				var element = form.elements[i];
840				var tagName = element.tagName || element.nodeName;
841
842				switch (tagName)
843				{
844					case 'INPUT':
845						if (element.type)
846							switch (element.type.toUpperCase())
847							{
848								default:
849									if (!element.name || element.name != 'form[' + name + ']') continue;
850									if (!element.value) continue;
851
852									if (element.value == value)
853									{
854										isChecked = true;
855										break primary_loop;
856									}
857
858									break;
859								case 'RADIO':
860									if (!element.name || element.name != 'form[' + name + ']') continue;
861									if (element.checked == true && element.value == value)
862									{
863										isChecked = true;
864										break primary_loop;
865									}
866									break;
867
868								case 'CHECKBOX':
869									if (!element.name || element.name != 'form[' + name + '][]') continue;
870									if (element.checked == true && element.value == value)
871									{
872										isChecked = true;
873										break primary_loop;
874									}
875									break;
876							}
877						break;
878
879					case 'SELECT':
880						if (!element.name || element.name != 'form[' + name + '][]') continue;
881
882						if (element.options)
883							for (var o=0; o<element.options.length; o++)
884								if (element.options[o].selected && element.options[o].value == value)
885								{
886									isChecked = true;
887									break primary_loop;
888								}
889						break;
890				}
891			}
892	}
893
894	return isChecked;
895};
896
897RSFormPro.getBlock = function(formId, block) {
898	var form 	 = RSFormPro.getForm(formId);
899	var possible = false;
900	var blocks, current_block;
901
902	if (typeof form != 'undefined') {
903		if (blocks = getElementsByClassName('rsform-block')) {
904			for (i=0; i<blocks.length; i++) {
905				var classes = blocks[i].className.split(' ');
906				for (c=0; c<classes.length; c++) {
907					if (classes[c] == 'rsform-block-' + block) {
908						if (blocks[i].parentNode) {
909							current_block = blocks[i];
910							if (current_block == form)
911								return [ blocks[i] ];
912
913							while (current_block.parentNode) {
914								current_block = current_block.parentNode;
915								if (current_block == form)
916									return [ blocks[i] ];
917							}
918						}
919
920						possible = [ blocks[i] ];
921					}
922				}
923			}
924		}
925	}
926
927	return possible;
928};
929
930RSFormPro.getFieldsByName = function(formId, name) {
931	var form 	= RSFormPro.getForm(formId);
932	var results = [];
933	var pushed  = false;
934
935	if (typeof form != 'undefined') {
936		for (var i=0; i<form.elements.length; i++) {
937			var element = form.elements[i];
938			pushed = false;
939			if (element.name && (
940					// single fields
941					element.name == 'form[' + name + ']' ||
942					// multiple fields
943					element.name == 'form[' + name + '][]' ||
944					// new field - Birthday field
945					element.name == 'form[' + name + '][d]' ||
946					element.name == 'form[' + name + '][m]' ||
947					element.name == 'form[' + name + '][y]'
948				)) {
949				results.push(element);
950				pushed = true;
951			}
952
953			if (!pushed)
954			{
955				if (element.name && element.getAttribute('data-rsfpsurveytable-answer') && element.name.substring(0, ('form[' + name + ']').length) === 'form[' + name + ']')
956				{
957					results.push(element);
958				}
959			}
960
961			if (pushed) {
962				// for calendar
963				if (element.id && element.id.indexOf('txtcal') > -1) {
964					var suffix = element.id.replace('txtcal', '');
965					if (document.getElementById('btn' + suffix))
966					{
967						results.push(document.getElementById('btn' + suffix));
968					}
969				}
970				// for labels (radio, checkbox)
971				var labels = form.getElementsByTagName('label');
972				for (var l=0; l<labels.length; l++) {
973					if (labels[l].htmlFor && labels[l].htmlFor == element.id)
974						results.push(labels[l]);
975				}
976			}
977		}
978	}
979
980	return results;
981};
982
983RSFormPro.showCounter = function(element, id) {
984	var current = element.value.length;
985	var result;
986	if (element.maxLength > 0)
987	{
988		result = current + '/' + element.maxLength;
989	}
990	else
991	{
992		result = current;
993	}
994	
995	document.getElementById('rsfp-counter-' + id).innerText = result;
996};
997
998RSFormPro.limitSelections = function(formId, field, max) {
999    RSFormProUtils.addEvent(window, 'load', function() {
1000        var fields = RSFormPro.getFieldsByName(formId, field);
1001        var objects = [];
1002        var i;
1003        var tagName;
1004
1005        if (!fields || !fields.length) {
1006            return;
1007        }
1008
1009        for (i = 0; i < fields.length; i++) {
1010            tagName = fields[i].tagName || fields[i].nodeName;
1011            tagName = tagName.toUpperCase();
1012
1013            if (tagName === 'INPUT' && fields[i].type && fields[i].type.toUpperCase() === 'CHECKBOX' && !fields[i].disabled) {
1014                objects.push(fields[i]);
1015            }
1016        }
1017
1018        if (!objects.length) {
1019            return;
1020        }
1021
1022        function limitSelections() {
1023            var values = RSFormProUtils.getChecked(objects);
1024            RSFormProUtils.remAttr(objects, 'disabled');
1025            if (values && values.length > 0 && values.length >= max) {
1026                RSFormProUtils.setAttr(RSFormProUtils.getUnchecked(objects), 'disabled', true);
1027            }
1028		}
1029
1030        for (i = 0; i < objects.length; i++) {
1031            RSFormProUtils.addEvent(objects[i], 'change', limitSelections);
1032        }
1033
1034        limitSelections();
1035    });
1036};
1037
1038/*HTML5 simulators*/
1039
1040RSFormPro.HTML5 = {
1041	validation: function(formId){
1042		var form = RSFormPro.getForm(formId);
1043		var errorElements = [];
1044		var html5types = ['number', 'email', 'range', 'url', 'tel'];
1045		var multipleTypes = ['radio'];
1046
1047		var checkValidityExists = true;
1048		var checkValidityFunction;
1049		var needsCheck;
1050		var options;
1051		var page = 0;
1052		var componentId;
1053		var elementId;
1054		var match;
1055
1056		if (form.elements.length) {
1057			for (var i = 0; i < form.elements.length; i++) {
1058				if (!checkValidityExists) {
1059					break;
1060				}
1061
1062				needsCheck = false;
1063				checkValidityFunction = false;
1064
1065				// if the multiple form is present and also validation we will need to find in which page the element is located
1066				if (form.elements[i].type === 'button') {
1067					var onclick = form.elements[i].getAttribute('onclick');
1068					if (typeof onclick == 'string' && (onclick.indexOf('rsfp_changePage') > -1 || onclick.indexOf('RSFormPro.Pages.change') > -1)) {
1069						var countCommas = 0;
1070						var pos = onclick.indexOf(',');
1071						while (pos > -1) {
1072							++countCommas;
1073							pos = onclick.indexOf(',', ++pos);
1074						}
1075
1076						if (countCommas > 2) {
1077							page++;
1078						}
1079					}
1080				}
1081				if (form.elements[i].getAttribute('data-rsfp-phonenumber'))
1082				{
1083					options = JSON.parse(form.elements[i].getAttribute('data-rsfp-phonenumber'));
1084					needsCheck = form.elements[i].value.length > 0;
1085					if (options['validation'] === 'precise')
1086					{
1087						checkValidityFunction = function(el) { return intlTelInput.getInstance(el).isValidNumberPrecise(); }
1088					}
1089					else
1090					{
1091						checkValidityFunction = function(el) { return intlTelInput.getInstance(el).isValidNumber(); }
1092					}
1093				}
1094				else
1095				{
1096					needsCheck = html5types.indexOf(form.elements[i].type) > -1;
1097					if (typeof(form.elements[i].checkValidity) === 'function')
1098					{
1099						checkValidityFunction = function(el) { return el.checkValidity() };
1100					}
1101				}
1102				if (needsCheck) {
1103					if (typeof(checkValidityFunction) === 'function' && checkValidityExists) {
1104						if (!checkValidityFunction(form.elements[i])) {
1105							var elementObj = {
1106								field: form.elements[i],
1107								page: page
1108							};
1109							// try to get the componentId
1110							elementId = form.elements[i].getAttribute('id');
1111							if (multipleTypes.indexOf(form.elements[i].type) > -1)
1112							{
1113								if (match = form.elements[i].getAttribute('name').match(/form\[(.*)\]/))
1114								{
1115									elementId = match[1];
1116								}
1117							}
1118							componentId = RSFormPro.HTML5.getComponentId(formId, elementId);
1119
1120							if (componentId) {
1121								elementObj.componentId = componentId;
1122							}
1123
1124							errorElements.push(elementObj);
1125						}
1126					} else {
1127						checkValidityExists = false;
1128					}
1129				}
1130			}
1131		}
1132		return errorElements;
1133	},
1134
1135	componentIds: {},
1136
1137	getComponentId: function(formId, elementAlias) {
1138		if (typeof RSFormPro.HTML5.componentIds[formId] == 'undefined') {
1139			RSFormPro.HTML5.componentIds[formId] = {};
1140		}
1141
1142		if (typeof RSFormPro.HTML5.componentIds[formId][elementAlias] == 'undefined') {
1143			RSFormPro.HTML5.componentIds[formId][elementAlias] = false;
1144			var block = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(elementAlias));
1145
1146			if (typeof block[0] !== 'undefined') {
1147				var componentIdBlock;
1148
1149				componentIdBlock = RSFormProUtils.getElementsByClassName('formNoError', 'span', block[0]);
1150				if (componentIdBlock.length === 0) {
1151					componentIdBlock = RSFormProUtils.getElementsByClassName('formError', 'span', block[0]);
1152				}
1153
1154				if (componentIdBlock.length > 0) {
1155					var componentId = componentIdBlock[0].getAttribute('id');
1156					RSFormPro.HTML5.componentIds[formId][elementAlias] = componentId.replace('component', '');
1157				}
1158			}
1159		}
1160
1161		return RSFormPro.HTML5.componentIds[formId][elementAlias];
1162	}
1163};
1164
1165/* Pagination functions */
1166
1167RSFormPro.Pages = {
1168	change: function(formId, page, totalPages, validate, errorClasses) {
1169		// callback functions if next page is clicked
1170		var direction = RSFormPro.Pages.checkDirection(formId, page);
1171		if (direction == 'next') {
1172			RSFormPro.callbacks.runCallback(formId, 'nextPage');
1173		}
1174		RSFormPro.callbacks.runCallback(formId, 'changePage');
1175		
1176		var thePage;
1177
1178		if (validate) {
1179			var form = RSFormPro.getForm(formId);
1180			if (!RSFormPro.Ajax.validate(form, page, errorClasses, totalPages)) {
1181				return false;
1182			}
1183		}
1184
1185		for (var i = 0; i <= totalPages; i++) {
1186			thePage = document.getElementById('rsform_' + formId + '_page_' + i);
1187			if (thePage) {
1188				RSFormPro.Pages.hide(thePage);
1189			}
1190		}
1191
1192		thePage = document.getElementById('rsform_' + formId + '_page_' + page);
1193		if (thePage) {
1194			RSFormPro.Pages.show(thePage);
1195			try {
1196				var func = window["rsfp_showProgress_" + formId];
1197				if (typeof func == "function") {
1198					func(page);
1199				}
1200			}
1201			catch (err) {}
1202		}
1203	},
1204	hide: function(thePage) {
1205		RSFormProUtils.addClass(thePage, 'formHidden');
1206	},
1207	show: function(thePage) {
1208		RSFormProUtils.removeClass(thePage, 'formHidden');
1209	},
1210	
1211	checkDirection : function(formId, page) {
1212		var base = RSFormPro.Pages;
1213		if (typeof base.history[formId] == 'undefined') {
1214			base.history[formId] = page;
1215			return 'next';
1216		} else {
1217			var direction;
1218			if (base.history[formId] <= page ) { 
1219				direction = 'next';
1220			} else {
1221				direction = 'prev';
1222			}
1223			base.history[formId] = page;
1224			
1225			return direction;
1226		}
1227	},	
1228	history: {}
1229};
1230
1231/* Condition functions */
1232RSFormPro.Conditions = {
1233	add: function(formId, name, fnCondition) {
1234		var form = RSFormPro.getForm(formId);
1235
1236		if (typeof form != 'undefined') {
1237			for (var i = 0; i < form.elements.length; i++) {
1238				var element = form.elements[i];
1239				if (element.name && (element.name == 'form[' + name + ']' || element.name == 'form[' + name + '][]')) {
1240					RSFormProUtils.addEvent(element, 'change', function() {
1241						fnCondition();
1242					});
1243				}
1244			}
1245		}
1246	},
1247	run: function(condition) {
1248		var formId = condition.form_id,
1249            conditions = [],
1250            items = [],
1251			detail, isChecked, displayValue, match;
1252
1253		var i, c;
1254
1255		if (typeof condition.details === 'object')
1256		{
1257			for (i = 0; i < condition.details.length; i++)
1258			{
1259				detail = condition.details[i];
1260                isChecked = RSFormPro.isChecked(formId, detail.ComponentName, detail.value);
1261                conditions.push(isChecked === (detail.operator === 'is'));
1262			}
1263
1264			items = [];
1265
1266			if (condition.ComponentNames)
1267			{
1268				for (c = 0; c < condition.ComponentNames.length; c++)
1269				{
1270					if (parseInt(condition.block) === 1)
1271					{
1272						items = items.concat(RSFormPro.getBlock(formId, RSFormProUtils.getAlias(condition.ComponentNames[c])));
1273					}
1274					else
1275					{
1276						items = items.concat(RSFormPro.getFieldsByName(formId, condition.ComponentNames[c]));
1277					}
1278				}
1279			}
1280
1281			if (items.length > 0)
1282			{
1283				if (condition.condition === 'all')
1284				{
1285                    // && conditions need all elements of the Array to be true -> no false in Array
1286                    match = conditions.indexOf(false) === -1;
1287				}
1288				else
1289				{
1290                    // || conditions need only one element to be true -> one true in array
1291					match = conditions.indexOf(true) > -1;
1292				}
1293
1294                if (match)
1295                {
1296                    displayValue = condition.action === 'show' ? '' : 'none';
1297                }
1298                else
1299                {
1300                    displayValue = condition.action === 'show' ? 'none' : '';
1301                }
1302
1303				RSFormProUtils.setDisplay(items, displayValue);
1304                if (displayValue === 'none')
1305				{
1306					if (condition.ComponentNames && condition.ComponentNames.length > 0)
1307					{
1308						for (c = 0; c < condition.ComponentNames.length; c++)
1309						{
1310							RSFormPro.resetValues(RSFormPro.getFieldsByName(formId, condition.ComponentNames[c]));
1311						}
1312					}
1313				}
1314			}
1315		}
1316	},
1317	runAll: function(formId) {
1318		var func = window['rsfp_runAllConditions' + formId];
1319		if (typeof func === 'function') {
1320			func();
1321		}
1322	},
1323	addReset: function(formId) {
1324		var resetElements = RSFormPro.getElementByType(formId, 'reset');
1325		if (resetElements.length > 0)
1326		{
1327			for (var i = 0; i < resetElements.length; i++)
1328			{
1329				RSFormProUtils.addEvent(resetElements[i], 'click', function() {
1330					window.setTimeout(function() {
1331						RSFormPro.Conditions.runAll(formId);
1332					}, 1);
1333				});
1334			}
1335		}
1336	},
1337	delayRun: function(formId) {
1338		var func = window['rsfp_runAllConditions' + formId];
1339		if (typeof func === 'function') {
1340			RSFormProUtils.addEvent(window, 'load', func);
1341		}
1342	}
1343};
1344
1345/* Calculation functions */
1346
1347RSFormPro.Calculations = {
1348	toDays: function(seconds) {
1349		return Math.round(parseFloat(seconds) / 86400);
1350	},
1351	toHours: function(seconds) {
1352		return Math.round(parseFloat(seconds) / 86400 * 24);
1353	},
1354	toMinutes: function(seconds) {
1355        return Math.round(parseFloat(seconds) / 86400 * 24 * 60);
1356    },
1357	addEvents: function(formId, fields) {
1358		RSFormProUtils.addEvent(window, 'load', function(){
1359			RSFormPro.Calculations._addEvents(formId, fields);
1360		});
1361	},
1362	_addEvents: function(formId, fields) {
1363		var func 		= window['rsfp_Calculations' + formId];
1364		var thefields	= fields ? fields : RSFormProPrices;
1365		var event 		= 'change';
1366		var objects, tagName;
1367		
1368		var resetElements = RSFormPro.getElementByType(formId, 'reset');
1369		if (resetElements.length > 0)
1370		{
1371			for (var i = 0; i < resetElements.length; i++)
1372			{
1373				RSFormProUtils.addEvent(resetElements[i], 'click', function() {
1374					if (typeof func === 'function') {
1375						window.setTimeout(func, 1);
1376					}
1377				});
1378			}
1379		}
1380
1381		for (var field in thefields) {
1382			if (!thefields.hasOwnProperty(field)) {
1383				continue;
1384			}
1385			field = field.replace(formId+'_','');
1386			objects = RSFormPro.getFieldsByName(formId,field);
1387			for(i = 0; i < objects.length;i++) {
1388				tagName = objects[i].tagName || objects[i].nodeName;
1389
1390				if (tagName === 'INPUT' || tagName === 'SELECT') {
1391					event = 'change';
1392					if (tagName === 'INPUT' && typeof objects[i].type == 'string') {
1393						switch (objects[i].type.toUpperCase())
1394						{
1395							default:
1396								event = 'change';
1397							break;
1398							
1399							case 'NUMBER':
1400							case 'TEXT':
1401								event = 'input';
1402								
1403								if (typeof RSFormPro.jQueryCalendar !== 'undefined' &&
1404									typeof RSFormPro.jQueryCalendar.calendars[formId] !== 'undefined' &&
1405									typeof RSFormPro.jQueryCalendar.calendars[formId][field] !== 'undefined')
1406									{
1407										RSFormPro.jQueryCalendar.calendars[formId][field].calendarInstance.setOptions({onChangeDateTime: function() {
1408											if (typeof func === 'function') {
1409												func();
1410											}
1411										}});
1412									}
1413								
1414								if (typeof RSFormPro.YUICalendar !== 'undefined' &&
1415									typeof RSFormPro.YUICalendar.calendars[formId] !== 'undefined' &&
1416									typeof RSFormPro.YUICalendar.calendars[formId][field] !== 'undefined')
1417									{
1418										RSFormPro.YUICalendar.calendars[formId][field].selectEvent.subscribe(function() {
1419											if (typeof func === 'function') {
1420												func();
1421											}
1422										}, RSFormPro.YUICalendar.calendars[formId][field], true);
1423									}
1424
1425								if (objects[i].hasOwnProperty('rsfpOnChange'))
1426								{
1427									objects[i].rsfpOnChange(func);
1428								}
1429							break;
1430						}
1431					}
1432
1433					RSFormProUtils.addEvent(objects[i], event, function() {
1434						if (typeof func === 'function') {
1435							func();
1436						}
1437					});
1438				}
1439			}
1440		}
1441	}
1442};
1443
1444/* AJAX functions */
1445RSFormPro.Ajax = {
1446	Wait: false,
1447	URL: false,
1448	Params: {},
1449	getParamsObject: function() {
1450		return {
1451			vars: [],
1452			push: function(str) {
1453				return this.vars.push(str);
1454			},
1455			
1456			indexOf: function(str) {
1457				return this.vars.join('&').indexOf(str);
1458			},
1459			
1460			replace: function(r, w) {
1461				this.vars = this.vars.join('&').replace(r, w).split('&');
1462				
1463				return this.vars.join('&');
1464			},
1465			
1466			toString: function() {
1467				return this.vars.join('&');
1468			}
1469		};
1470	},
1471	getXHR: function() {
1472		try {
1473			return new window.XMLHttpRequest();
1474		} catch ( e ) {}
1475	},
1476	getXHRLegacy: function() {
1477		return {
1478			send: function(data)
1479			{
1480				if (data === RSFormPro.Ajax.Params)
1481				{
1482					data = data.toString();
1483				}
1484				
1485				return RSFormPro.Ajax.xhr.send(data);
1486			}
1487		}
1488	},
1489	displayValidationErrors: function(formComponents, task, formId, data) {
1490		if (task == 'afterSend') {
1491			var ids, i, j, id, formComponent, elementBlock;
1492			var parentErrorClass = typeof data.parentErrorClass !== 'undefined' && data.parentErrorClass.length > 0 ? data.parentErrorClass : false;
1493			var fieldErrorClass = typeof data.fieldErrorClass !== 'undefined' && data.fieldErrorClass.length > 0 ? data.fieldErrorClass : false;
1494
1495			ids = data.response[0].split(',');
1496			for (i = 0; i < ids.length; i++)
1497			{
1498				id = parseInt(ids[i]);
1499
1500				if (isNaN(id))
1501				{
1502					continue;
1503				}
1504
1505				if (typeof formComponents[id] === 'undefined')
1506				{
1507					continue;
1508				}
1509
1510				formComponent = RSFormPro.getFieldsByName(formId, formComponents[id]);
1511
1512				if (!formComponent || formComponent.length < 1)
1513				{
1514					continue;
1515				}
1516
1517				for (j = 0; j < formComponent.length; j++)
1518				{
1519					if (formComponent[j])
1520					{
1521						RSFormProUtils.removeClass(formComponent[j], 'rsform-error');
1522						formComponent[j].removeAttribute('aria-invalid');
1523						if (formComponent[j].getAttribute('aria-describedby') === 'component' + id) {
1524							formComponent[j].removeAttribute('aria-describedby');
1525						}
1526
1527						if (parentErrorClass)
1528						{
1529							try
1530							{
1531								if (elementBlock = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(formComponents[id])))
1532								{
1533									RSFormProUtils.removeClass(elementBlock[0], parentErrorClass);
1534								}
1535							}
1536							catch (err) {}
1537						}
1538
1539						if (fieldErrorClass)
1540						{
1541							RSFormProUtils.removeClass(formComponent[j], fieldErrorClass);
1542						}
1543					}
1544				}
1545			}
1546
1547			ids = data.response[1].split(',');
1548			var doScroll = false;
1549			var doFocus = false;
1550			for (i = 0; i < ids.length; i++)
1551			{
1552				id = parseInt(ids[i]);
1553				
1554				if (isNaN(id))
1555				{
1556					continue;
1557				}
1558				
1559				if (typeof formComponents[id] === 'undefined')
1560				{
1561					continue;
1562				}
1563				
1564				formComponent = RSFormPro.getFieldsByName(formId, formComponents[id]);
1565
1566				if (!formComponent || formComponent.length < 1)
1567				{
1568					continue;
1569				}
1570				
1571				for (j = 0; j < formComponent.length; j++)
1572				{
1573					if (formComponent[j])
1574					{
1575						RSFormProUtils.addClass(formComponent[j], 'rsform-error');
1576
1577						if (!doScroll)
1578						{
1579							doScroll = true;
1580						}
1581						
1582						if (parentErrorClass)
1583						{
1584							try
1585							{
1586								if (elementBlock = RSFormPro.getBlock(formId, RSFormProUtils.getAlias(formComponents[id])))
1587								{
1588									RSFormProUtils.addClass(elementBlock[0], parentErrorClass);
1589								}
1590							}
1591							catch (err) {}
1592						}
1593
1594						if (fieldErrorClass)
1595						{
1596							RSFormProUtils.addClass(formComponent[j], fieldErrorClass);
1597						}
1598
1599						if (['INPUT', 'SELECT', 'TEXTAREA'].indexOf(formComponent[j].nodeName) > -1)
1600						{
1601							if (formComponent[j].getAttribute('type') !== 'button') {
1602								formComponent[j].setAttribute('aria-invalid', 'true');
1603								formComponent[j].setAttribute('aria-describedby', 'component' + id);
1604
1605								if (!doFocus && typeof formComponent[j].focus === 'function') {
1606									formComponent[j].focus();
1607									doFocus = true;
1608								}
1609							}
1610						}
1611					}
1612				}
1613			}
1614			
1615			// scroll to first error elment
1616			if (RSFormPro.scrollToError && doScroll){
1617				RSFormPro.gotoErrorElement(formId);
1618			}
1619		}
1620	},
1621	validate: function(form, page, errorClasses, totalPages) {
1622		try {
1623			var el = form.elements.length;
1624		} catch (err) {
1625			form = this;
1626		}
1627
1628		RSFormPro.Ajax.xhr = RSFormPro.Ajax.getXHR();
1629		RSFormPro.Ajax.xmlHttp = RSFormPro.Ajax.getXHRLegacy();
1630		var url = 'index.php?option=com_rsform&task=ajaxValidate';
1631		if (typeof RSFormPro.Ajax.URL == 'string') {
1632			url = RSFormPro.Ajax.URL;
1633		}
1634		
1635		RSFormPro.Ajax.Params = RSFormPro.Ajax.getParamsObject();
1636
1637		var submits = [],
1638			errorFields = [],
1639			success = false,
1640			formId = form.elements['form[formId]'].value,
1641			totalJSDetectedPages = 0,
1642			i,
1643			j;
1644
1645		// File uploads AJAX validation variabiles
1646		var ajaxSkippedFileUploads = [],
1647			filesLength = 0,
1648			filesCollection = [],
1649			identicalFiles = [];
1650		
1651		if (typeof errorClasses != 'object')
1652		{
1653			errorClasses = {'parent': '', 'field': ''}
1654		}
1655
1656		for (i=0; i<form.elements.length; i++)
1657		{
1658			// try and detect total pages of the form
1659			if (form.elements[i].type == 'button') {
1660				var onclick = form.elements[i].getAttribute('onclick');
1661				if (typeof onclick === 'string' && (onclick.indexOf('rsfp_changePage') > -1 || onclick.indexOf('RSFormPro.Pages.change') > -1)) {
1662					var countCommas = 0;
1663					var pos = onclick.indexOf(',');
1664					while (pos > -1) {
1665						++countCommas;
1666						pos = onclick.indexOf(',', ++pos);
1667					}
1668
1669					if (countCommas > 2) {
1670						totalJSDetectedPages++;
1671					}
1672				}
1673			}
1674
1675			// don't send an empty value
1676			if (!form.elements[i].name) continue;
1677			if (form.elements[i].name.length == 0) continue;
1678			// check if the checkbox is checked
1679			if (form.elements[i].type == 'checkbox' && form.elements[i].checked == false) continue;
1680			// check if the radio is selected
1681			if (form.elements[i].type == 'radio' && form.elements[i].checked == false) continue;
1682
1683			if (form.elements[i].type == 'submit' && form.elements[i].getAttribute('data-disableonsubmit') == '1') {
1684				submits.push(form.elements[i]);
1685				form.elements[i].disabled = true;
1686			}
1687
1688			// check if form is a dropdown with multiple selections
1689			if (form.elements[i].type == 'select-multiple')
1690			{
1691				for (j = 0; j < form.elements[i].options.length; j++) {
1692					if (form.elements[i].options[j].selected) {
1693						RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].options[j].value));
1694					}
1695				}
1696
1697				continue;
1698			}
1699
1700			if (form.elements[i].type == 'file')
1701			{
1702				if ('files' in form.elements[i])
1703				{
1704					try
1705					{
1706						if (RSFormPro.usePositioning)
1707						{
1708							if (form.elements[i].offsetParent !== document.getElementsByTagName('body')[0])
1709							{
1710								throw 'CONDITIONAL_HIDDEN';
1711							}
1712						}
1713						else
1714						{
1715							if (form.elements[i].offsetParent === null)
1716							{
1717								throw 'CONDITIONAL_HIDDEN';
1718							}
1719						}
1720
1721						if (form.elements[i].getAttribute('data-rsfp-skip-ajax') === 'true')
1722						{
1723							// Not already processed
1724							if (ajaxSkippedFileUploads.indexOf(form.elements[i].name) === -1)
1725							{
1726								// All fields are identical, make sure this code is only run once.
1727								ajaxSkippedFileUploads.push(form.elements[i].name);
1728
1729								// Get all identical fields
1730								identicalFiles = form.elements[form.elements[i].name];
1731
1732								filesLength = 0;
1733								filesCollection = [];
1734
1735								if (typeof identicalFiles === 'object')
1736								{
1737									// NodeList (multiple inputs)
1738									if (typeof identicalFiles.length !== 'undefined' && identicalFiles.length > 0)
1739									{
1740										for (var tmp = 0; tmp < identicalFiles.length; tmp++)
1741										{
1742											if (identicalFiles[tmp].files.length > 0)
1743											{
1744												filesLength += identicalFiles[tmp].files.length;
1745												filesCollection = filesCollection.concat(identicalFiles[tmp].files[0]);
1746											}
1747										}
1748									}
1749									else if (typeof identicalFiles.files !== 'undefined')
1750									{
1751										// Just one input
1752										filesLength += identicalFiles.files.length;
1753										filesCollection = filesCollection.concat(identicalFiles.files[0]);
1754									}
1755								}
1756							}
1757							else
1758							{
1759								throw 'AJAX_SKIPPED_FILE_UPLOAD';
1760							}
1761						}
1762						else
1763						{
1764							filesLength = form.elements[i].files.length;
1765							filesCollection = form.elements[i].files;
1766						}
1767
1768						if (filesLength === 0 && form.elements[i].getAttribute('data-rsfp-required') === 'true')
1769						{
1770							throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormPro.Translations.translate(formId, form.elements[i].getAttribute('id'), 'VALIDATIONMESSAGE'));
1771						}
1772
1773						if (form.elements[i].getAttribute('data-rsfp-required') === 'true' || filesLength > 0)
1774						{
1775							if (form.elements[i].getAttribute('data-rsfp-minfiles'))
1776							{
1777								var minFiles = parseInt(form.elements[i].getAttribute('data-rsfp-minfiles'));
1778
1779								if (filesLength < minFiles)
1780								{
1781									throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_MIN
1781FILES_REQUIRED'), minFiles));
1782								}
1783							}
1784
1785							if (form.elements[i].getAttribute('data-rsfp-maxfiles'))
1786							{
1787								var maxFiles = parseInt(form.elements[i].getAttribute('data-rsfp-maxfiles'));
1788
1789								if (filesLength > maxFiles)
1790								{
1791									throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_MAXFILES_REQUIRED'), maxFiles));
1792								}
1793							}
1794						}
1795
1796						for (var f = 0; f < filesLength; f++)
1797						{
1798							var file = filesCollection[f];
1799							var maxSize = parseInt(form.elements[i].getAttribute('data-rsfp-size'));
1800							if ('size' in file && maxSize > 0)
1801							{
1802								if (file.size > maxSize)
1803								{
1804									throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_FILE_EXCEEDS_LIMIT'), file.name, maxSize / 1024));
1805								}
1806							}
1807							if ('name' in file)
1808							{
1809								var exts = form.elements[i].getAttribute('data-rsfp-exts');
1810								if (exts)
1811								{
1812									exts = JSON.parse(exts);
1813
1814									var ext = file.name.slice((file.name.lastIndexOf(".") - 1 >>> 0) + 2);
1815									if (exts.indexOf(ext.toLowerCase()) === -1)
1816									{
1817										throw new RSFormPro.validationError('VALIDATION_ERROR', RSFormProUtils.sprintf(RSFormPro.Translations.commonTranslate('COM_RSFORM_FILE_EXTENSION_NOT_ALLOWED'), file.name));
1818									}
1819								}
1820							}
1821						}
1822					}
1823					catch (error)
1824					{
1825						if (typeof error === 'object')
1826						{
1827							if (error.toString() === 'VALIDATION_ERROR')
1828							{
1829								var parents = RSFormProUtils.getParents(form.elements[i]),
1830									page_number,
1831									parent;
1832								if (parents.length > 0)
1833								{
1834									for (var p = 0; p < parents.length; p++)
1835									{
1836										parent = parents[p];
1837
1838										if ('getAttribute' in parent)
1839										{
1840											var hasId = parents[p].getAttribute('id');
1841											var pageId = 'rsform_' + formId + '_page_';
1842											if (hasId && hasId.indexOf(pageId) === 0)
1843											{
1844												page_number = hasId.slice(pageId.length);
1845												break;
1846											}
1847										}
1848									}
1849								}
1850
1851								var elementObj = {
1852									field: form.elements[i],
1853									page: page_number
1854								};
1855
1856								// try to get the componentId
1857								var componentId = RSFormPro.HTML5.getComponentId(formId, form.elements[i].getAttribute('id'));
1858								if (componentId)
1859								{
1860									elementObj.componentId = componentId;
1861
1862									if (document.getElementById('component' + componentId) && error.message.length > 0)
1863									{
1864										document.getElementById('component' + componentId).innerText = error.message;
1865									}
1866								}
1867
1868								errorFields.push(elementObj);
1869							}
1870						}
1871					}
1872				}
1873			}
1874
1875			if (form.elements[i].type !== 'file')
1876			{
1877				if (typeof RSFormPro.Editors[form.elements[i].name] === 'function' && RSFormPro.Editors[form.elements[i].name]() !== null)
1878				{
1879					RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(RSFormPro.Editors[form.elements[i].name]()));
1880				}
1881				else
1882				{
1883					RSFormPro.Ajax.Params.push(form.elements[i].name + '=' + encodeURIComponent(form.elements[i].value));
1884				}
1885			}
1886		}
1887
1888		errorFields = errorFields.concat(RSFormPro.HTML5.validation(formId));
1889
1890		if (page) {
1891			RSFormPro.Ajax.Params.push('page=' + page);
1892		}
1893
1894		RSFormPro.Ajax.xhr.open("POST", url, true);
1895
1896		//Send the proper header information along with the request
1897		RSFormPro.Ajax.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
1898		
1899		if (typeof ajaxExtraValidationScript[formId] == 'function') {
1900			ajaxExtraValidationScript[formId]('beforeSend', formId, {'url': url, 'params': RSFormPro.Ajax.Params});
1901		}
1902
1903		if (!RSFormPro.Ajax.Wait)
1904		{
1905			// B/C layer
1906			RSFormPro.Ajax.xmlHttp.send(RSFormPro.Ajax.Params);
1907		}
1908		success = true;
1909		
1910		RSFormPro.Ajax.xhr.onreadystatechange = function() {
1911			if (RSFormPro.Ajax.xhr.readyState === 4 && RSFormPro.Ajax.xhr.status === 200) {
1912				try
1913				{
1914					var RSFormProResponse = JSON.parse(RSFormPro.Ajax.xhr.responseText);
1915				}
1916				catch (error)
1917				{
1918					// Parse invalid data
1919					if (typeof RSFormProResponse !== 'object')
1920					{
1921						var match = RSFormPro.Ajax.xhr.responseText.match(/{.*}/);
1922
1923						if (match.length > 0)
1924						{
1925							RSFormProResponse = JSON.parse(match[0]);
1926						}
1927					}
1928				}
1929
1930				var response = [];
1931				var ids;
1932				var i;
1933
1934				if (typeof RSFormProResponse.formComponents !== 'undefined')
1935				{
1936					// All spans set to no error
1937					ids = RSFormProResponse.formComponents;
1938
1939					for (i = 0; i < ids.length; i++)
1940					{
1941						if (!isNaN(parseInt(ids[i])) && document.getElementById('component'+ids[i]))
1942						{
1943							document.getElementById('component'+ids[i]).className = 'formNoError';
1944						}
1945					}
1946
1947					// Legacy
1948					response.push(RSFormProResponse.formComponents.join(','));
1949				}
1950
1951				if (typeof RSFormProResponse.invalidComponents === 'undefined')
1952				{
1953					RSFormProResponse.invalidComponents = [];
1954				}
1955
1956				// add the HTML5 elements with errors
1957				var errorOnPage;
1958				if (errorFields.length)
1959				{
1960					for (i = 0; i < errorFields.length; i++)
1961					{
1962						if (typeof errorFields[i].componentId !== 'undefined')
1963						{
1964							if (typeof page === 'undefined' || (page - 1) == errorFields[i].page)
1965							{
1966								RSFormProResponse.invalidComponents.push(errorFields[i].componentId);
1967								if (typeof errorOnPage !== 'undefined')
1968								{
1969									errorOnPage = errorFields[i].page < errorOnPage ? errorFields[i].page : errorOnPage;
1970								}
1971								else 
1972								{
1973									errorOnPage = errorFields[i].page;
1974								}
1975							}
1976						}
1977					}
1978				}
1979
1980				// Show errors
1981				var errorComponents = [];
1982
1983				var errorMessageContainer;
1984
1985				for (i = 0; i < RSFormProResponse.invalidComponents.length; i++)
1986				{
1987					if (!isNaN(parseInt(RSFormProResponse.invalidComponents[i])))
1988					{
1989						errorMessageContainer = document.getElementById('component' + RSFormProResponse.invalidComponents[i]);
1990
1991						if (errorMessageContainer)
1992						{
1993							errorMessageContainer.className = 'formError';
1994
1995							if (RSFormProResponse.validationMessages && typeof RSFormProResponse.validationMessages[RSFormProResponse.invalidComponents[i]] !== 'undefined')
1996							{
1997								errorMessageContainer.innerHTML = RSFormProResponse.validationMessages[RSFormProResponse.invalidComponents[i]];
1998							}
1999						}
2000
2001						errorComponents.push(RSFormProResponse.invalidComponents[i]);
2002						success = false;
2003					}
2004				}
2005
2006				// lets detect if the multiple page form is submitted
2007				var changePageHTML5Errors = false;
2008				if (totalJSDetectedPages > 0 && RSClickedSubmitElement && submits.indexOf(RSClickedSubmitElement) >= 0 && typeof errorOnPage !== 'undefined') {
2009					changePageHTML5Errors = true;
2010				}
2011
2012				// Legacy
2013				response.push(RSFormProResponse.invalidComponents.join(','));
2014
2015				if (typeof RSFormProResponse.allPages !== 'undefined' || changePageHTML5Errors)
2016				{
2017					// Legacy
2018					response.push(RSFormProResponse.currentPage);
2019					response.push(RSFormProResponse.allPages);
2020
2021					if (typeof RSFormProResponse.allPages !== 'undefined')
2022					{
2023						page = parseInt(RSFormProResponse.currentPage) - 1;
2024						totalPages = parseInt(RSFormProResponse.allPages);
2025						if (changePageHTML5Errors)
2026						{
2027							page = page > errorOnPage ? errorOnPage : page;
2028						}
2029					}
2030					else
2031					{
2032						if (changePageHTML5Errors)
2033						{
2034							page = errorOnPage;
2035							totalPages = totalJSDetectedPages;
2036						}
2037					}
2038
2039					RSFormPro.Pages.change(formId, page, totalPages, false);
2040				}
2041
2042				if (typeof ajaxExtraValidationScript[formId] === 'function')
2043				{
2044					// rewrite the response so that all the error components are added (that includes HTML5 fields)
2045					if (errorComponents.length)
2046					{
2047						response[1] = errorComponents.join();
2048					}
2049
2050					ajaxExtraValidationScript[formId]('afterSend', formId, {'url': url, 'params': RSFormPro.Ajax.Params, 'response': response, 'parentErrorClass': errorClasses.parent, 'fieldErrorClass': errorClasses.field, 'json': RSFormProResponse});
2051				}
2052				
2053				if (success === false)
2054				{
2055					// The submits must be clickable again
2056					for (i = 0; i < submits.length; i++)
2057					{
2058						submits[i].disabled = false;
2059					}
2060
2061					try
2062					{
2063						if (typeof page === 'undefined' || page == 0)
2064						{
2065							RSFormPro.callbacks.runCallback(formId, 'afterValidationFailed'); // callback functions if validation fails when form is submitted
2066						}
2067						else
2068						{
2069							RSFormPro.callbacks.runCallback(formId, 'nextPageFailed'); // callback functions if validation fails when a specific page of the form is checked
2070						}
2071
2072						if (document.getElementById('rsform_error_' + formId))
2073						{
2074							document.getElementById('rsform_error_' + formId).style.display = 'block';
2075						}
2076					}
2077					catch (err) { }
2078				}
2079				else
2080				{
2081					// Change the page if the validation passes
2082					if (page)
2083					{
2084						RSFormPro.Pages.change(formId, page, totalPages, false);
2085						// The submits must be clickable again
2086						for (i = 0; i < submits.length; i++)
2087						{
2088							submits[i].disabled = false;
2089						}
2090					}
2091					else
2092					{
2093						// the submit button has been pressed so we need to submit the form
2094						// if the submit button or any other element has the id submit the form.submit() function is overwritten
2095						RSFormPro.submitForm(form);
2096					}
2097
2098					try
2099					{
2100						if (typeof page === 'undefined' || page == 0)
2101						{
2102							RSFormPro.callbacks.runCallback(formId, 'afterValidationSuccess'); // callback functions if validation succeeds
2103						}
2104						else
2105						{
2106							RSFormPro.callbacks.runCallback(formId, 'nextPageSuccess'); // callback functions if validation succeeds when a specific page of the form is checked
2107						}
2108
2109						if (document.getElementById('rsform_error_' + formId))
2110						{
2111							document.getElementById('rsform_error_' + formId).style.display = 'none';
2112						}
2113					}
2114					catch (err) { }
2115				}
2116
2117				return success;
2118			}
2119		};
2120
2121		return false;
2122	},
2123	overrideSubmit: function(formId, validationParams, disableSubmitButton) {
2124        var form = RSFormPro.getForm(formId);
2125        var submitElement = RSFormPro.getElementByType(formId, 'submit');
2126		var i, j;
2127        for (i = 0; i < submitElement.length; i++) {
2128			if (RSFormProUtils.hasClass(submitElement[i],'rsform-submit-button')) {
2129				RSFormProUtils.addEvent(submitElement[i],'click', (function(event) {
2130					event.preventDefault();
2131					RSClickedSubmitElement = this;
2132					if (disableSubmitButton) {
2133						for (j = 0; j < submitElement.length; j++) {
2134							submitElement[j].setAttribute('data-disableonsubmit','1');
2135						}
2136					}
2137
2138					RSFormPro.Ajax.validate(form, undefined, validationParams);
2139				}));
2140			}
2141		}
2142	}
2143};
2144
2145RSFormPro.validationError = function(type, message) {
2146	this.type = type;
2147	this.message = message;
2148};
2149
2150RSFormPro.validationError.prototype.toString = function() {
2151	return this.type;
2152};
2153
2154RSFormPro.callbacks = {
2155	allCallbacks: {},
2156	
2157	addCallback: function(formId, callbackName, args) {
2158		var base = RSFormPro.callbacks;
2159		
2160		if (typeof base.allCallbacks[formId] == 'undefined') {
2161			base.allCallbacks[formId] = {}
2162		}
2163		
2164		if (typeof base.allCallbacks[formId][callbackName] == 'undefined') {
2165			base.allCallbacks[formId][callbackName] = [];
2166		}
2167		
2168		base.allCallbacks[formId][callbackName].push(args);
2169	},
2170	
2171	runCallback: function(formId, callbackName) {
2172		var base = RSFormPro.callbacks;
2173		if (typeof base.allCallbacks[formId] != 'undefined' && typeof base.allCallbacks[formId][callbackName] != 'undefined' && base.allCallbacks[formId][callbackName].length > 0) {
2174			for (var i = 0; i < base.allCallbacks[formId][callbackName].length; i++) {
2175				var args = base.allCallbacks[formId][callbackName][i];
2176				var functionName = args[0];
2177				
2178				var functionArgs =  [];
2179				for (var j = 1; j < args.length; j++) {
2180					functionArgs.push(args[j]);
2181				}
2182				
2183				// execute the callback function set for this trigger
2184				functionName.apply(self, functionArgs);
2185			}
2186		}
2187	}
2188};
2189
2190/* Translations */
2191
2192RSFormPro.Translations = {
2193	translations: {},
2194	commonTranslations: {},
2195
2196	add: function(formId, name, key, translation) {
2197		if (typeof this.translations[formId + '-' + name] !== 'object')
2198		{
2199			this.translations[formId + '-' + name] = {};
2200		}
2201
2202		this.translations[formId + '-' + name][key] = translation;
2203	},
2204
2205	translate: function(formId, name, key) {
2206		if (typeof this.translations[formId + '-' + name][key] == 'string')
2207		{
2208			return this.translations[formId + '-' + name][key];
2209		}
2210
2211		return key;
2212	},
2213
2214	addCommonTranslation: function(key, translation) {
2215		this.commonTranslations[key] = translation;
2216	},
2217
2218	addCommonTranslations: function(translations) {
2219		var self = this;
2220		translations.forEach(function(el){
2221			self.commonTranslations[el[0]] = el[1];
2222		})
2223	},
2224
2225	commonTranslate: function(key) {
2226		if (typeof this.commonTranslations[key] == 'string')
2227		{
2228			return this.commonTranslations[key];
2229		}
2230
2231		return key;
2232	}
2233};
2234
2235RSFormPro.previewFields = {
2236	'elements': [],
2237	'delimiter': ', ',
2238	escapeValue: function(str) {
2239		var textAreaDiv = document.createElement('textarea');
2240		textAreaDiv.textContent = str;
2241		return textAreaDiv.innerHTML;
2242	},
2243	attachEvents: function() {
2244		if (RSFormPro.previewFields.elements.length > 0) {
2245			var element, results, i, j, tagName;
2246			var form;
2247			for (i = 0; i < RSFormPro.previewFields.elements.length; i++) {
2248				element = RSFormPro.previewFields.elements[i];
2249				results = RSFormPro.getFieldsByName(element.formId, element.fieldName);
2250				form = RSFormPro.getForm(element.formId)
2251
2252				if (results.length > 0) {
2253					for (j = 0; j < results.length; j++) {
2254						(function(element, field, formId, form){
2255							var funcValue = function () {
2256								if (document.getElementById('preview-' + element.previewId)) {
2257									if (field.hasOwnProperty('rsfpGetPreviewValue')) {
2258										document.getElementById('preview-' + element.previewId).innerHTML = field.rsfpGetPreviewValue();
2259									} else {
2260										document.getElementById('preview-' + element.previewId).innerText = field.value;
2261									}
2262								}
2263							}
2264							var funcMultiple = function () {
2265								if (document.getElementById('preview-' + element.previewId)) {
2266									var theValue = [];
2267									if (form.elements[field.name]) {
2268										if (form.elements[field.name].forEach) {
2269											form.elements[field.name].forEach(function (el) {
2270												if (el.checked) {
2271													if (document.querySelector('[for="' + el.id + '"]')) {
2272														theValue.push(RSFormPro.previewFields.escapeValue(document.querySelector('[for="' + el.id + '"]').innerText));
2273													} else {
2274														if (el.hasOwnProperty('rsfpGetPreviewValue')) {
2275															theValue.push(RSFormPro.previewFields.escapeValue(el.rsfpGetPreviewValue()));
2276														} else {
2277															theValue.push(RSFormPro.previewFields.escapeValue(el.value));
2278														}
2279													}
2280												}
2281											})
2282										} else {
2283											if (form.elements[field.name].checked) {
2284												if (form.elements[field.name].hasOwnProperty('rsfpGetPreviewValue')) {
2285													theValue.push(RSFormPro.previewFields.escapeValue(form.elements[field.name].rsfpGetPreviewValue()));
2286												} else {
2287													theValue.push(RSFormPro.previewFields.escapeValue(form.elements[field.name].value));
2288												}
2289											}
2290										}
2291									}
2292									document.getElementById('preview-' + element.previewId).innerHTML = theValue.join(element.separator || RSF
2292ormPro.previewFields.delimiter);
2293								}
2294							}
2295							var funcSurveyTable = function() {
2296								if (document.getElementById('preview-' + element.previewId)) {
2297									var theValue = [];
2298									var theQuestions = [];
2299									var theAnswers = [];
2300									var questions = parseInt(field.getAttribute('data-rsfpsurveytable-questions'));
2301									if (!isNaN(questions)) {
2302										var match = field.name.match(/^form\[(.*)]\[[0-9]+]$/);
2303										if (match)
2304										{
2305											var name = match[1];
2306											var firstPart = 'form[' + name + ']';
2307											for (var i = 0; i < questions; i ++) {
2308												if (form.elements[firstPart + '[' + i + ']'])
2309												{
2310													if (form.elements[firstPart + '[' + i + ']'].forEach)
2311													{
2312														form.elements[firstPart + '[' + i + ']'].forEach(function(el){
2313															if (el.checked)
2314															{
2315																theAnswers.push(el.parentNode.getAttribute('data-th'));
2316
2317																if (document.getElementById(el.getAttribute('aria-labelledby')))
2318																{
2319																	theQuestions.push(document.getElementById(el.getAttribute('aria-labelledby')).innerText);
2320																}
2321																else
2322																{
2323																	theQuestions.push(el.parentNode.parentNode.firstChild.innerText);
2324																}
2325															}
2326														});
2327													}
2328													else
2329													{
2330														if (form.elements[firstPart + '[' + i + ']'].checked)
2331														{
2332															theAnswers.push(form.elements[firstPart + '[' + i + ']'].parentNode.getAttribute('data-th'));
2333
2334															if (document.getElementById(form.elements[firstPart + '[' + i + ']'].getAttribute('aria-labelledby')))
2335															{
2336																theQuestions.push(document.getElementById(form.elements[firstPart + '[' + i + ']'].getAttribute('aria-labelledby')).innerText);
2337															}
2338															else
2339															{
2340																theQuestions.push(form.elements[firstPart + '[' + i + ']'].parentNode.parentNode.firstChild.innerText);
2341															}
2342														}
2343													}
2344												}
2345											}
2346
2347											for (var j = 0; j < theAnswers.length; j++) {
2348												theValue.push(element.template.replace('{question}', theQuestions[j]).replace('{answer}', theAnswers[j]));
2349											}
2350										}
2351									}
2352
2353									document.getElementById('preview-' + element.previewId).innerHTML = theValue.join(element.separator || RSF
2353ormPro.previewFields.delimiter);
2354								}
2355							}
2356							var funcSelect = function () {
2357								if (document.getElementById('preview-' + element.previewId)) {
2358									var theValue = [];
2359									if (field.options.length > 0) {
2360										for (var i = 0; i < field.options.length; i++) {
2361											if (field.options[i].selected) {
2362												theValue.push(RSFormPro.previewFields.escapeValue(field.options[i].text));
2363											}
2364										}
2365									}
2366									document.getElementById('preview-' + element.previewId).innerHTML = theValue.join(element.separator || RSFormPro.previewFields.delimiter);
2367								}
2368							}
2369							var funcBirthday = function () {
2370								if (document.getElementById('preview-' + element.previewId)) {
2371									var theValue = [];
2372									var theRoot = field.name.replace(/\[[dmy]]$/, '');
2373									var theElements = [theRoot + '[d]', theRoot + '[m]', theRoot + '[y]'];
2374									theElements.forEach(function(el){
2375										if (form.elements[el] && form.elements[el].value !== '') {
2376											theValue.push(form.elements[el].options[form.elements[el].selectedIndex].text);
2377										}
2378									})
2379									document.getElementById('preview-' + element.previewId).innerHTML = theValue.join(element.separator || '-');
2380								}
2381							}
2382							var funcFiles = function () {
2383								if (document.getElementById('preview-' + element.previewId)) {
2384									var f;
2385									var theValue = [];
2386									if (form.elements[field.name]) {
2387										if (form.elements[field.name].forEach) {
2388											form.elements[field.name].forEach(function (el) {
2389												if (el.files && el.files.length > 0) {
2390													for (f = 0; f < el.files.length; f++) {
2391														theValue.push(RSFormPro.previewFields.escapeValue(el.files[f].name));
2392													}
2393												}
2394											})
2395										} else {
2396											if (form.elements[field.name].files && form.elements[field.name].files.length > 0) {
2397												for (f = 0; f < form.elements[field.name].files.length; f++) {
2398													theValue.push(RSFormPro.previewFields.escapeValue(form.elements[field.name].files[f].name));
2399												}
2400											}
2401										}
2402									}
2403									document.getElementById('preview-' + element.previewId).innerHTML = theValue.join(element.separator || RSF
2403ormPro.previewFields.delimiter);
2404								}
2405							}
2406							tagName = field.tagName || field.nodeName;
2407
2408							if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
2409								var attachEvent = 'change';
2410								if (tagName === 'INPUT' && typeof field.type == 'string') {
2411									switch (field.type.toUpperCase()) {
2412										case 'FILE':
2413											funcValue = funcFiles;
2414											break;
2415
2416										case 'CHECKBOX':
2417										case 'RADIO':
2418											if (field.getAttribute('data-rsfpsurveytable-answer'))
2419											{
2420												funcValue = funcSurveyTable;
2421											}
2422											else
2423											{
2424												funcValue = funcMultiple;
2425											}
2426
2427											break;
2428
2429										case 'NUMBER':
2430										case 'TEXT':
2431										case 'PASSWORD':
2432										case 'EMAIL':
2433										case 'TEL':
2434										case 'URL':
2435										case 'RANGE':
2436											attachEvent = 'input';
2437											if (typeof RSFormPro.jQueryCalendar !== 'undefined' &&
2438												typeof RSFormPro.jQueryCalendar.calendars[formId] !== 'undefined' &&
2439												typeof RSFormPro.jQueryCalendar.calendars[formId][element.fieldName] !== 'undefined') {
2440												RSFormPro.jQueryCalendar.calendars[formId][element.fieldName].calendarInstance.setOptions({
2441													onChangeDateTime: function () {
2442														if (typeof funcValue === 'function') {
2443															funcValue();
2444														}
2445													}
2446												});
2447											}
2448
2449											if (typeof RSFormPro.YUICalendar !== 'undefined' &&
2450												typeof RSFormPro.YUICalendar.calendars[formId] !== 'undefined' &&
2451												typeof RSFormPro.YUICalendar.calendars[formId][element.fieldName] !== 'undefined') {
2452												RSFormPro.YUICalendar.calendars[formId][element.fieldName].selectEvent.subscribe(function () {
2453													if (typeof funcValue === 'function') {
2454														funcValue();
2455													}
2456												}, RSFormPro.YUICalendar.calendars[formId][element.fieldName], true);
2457											}
2458
2459											if (field.hasOwnProperty('rsfpOnChange')) {
2460												field.rsfpOnChange(funcValue);
2461											}
2462											break;
2463									}
2464								} else if (tagName === 'SELECT' && field.multiple === false && field.name.match(/form\[.*?]\[[dmy]]/)) {
2465									funcValue = funcBirthday;
2466								} else if (tagName === 'SELECT') {
2467									funcValue = funcSelect;
2468								} else if (tagName === 'TEXTAREA') {
2469									attachEvent = 'input';
2470								}
2471
2472								RSFormProUtils.addEvent(field, attachEvent, function () {
2473									if (typeof funcValue === 'function') {
2474										funcValue();
2475									}
2476								});
2477
2478								funcValue();
2479							}
2480						})(element, results[j], element.formId, form);
2481					}
2482				}
2483			}
2484		}
2485	}
2486};
2487
2488/* Helper functions */
2489var RSFormProUtils = {
2490	addEvent: function(obj, evType, fn) {
2491		if (obj.addEventListener)
2492		{
2493			obj.addEventListener(evType, fn, false);
2494			return true;
2495		}
2496		else if (obj.attachEvent)
2497		{
2498			var r = obj.attachEvent("on"+evType, fn);
2499			return r;
2500		}
2501		else
2502		{
2503			return false;
2504		}
2505	},
2506	hasClass: function (el, name) {
2507		return new RegExp('(\\s|^)' + name + '(\\s|$)').test(el.className);
2508	},
2509	addClass: function(el, name) {
2510		if (!RSFormProUtils.hasClass(el, name)) {
2511			el.className += (el.className ? ' ' : '') + name;
2512		}
2513	},
2514	removeClass: function(el, name) {
2515		if (RSFormProUtils.hasClass(el, name)) {
2516			el.className = el.className.replace(new RegExp('(\\s|^)' + name + '(\\s|$)'),' ').replace(/^\s+|\s+$/g, '');
2517		}
2518	},
2519	setDisplay: function (items, value) {
2520		if (!items || !items.length) {
2521			return false;
2522		}
2523
2524		for (var i = 0; i < items.length; i++) {
2525			if (!items[i]) {
2526				continue;
2527			}
2528
2529			if (!RSFormPro.usePositioning) {
2530				items[i].style.display = value;
2531			} else {
2532				value === 'none' ? RSFormProUtils.addClass(items[i], 'formHidden') : RSFormProUtils.removeClass(items[i], 'formHidden');
2533			}
2534		}
2535	},
2536	setAttr: function (items, attr, value) {
2537        for (var i = 0; i < items.length; i++) {
2538            items[i].setAttribute(attr, value);
2539        }
2540	},
2541    remAttr: function (items, attr) {
2542        for (var i = 0; i < items.length; i++) {
2543            items[i].removeAttribute(attr);
2544        }
2545    },
2546	getChecked: function (items) {
2547		var elements = [];
2548		var element, tagName;
2549        for (var i = 0; i < items.length; i++) {
2550        	element = items[i];
2551            tagName = element.tagName || element.nodeName;
2552
2553            if (tagName == 'INPUT' && element.type && element.type.toUpperCase() == 'CHECKBOX' && element.checked == true) {
2554				elements.push(element);
2555			}
2556        }
2557
2558        return elements;
2559	},
2560    getUnchecked: function (items) {
2561        var elements = [];
2562        var element, tagName;
2563        for (var i = 0; i < items.length; i++) {
2564            element = items[i];
2565            tagName = element.tagName || element.nodeName;
2566
2567            if (tagName == 'INPUT' && element.type && element.type.toUpperCase() == 'CHECKBOX' && !element.checked) {
2568                elements.push(element);
2569            }
2570        }
2571
2572        return elements;
2573    },
2574	getAlias: function(str) {
2575		str = str.replace(/\-/g, ' ');
2576
2577		if (!String.prototype.trim) {
2578			str = str.replace(/^\s+|\s+$/g, '');
2579		} else {
2580			str = str.trim();
2581		}
2582
2583		str = str.toLowerCase();
2584		str = str.replace(/(\s|[^A-Za-z0-9\-])+/g, '-');
2585		str = str.replace(/^\-+|\-+$/g, '');
2586
2587		return str;
2588	},
2589	getParents: function(a) {
2590		var els = [];
2591		while (a) {
2592			els.push(a);
2593			a = a.parentNode;
2594		}
2595		// Remove our own element
2596		if (els.length > 0)
2597		{
2598			els.shift()
2599		}
2600
2601		return els;
2602	},
2603	getElementsByClassName: function (className, tag, elm) {
2604		if (document.getElementsByClassName) {
2605			getElementsByClassName = function (className, tag, elm) {
2606				elm = elm || document;
2607				var elements = elm.getElementsByClassName(className),
2608					nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
2609					returnElements = [],
2610					current;
2611				for(var i=0, il=elements.length; i<il; i+=1){
2612					current = elements[i];
2613					if(!nodeName || nodeName.test(current.nodeName)) {
2614						returnElements.push(current);
2615					}
2616				}
2617				return returnElements;
2618			};
2619		} else if (document.evaluate) {
2620			getElementsByClassName = function (className, tag, elm) {
2621				tag = tag || "*";
2622				elm = elm || document;
2623				var classes = className.split(" "),
2624					classesToCheck = "",
2625					xhtmlNamespace = "http://www.w3.org/1999/xhtml",
2626					namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
2627					returnElements = [],
2628					elements,
2629					node;
2630				for(var j=0, jl=classes.length; j<jl; j+=1){
2631					classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
2632				}
2633				try	{
2634					elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
2635				}
2636				catch (e) {
2637					elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
2638				}
2639				while ((node = elements.iterateNext())) {
2640					returnElements.push(node);
2641				}
2642				return returnElements;
2643			};
2644		} else {
2645			getElementsByClassName = function (className, tag, elm) {
2646				tag = tag || "*";
2647				elm = elm || document;
2648				var classes = className.split(" "),
2649					classesToCheck = [],
2650					elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
2651					current,
2652					returnElements = [],
2653					match;
2654				for(var k=0, kl=classes.length; k<kl; k+=1){
2655					classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
2656				}
2657				for(var l=0, ll=elements.length; l<ll; l+=1){
2658					current = elements[l];
2659					match = false;
2660					for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
2661						match = classesToCheck[m].test(current.className);
2662						if (!match) {
2663							break;
2664						}
2665					}
2666					if (match) {
2667						returnElements.push(current);
2668					}
2669				}
2670				return returnElements;
2671			};
2672		}
2673
2674		return getElementsByClassName(className, tag, elm);
2675	},
2676
2677	/*!
2678	**  sprintf.js -- POSIX sprintf(3)-style String Formatting for JavaScript
2679	**  Copyright (c) 2006-2019 Dr. Ralf S. Engelschall <[email protected]>
2680	**  Partly based on Public Domain code by Jan Moesen <http://jan.moesen.nu/>
2681	**
2682	**  Permission is hereby granted, free of charge, to any person obtaining
2683	**  a copy of this software and associated documentation files (the
2684	**  "Software"), to deal in the Software without restriction, including
2685	**  without limitation the rights to use, copy, modify, merge, publish,
2686	**  distribute, sublicense, and/or sell copies of the Software, and to
2687	**  permit persons to whom the Software is furnished to do so, subject to
2688	**  the following conditions:
2689	**
2690	**  The above copyright notice and this permission notice shall be included
2691	**  in all copies or substantial portions of the Software.
2692	**
2693	**  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2694	**  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2695	**  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2696	**  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
2697	**  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2698	**  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2699	**  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2700	*/
2701	sprintf: function () {
2702		/*  argument sanity checking  */
2703		if (!arguments || arguments.length < 1)
2704			throw new Error("sprintf: ERROR: not enough arguments");
2705
2706		/*  initialize processing queue  */
2707		var argumentnum = 0;
2708		var done = "", todo = arguments[argumentnum++];
2709
2710		/*  parse still to be done format string  */
2711		var m;
2712		while ((m = /^([^%]*)%(?:(\d+)\$|\((.*?)\))?([#0 +'-]+)?(\*|\d+)?(\.\*|\.\d+)?([%diouxXfFeEcs])((?:.|[\r\n])*)$/.exec(todo))) {
2713			var pProlog    = m[1],
2714				pAccessD   = m[2],
2715				pAccessN   = m[3],
2716				pFlags     = m[4],
2717				pMinLength = m[5],
2718				pPrecision = m[6],
2719				pType      = m[7],
2720				pEpilog    = m[8];
2721
2722			/*  determine substitution  */
2723			var subst;
2724			if (pType === "%")
2725			/*  special case: escaped percent character  */
2726				subst = "%";
2727			else {
2728				/*  parse padding and justify aspects of flags  */
2729				var padWith = " ";
2730				var justifyRight = true;
2731				if (pFlags) {
2732					if (pFlags.indexOf("0") >= 0)
2733						padWith = "0";
2734					if (pFlags.indexOf("-") >= 0) {
2735						padWith = " ";
2736						justifyRight = false;
2737					}
2738				}
2739				else
2740					pFlags = "";
2741
2742				/*  determine minimum length  */
2743				var access;
2744				var minLength = -1;
2745				if (pMinLength) {
2746					if (pMinLength === "*") {
2747						access = argumentnum++;
2748						if (access >= arguments.length)
2749							throw new Error("sprintf: ERROR: not enough arguments");
2750						minLength = arguments[access];
2751					}
2752					else
2753						minLength = parseInt(pMinLength, 10);
2754				}
2755
2756				/*  determine precision  */
2757				var precision = -1;
2758				if (pPrecision) {
2759					if (pPrecision === ".*") {
2760						access = argumentnum++;
2761						if (access >= arguments.length)
2762							throw new Error("sprintf: ERROR: not enough arguments");
2763						precision = arguments[access];
2764					}
2765					else
2766						precision = parseInt(pPrecision.substring(1), 10);
2767				}
2768
2769				/*  determine how to fetch argument  */
2770				access = argumentnum++;
2771				if (pAccessD) {
2772					access = parseInt(pAccessD, 10);
2773					if (access >= arguments.length)
2774						throw new Error("sprintf: ERROR: not enough arguments");
2775					subst = arguments[access];
2776				}
2777				else if (pAccessN) {
2778					if (typeof arguments[1] !== "object")
2779						throw new Error("sprintf: ERROR: invalid non-object arguments for named argument");
2780					subst = arguments[1][pAccessN];
2781					if (typeof subst === "undefined")
2782						throw new Error("sprintf: ERROR: invalid undefined value for named argument");
2783				}
2784				else {
2785					if (access >= arguments.length)
2786						throw new Error("sprintf: ERROR: not enough arguments");
2787					subst = arguments[access];
2788				}
2789
2790				/*  dispatch into expansions according to type  */
2791				var prefix = "";
2792				switch (pType) {
2793					/*  decimal number  */
2794					case "d":
2795					case "i":
2796						if (typeof subst !== "number")
2797							subst = 0;
2798						subst = subst.toString(10);
2799						if (pFlags.indexOf("#") >= 0 && subst >= 0)
2800							subst = "+" + subst;
2801						if (pFlags.indexOf(" ") >= 0 && subst >= 0)
2802							subst = " " + subst;
2803						break;
2804
2805					/*  binary number  */
2806					case "b":
2807						if (typeof subst !== "number")
2808							subst = 0;
2809						subst = subst.toString(2);
2810						break;
2811
2812					/*  octal number  */
2813					case "o":
2814						if (typeof subst !== "number")
2815							subst = 0;
2816						subst = subst.toString(8);
2817						break;
2818
2819					/*  unsigned decimal number  */
2820					case "u":
2821						if (typeof subst !== "number")
2822							subst = 0;
2823						subst = Math.abs(subst);
2824						subst = subst.toString(10);
2825						break;
2826
2827					/*  (lower-case) hexadecimal number  */
2828					case "x":
2829						if (typeof subst !== "number")
2830							subst = 0;
2831						subst = subst.toString(16).toLowerCase();
2832						if (pFlags.indexOf("#") >= 0)
2833							prefix = "0x";
2834						break;
2835
2836					/*  (upper-case) hexadecimal number  */
2837					case "X":
2838						if (typeof subst !== "number")
2839							subst = 0;
2840						subst = subst.toString(16).toUpperCase();
2841						if (pFlags.indexOf("#") >= 0)
2842							prefix = "0X";
2843						break;
2844
2845					/*  (lower/upper-case) floating point number (fixed precision)  */
2846					case "f":
2847					case "F":
2848						if (typeof subst !== "number")
2849							subst = 0.0;
2850						subst = 0.0 + subst;
2851						if (precision > -1) {
2852							if (subst.toFixed)
2853								subst = subst.toFixed(precision);
2854							else {
2855								subst = (Math.round(subst * Math.pow(10, precision)) / Math.pow(10, precision));
2856								subst += "0000000000";
2857								subst = subst.substr(0, subst.indexOf(".") + precision + 1);
2858							}
2859						}
2860						subst = "" + subst;
2861						if (pFlags.indexOf("'") >= 0) {
2862							var k = 0;
2863							for (var i = (subst.length - 1) - 3; i >= 0; i -= 3) {
2864								subst = subst.substring(0, i) + (k === 0 ? "." : ",") + subst.substring(i);
2865								k = (k + 1) % 2;
2866							}
2867						}
2868						break;
2869
2870					/*  (lower/upper-case) floating point number (exponential-based precision)  */
2871					case "e":
2872					case "E":
2873						if (typeof subst !== "number")
2874							subst = 0.0;
2875						subst = 0.0 + subst;
2876						if (precision > -1) {
2877							if (subst.toExponential)
2878								subst = subst.toExponential(precision);
2879							else
2880								throw new Error("sprintf: ERROR: toExponential() method not supported");
2881						}
2882						subst = "" + subst;
2883						if (pType === "E")
2884							subst = subst.replace(/e\+/, "E+");
2885						break;
2886
2887					/*  single character  */
2888					case "c":
2889						if (typeof subst !== "number")
2890							subst = 0;
2891						subst = String.fromCharCode(subst);
2892						break;
2893
2894					/*  string  */
2895					case "s":
2896						if (typeof subst !== "string")
2897							subst = String(subst);
2898						if (precision > -1)
2899							subst = subst.substr(0, precision);
2900						break;
2901					default:
2902						throw new Error("sprintf: ERROR: invalid conversion character \"" + pType + "\"");
2903				}
2904
2905				/*  apply optional padding  */
2906				var padding = minLength - subst.toString().length - prefix.toString().length;
2907				if (padding > 0) {
2908					var arrTmp = new Array(padding + 1);
2909					if (justifyRight)
2910						subst = arrTmp.join(padWith) + subst;
2911					else
2912						subst = subst + arrTmp.join(padWith);
2913				}
2914
2915				/*  add optional prefix  */
2916				subst = prefix + subst;
2917			}
2918
2919			/*  update the processing queue  */
2920			done = done + pProlog + subst;
2921			todo = pEpilog;
2922		}
2923
2924		/*  return finally formatted string  */
2925		return (done + todo);
2926	}
2927};
2928
2929function isset() {
2930  // http://kevin.vanzonneveld.net
2931  // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
2932  // +   improved by: FremyCompany
2933  // +   improved by: Onno Marsman
2934  // +   improved by: Rafał Kukawski
2935  // *     example 1: isset( undefined, true);
2936  // *     returns 1: false
2937  // *     example 2: isset( 'Kevin van Zonneveld' );
2938  // *     returns 2: true
2939  var a = arguments,
2940    l = a.length,
2941    i = 0,
2942    undef;
2943
2944  if (l === 0) {
2945    throw new Error('Empty isset');
2946  }
2947
2948  while (i !== l) {
2949    if (a[i] === undef || a[i] === null) {
2950      return false;
2951    }
2952    i++;
2953  }
2954  return true;
2955}
2956
2957/* Legacy functions */
2958
2959function rsfp_geolocation(term, id, mapid,  map, marker, geocoder, type) {
2960	return RSFormPro.initGeoLocation(term, id, mapid, map, marker, geocoder, type);
2961}
2962
2963function refreshCaptcha(componentId, captchaPath) {
2964	return RSFormPro.refreshCaptcha(componentId, captchaPath);
2965}
2966
2967function number_format(number, decimals, dec_point, thousands_sep) {
2968	return RSFormPro.formatNumber(number, decimals, dec_point, thousands_sep);
2969}
2970
2971function rsfp_toNumber(number, decimal, thousands, decimals) {
2972	return RSFormPro.toNumber(number, decimal, thousands, decimals);
2973}
2974
2975function rsfp_getForm(formId) {
2976	return RSFormPro.getForm(formId);
2977}
2978
2979function rsfp_getValue(formId, name) {
2980	return RSFormPro.getValue(formId, name);
2981}
2982
2983function rsfp_verifyChecked(formId, name, value) {
2984	return RSFormPro.isChecked(formId, name, value);
2985}
2986
2987function rsfp_getBlock(formId, block) {
2988	return RSFormPro.getBlock(formId, block);
2989}
2990
2991function rsfp_getFieldsByName(formId, name) {
2992	return RSFormPro.getFieldsByName(formId, name);
2993}
2994
2995function rsfp_addEvent(obj, evType, fn) {
2996	return RSFormProUtils.addEvent(obj, evType, fn);
2997}
2998
2999function rsfp_setDisplay(items, value) {
3000	return RSFormProUtils.setDisplay(items, value);
3001}
3002
3003function stringURLSafe(str) {
3004	return RSFormProUtils.getAlias(str);
3005}
3006
3007function rsfp_changePage(formId, page, totalPages, validate, errorClasses) {
3008	return RSFormPro.Pages.change(formId, page, totalPages, validate, errorClasses);
3009}
3010
3011function rsfp_hidePage(thePage) {
3012	return RSFormPro.Pages.hide(thePage);
3013}
3014
3015function rsfp_showPage(thePage) {
3016	return RSFormPro.Pages.show(thePage);
3017}
3018
3019function rsfp_checkValidDate(fieldName) {
3020	return RSFormPro.disableInvalidDates(fieldName);
3021}
3022
3023function rsfp_addCondition(formId, name, fnCondition) {
3024	return RSFormPro.Conditions.add(formId, name, fnCondition);
3025}
3026
3027function rsfp_runAllConditions(formId) {
3028	return RSFormPro.Conditions.runAll(formId);
3029}
3030
3031function rsfp_setCalculationsEvents(formId, fields) {
3032	return RSFormPro.Calculations.addEvents(formId, fields);
3033}
3034
3035function getElementsByClassName(className, tag, elm) {
3036	return RSFormProUtils.getElementsByClassName(className, tag, elm);
3037}
3038
3039function buildXmlHttp() {
3040	return RSFormPro.Ajax.getXHR();
3041}
3042
3043function ajaxDisplayValidationErrors(formComponents, task, formId, data) {
3044	return RSFormPro.Ajax.displayValidationErrors(formComponents, task, formId, data);
3045}
3046
3047function ajaxValidation(form, page, errorClasses) {
3048	return RSFormPro.Ajax.validate(form, page, errorClasses);
3049}

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.