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