1(function () { 2 3 4 // polyfill for matches and closest 5 if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector; 6 if (!Element.prototype.closest) Element.prototype.closest = function (selector) { 7 var el = this; 8 while (el) { 9 if (el.matches(selector)) { 10 return el; 11 } 12 el = el.parentElement; 13 } 14 }; 15 16 17 18 //execute init() on document ready 19 if (document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll)) { 20 listen(); 21 } else { 22 document.addEventListener("DOMContentLoaded", listen); 23 } 24 25 function listen() { 26 27 // Inline script setting umbracoFormsCollection was removed in 8.11/9.3, and replaced by config elements. 28 // So if we have them, use it, otherwise fall-back to legacy method. 29 var configElements = document.getElementsByClassName("umbraco-forms-form-config"); 30 if (configElements.length > 0) { 31 var umbracoFormsCollectionFromConfig = []; 32 for (var i = 0; i < configElements.length; i++) { 33 var configElement = configElements[i]; 34 var form = { 35 formId: configElement.dataset.id, 36 pageButtonConditions: JSON.parse(configElement.dataset.serializedPageButtonConditions), 37 fieldSetConditions: JSON.parse(configElement.dataset.serializedFieldsetConditions), 38 fieldConditions: JSON.parse(configElement.dataset.serializedFieldConditions), 39 triggerConditionsCheckOn: configElement.dataset.triggerConditionsCheckOn, 40 recordValues: JSON.parse(configElement.dataset.serializedFieldsNotDisplayed), 41 formElementHtmlIdPrefix: configElement.dataset.formElementHtmlIdPrefix, 42 }; 43 umbracoFormsCollectionFromConfig.push(form); 44 } 45 initCollection(umbracoFormsCollectionFromConfig, true); // Set the 'jsonParsed' flag, indicating that we already have a JSON structure, which we don't have with the legacy, inline script method. 46 } else { 47 if (typeof umbracoFormsCollection === "undefined") { 48 //this will occur if this js file is loaded before the inline scripts, in which case 49 //we'll listen for the inline scripts to execute a custom event. 50 document.addEventListener("umbracoFormLoaded", init); 51 } 52 else { 53 initCollection(umbracoFormsCollection); 54 } 55 } 56 57 // Scrolling to the submitted form was also moved from an inline script in 8.11/9.3. 58 var submittedFormElement = document.getElementById("umbraco-forms-form-submitted"); 59 if (submittedFormElement) { 60 scrollToSubmittedForm(); 61 } 62 } 63 64 function initCollection(formsCollection, jsonParsed) { 65 configureUmbracoFormsValidation(); 66 67 for (var i = 0; i < formsCollection.length; i++) { 68 init({ form: formsCollection[i] }, jsonParsed); 69 } 70 } 71 72 function init(e, jsonParsed) { 73 74 var formItem = jsonParsed ? e.form : JSON.parse(decodeURI(e.form)); 75 76 var forms = document.querySelectorAll('.umbraco-forms-form'); 77 78 for(var i = 0; i < forms.length; i++) { 79 var form = forms[i]; 80 81 dependencyCheck(form); 82 83 var page = form.querySelector('.umbraco-forms-page'); 84 var conditions = new UmbracoFormsConditions(page, 85 formItem.pageButtonConditions, 86 formItem.fieldSetConditions, 87 formItem.fieldConditions, 88 formItem.triggerConditionsCheckOn && formItem.triggerConditionsCheckOn.length > 0 ? formItem.triggerConditionsCheckOn : "change", 89 formItem.recordValues, 90 formItem.formElementHtmlIdPrefix); 91 conditions.watch(); 92 93 applyFormAccessibility(form); 94 } 95 } 96 97 function scrollToSubmittedForm() { 98 document.onreadystatechange = function () { 99 100 if (document.readyState == "complete") {
101 var validationsDivs = document.querySelectorAll(".field-validation-error, .umbraco-forms-submitmessage"); 102 var scrollY = 0; 103 for (var i = 0; i < validationsDivs.length; i++) { 104 var node = getNode(validationsDivs[i]); 105 var offset = node.getBoundingClientRect().top; 106 if (0 < offset && (offset < scrollY || scrollY === 0)) { 107 scrollY = offset; 108 } 109 } 110 111 if (scrollY > 0) { 112 window.scrollTo(0, scrollY); 113 } 114 } 115 } 116 117 function getNode(node) { 118 var runner = node; 119 while (runner.tagName !== "BODY") { 120 if (runner.classList.contains("umbraco-forms-field")) { 121 return runner; 122 } 123 124 runner = runner.parentNode; 125 } 126 127 return node; 128 } 129 } 130 131 /** Configures the jquery validation for Umbraco forms */ 132 function configureUmbracoFormsValidation() { 133 134 if (window.aspnetValidation !== undefined) { 135 // Asp-net validation setup: 136 137 var validationService = new aspnetValidation.ValidationService(); 138 139 // TODO: equivilant to this: 140 /* 141 $.validator.setDefaults({ 142 ignore: ":hidden" 143 }); 144 */ 145 146 var required = function (value, element) { 147 // Handle single and multiple checkboxes: 148 if(element.type.toLowerCase() === "checkbox" || element.type.toLowerCase() === "radio") { 149 var allCheckboxesOfThisName = element.form.querySelectorAll("input[name='"+element.name+"']"); 150 for (var i=0; i<allCheckboxesOfThisName.length; i++) { 151 if (allCheckboxesOfThisName[i].checked === true) { 152 return true; 153 } 154 } 155 return false; 156 } 157 return Boolean(value); 158 } 159 validationService.addProvider("requiredcb", required); 160 validationService.addProvider("required", required);// this will go instead of the build-in required. 161 162 163 var umbracoforms_regex = function (value, element, params) { 164 if (!value || !params.pattern) { 165 return true; 166 } 167 168 var r = new RegExp(params.pattern); 169 return r.test(value); 170 } 171 validationService.addProvider("umbracoforms_regex", umbracoforms_regex); 172 173 var wrapProviderWithIgnorerBehaviour = function (provider) { 174 return function(value, element, params) { 175 176 // If field is hidden we ignorer the validation. 177 if (element.offsetParent === null) { 178 return true; 179 } 180 181 return provider(value, element, params); 182 } 183 } 184 185 // we can only incept with default validator if we do it after bootstrapping but before window load event triggers validationservice. 186 window.addEventListener('load', function() { 187 188 // Wrap all providers with ignorer hidden fields logic: 189 for (var key in validationService.providers) { 190 validationService.providers[key] = wrapProviderWithIgnorerBehaviour(validationService.providers[key]); 191 } 192 }); 193 194 // bootstrap validation service. 195 validationService.bootstrap(); 196
197 // Without jquery validation, the previous page submit button click isn't sent with it's name, 198 // so can't be used server-side to determine whether to go forward or back. 199 // Hence we'll use an alternate method, setting a hidden field that's also used in the check. 200 var handlePreviousClicked = function () { 201 this.form.elements["PreviousClicked"].value = "clicked"; 202 }; 203 204 // - previous buttons are indicated by a data attribute of data-umb="prev-forms-form", introduced in 8.12/9.4. 205 var previousButtonElements = document.querySelectorAll("[data-umb='prev-forms-form']"); 206 207 // - prior to that classes were used to identify them, so for compatibility with custom themes, we'll check for those too 208 // if we haven't found any via the data attribute. 209 if (previousButtonElements.length === 0) { 210 previousButtonElements = document.getElementsByClassName("prev cancel"); 211 } 212 213 for (var i = 0; i < previousButtonElements.length; i++) { 214 previousButtonElements[i].form.elements["PreviousClicked"].value = ""; 215 previousButtonElements[i].addEventListener('click', handlePreviousClicked, false); 216 } 217 218 } else if (typeof jQuery === "function" && $.validator && $.validator.unobtrusive) { 219 //Jquery validation setup 220 221 $.validator.setDefaults({ 222 ignore: ":hidden" 223 }); 224 225 $.validator.unobtrusive.adapters.addBool("requiredcb", "required"); 226 227 228 $.validator.addMethod("umbracoforms_regex", function (value, element) { 229 230 var regex = $(element).attr("data-regex"); 231 var val = $(element).val(); 232 if (val.length === 0) { 233 return true; 234 } 235 return val.match(regex); 236 }); 237 238 $.validator.unobtrusive.adapters.addBool("regex", "umbracoforms_regex"); 239 240 var submitInputs = document.querySelectorAll(".umbraco-forms-form input[type=submit]:not(.cancel)"); 241 for (let i = 0; i < submitInputs.length; i++) { 242 var input = submitInputs[i]; 243 input.addEventListener("click", function (evt) { 244 evt.preventDefault(); 245 var frm = $(this).closest("form"); 246 resetValidationMessages(frm[0]); 247 frm.validate(); 248 if (frm.valid()) { 249 frm.submit(); 250 this.setAttribute("disabled", "disabled"); 251 252 } 253 }.bind(input)); 254 } 255 } 256 257 } 258 259 /** 260 * method to determine if Umbraco Forms can run and has the required dependencies loaded 261 * @param {Form Element} formEl the element of the form 262 */ 263 function dependencyCheck(formEl) { 264 // Only perform check if the global 'Umbraco.Sys' is null/undefined. 265 // If present means we are in backoffice & that this is being rendered as a macro preview and We do not need to perform this check here. 266 // Similarly we need a check for if running in a rich text editor. 267 var isBackOffice = function () { 268 return typeof Umbraco !== "undefined" && typeof Umbraco.Sys !== "undefined"; 269 }; 270 var isBackOfficeRte = function () { 271 return document.body.id === "tinymce"; 272 }; 273 if (isBackOffice() || isBackOfficeRte()) { 274 return; 275 } 276 277 var errorElement = document.createElement("div"); 278 errorElement.className = "umbraco-forms missing-library"; 279 errorElement.style.color = "#fff"; 280 errorElement.style.backgroundColor = "#9d261d"; 281 errorElement.style.padding = "15px"; 282 errorElement.style.margin = "10px 0"; 283 var errorMessage = ""; 284 285 //Ensure umbracoForm is not null 286 if (formEl) { 287 288 //Check to see if the message for the form has been inserted already 289 var checkForExistinhgErr = formEl.getElementsByClassName('umbraco-forms missing-library'); 290 if (checkForExistinhgErr.length > 0) { 291 return; 292 } 293 294 var hasValidationFramework = false;
295 296 if (window.jQuery && $ && $.validator !== undefined) { 297 hasValidationFramework = true; 298 } else if (window.aspnetValidation !== undefined) { 299 hasValidationFramework = true; 300 } 301 302 if(hasValidationFramework === false) { 303 errorMessage = errorMessage + "Umbraco Forms requires a validation framework to run, please read documentation for posible options."; 304 } 305 306 if (errorMessage !== "") { 307 errorElement.innerHTML = errorMessage + '<br/> <a href="https://docs.umbraco.com/umbraco-forms/developer/prepping-frontend" target="_blank" style="text-decoration:underline; color:#fff;">See Umbraco Forms Documentation</a>'; 308 309 formEl.insertBefore(errorElement, formEl.childNodes[0]); 310 } 311 } 312 } 313 314 /** 315 * Applies form accessibility improvements. 316 * @param {Element} formEl the element of the form. 317 */ 318 function applyFormAccessibility(formEl) { 319 setFocusToFirstElementOnValidationError(formEl); 320 } 321 322 /** 323 * Monitors for validation errors and when found sets the focus to the first field with an error. 324 * @param {Element} formEl the element of the form. 325 */ 326 function setFocusToFirstElementOnValidationError(formEl) { 327 if ("MutationObserver" in window === false) { 328 return; 329 } 330 331 // To implement this, we are relying on on monitoring for validation message elements, which only fires when there are changes. 332 // So if you have two errors, and fix the first one, it wouldn't then highlight the second one on re-submitting the form. 333 // Unless we reset the validation messages on submit, so they get changed back on errors. 334 if (window.aspnetValidation !== undefined) { 335 var form = formEl.getElementsByTagName('form')[0]; 336 var handleResetValidationMessages = function () { 337 resetValidationMessages(form); 338 }; 339 form.addEventListener('submit', handleResetValidationMessages, false); 340 } else { 341 // For jquery.validate, we need to hook this in as part of the submit handler coded in configureUmbracoFormsValidation(); 342 } 343 344 // Watch for changes to the validation error messages in the DOM tree using a MutationObserver. 345 // See: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver 346 var observer = new MutationObserver(function (mutationRecords) { 347 for (var i = 0; i < mutationRecords.length; i++) { 348 var mutationRecord = mutationRecords[i]; 349 if (mutationRecord.target.className === 'field-validation-error') { 350 setFocusOnFormField(mutationRecord.target); 351 break; 352 } 353 } 354 }); 355 356 observer.observe(formEl, { 357 attributes: true, 358 attributeFilter: ['class'], 359 childList: false, 360 characterData: false, 361 subtree: true 362 }); 363 } 364 365 /** 366 * Resets the validation messages for a form. 367 * @param {Element} formEl the element of the form. 368 */ 369 function resetValidationMessages(formEl) { 370 var validationErrorMessageElements = formEl.getElementsByClassName('field-validation-error'); 371 for (var i = 0; i < validationErrorMessageElements.length; i++) { 372 validationErrorMessageElements[i].className = 'field-validation-valid'; 373 } 374 } 375 376 /** 377 * Sets the focus to the form field input element associated with the provided validation message element. 378 * @param {Element} validationErrorEl the element of the validation error. 379 */ 380 function setFocusOnFormField(validationErrorEl) { 381 var formFieldElement = validationErrorEl.previousElementSibling; 382 while (formFieldElement) { 383 if (formFieldElement.tagName.toLowerCase() === 'input' || 384 formFieldElement.tagName.toLowerCase() === 'textarea' || 385 formFieldElement.tagName.toLowerCase() === 'select') { 386 formFieldElement.focus(); 387 break; 388 } 389 390 if (formFieldElement.classList.contains("radiobuttonlist") || 391 formFieldElement.classList.contains("checkboxlist")) { 392 for (var i = 0; i < formFieldElement.children.length; i++) { 393 var formFieldChildElement = formFieldElement.children[i]; 394 if (formFieldChildElement.tagName.toLowerCase() === 'input') { 395 formFieldChildElement.focus(); 396 break; 397 } 398 } 399 400 break; 401 } 402 403 formFieldElement = formFieldElement.previousElementSibling; 404 } 405 } 406 407 /** 408 * Class to handle Umbraco Forms conditional statements 409 * @param {any} form a reference to the form 410 * @param {any} pageButtonConditions a reference to the page button conditions 411 * @param {any} fieldsetConditions a reference to the fieldset conditions 412 * @param {any} fieldConditions a reference to the field conditions 413 * @param {any} triggerConditionsCheckOn the client-side event on which condition checks should be triggered 414 * @param {any} values the form values 415 * @param {any} formElementHtmlIdPrefix the HTML ID prefix used when rendering the form 416 * @return {Object} reference to the created class 417 */ 418 function UmbracoFormsConditions(form, pageButtonConditions, fieldsetConditions, fieldConditions, triggerConditionsCheckOn, values, formElementHtmlIdPrefix) { 419
420 //our conditions "class" - must always be newed to work as it uses a form instance to operate on 421 //load all the information from the dom and serverside info and then the class will take care of the rest 422 423 var self = {}; 424 self.form = form; 425 self.pageButtonConditions = pageButtonConditions; 426 self.fieldsetConditions = fieldsetConditions; 427 self.fieldConditions = fieldConditions; 428 self.triggerConditionsCheckOn = triggerConditionsCheckOn; 429 self.values = values; 430 self.formElementHtmlIdPrefix = formElementHtmlIdPrefix; 431 self.dataTypes = {}; 432 433 //Iterates through all the form elements found on the page to update the registered value 434 function populateFieldValues(page, formValues, dataTypes) { 435 436 var selectFields = page.querySelectorAll("select"); 437 for (let i = 0; i < selectFields.length; i++) { 438 const field = selectFields[i]; 439 formValues[field.getAttribute("id")] = field.value; 440 dataTypes[field.getAttribute("id")] = "select"; 441 } 442 443 var textareaFields = page.querySelectorAll("textarea"); 444 for (let i=0; i<textareaFields.length; i++) { 445 const field = textareaFields[i]; 446 formValues[field.getAttribute("id")] = field.value; 447 dataTypes[field.getAttribute("id")] = "textarea"; 448 } 449 450 // clear out all saved checkbox values to we can safely append 451 var checkboxFields = page.querySelectorAll("input[type=checkbox]"); 452 for (let i=0; i<checkboxFields.length; i++) { 453 const field = checkboxFields[i]; 454 formValues[field.getAttribute("name")] = null; 455 dataTypes[field.getAttribute("name")] = "checkbox"; 456 } 457 458 //$page.find("input").each(function () { 459 var inputFields = page.querySelectorAll("input"); 460 for (let i=0; i<inputFields.length; i++) { 461 const field = inputFields[i]; 462 463 if (field.getAttribute('type') === "text" || 464 field.getAttribute('type') === "number" || 465 field.getAttribute('type') === "email" || 466 field.getAttribute('type') === "url" || 467 field.getAttribute('type') === "tel" || 468 field.getAttribute('type') === "date" || 469 field.getAttribute('type') === "datetime-local" || 470 field.getAttribute("type") === "hidden") { 471 formValues[field.getAttribute("id")] = field.value; 472 dataTypes[field.getAttribute("id")] = "text"; 473 } 474 475 if (field.getAttribute('type') === "radio") { 476 if (field.matches(':checked')) { 477 formValues[field.getAttribute("name")] = field.value; 478 dataTypes[field.getAttribute("name")] = "radio"; 479 } 480 } 481 482 if (field.getAttribute("type") === "checkbox") { 483 if (field.getAttribute("id") !== field.getAttribute("name")) { 484 if (field.matches(":checked")) { 485 if (formValues[field.getAttribute("name")] === null) { 486 formValues[field.getAttribute("name")] = field.value; 487 } 488 else { 489 formValues[field.getAttribute("name")] += ";;" + field.value; 490 } 491 } 492 } 493 else { 494 formValues[field.getAttribute("id")] = (field.matches(":checked") ? "true" : "false"); 495 } 496 } 497 } 498 } 499 500 /* Public api */ 501 502 self.operators = { 503 Is: function (value, expected, dataType) { 504 if ((value || "") === expected) { 505 return true; 506 } 507 if (value == null) { 508 return (expected == value); 509 } 510 511 if (dataType === "checkbox") { 512 if (expected.toUpperCase() === "TRUE" || expected.toUpperCase() === "ON") { 513 expected = "true" 514 } else if (expected.toUpperCase() === "FALSE" || expected.toUpperCase() === "OFF") { 515 expected = "false" 516 } 517 } 518 519 var values = value.split(';;'); 520 var matchingExpected = values.filter( 521 function (o) { 522 return o === expected; 523 }); 524 return matchingExpected.length > 0; 525 }, 526 IsNot: function (value, unexpected, dataType) { 527 if (value == null) { 528 return (unexpected != value); 529 } 530 var values = value.split(';;'); 531 var matchingUnexpected = values.filter( 532 function (o) { 533 return o === unexpected; 534 }); 535 536 if (dataType === "checkbox") { 537 if (unexpected.toUpperCase() === "TRUE" || unexpected.toUpperCase() === "ON") { 538 unexpected = "true" 539 } else if (unexpected.toUpperCase() === "FALSE" || unexpected.toUpperCase() === "OFF") { 540 unexpected = "false" 541 } 542 } 543 return (value || "") !== unexpected && matchingUnexpected.length === 0; 544 }, 545 GreaterThen: function (value, limit) { 546 if (isNaN(value) || isNaN(limit)) { 547 return value > limit; 548 } 549 550 return parseInt(value) > parseInt(limit); 551 }, 552 LessThen: function (value, limit) { 553 if (isNaN(value) || isNaN(limit)) { 554 return value < limit; 555 } 556 557 return parseInt(value) < parseInt(limit); 558 }, 559 StartsWith: function (value, criteria) { 560 return value && value.indexOf(criteria) === 0; 561 }, 562 EndsWith: function (value, criteria) { 563 return value && value.indexOf(criteria) === value.length - criteria.length; 564 }, 565 Contains: function (value, criteria) { 566 return value && value.indexOf(criteria) > -1; 567 } 568 }; 569 570 self.watch = function () { 571 // This is a special case for pikaday 572 // The only way around to pickup the value, for now, is to 573 // subscribe to blur events 574 var datepickerfields = self.form.querySelectorAll('.datepickerfield'); 575 for(let i = 0; i < datepickerfields.length; i++) { 576 const field = datepickerfields[i]; 577 field.addEventListener('blur', function () { 578 if(this.value===""){ 579 // Here comes the hack 580 // Force the hidden datepicker field the datepicker field 581 var id = this.getAttribute("id"); 582 var hiddenDatePickerField = id.substr(0, id.length-2); 583 self.values[hiddenDatePickerField]="";
584 document.getElementById(hiddenDatePickerField).value="";// sadly we cant use querySelector with current mark-up (would need to prefix IDs) 585 } 586 587 populateFieldValues(self.form, self.values, self.dataTypes); 588 //process the conditions 589 self.run(); 590 }.bind(field)); 591 } 592 //subscribe to change or input event as per configuration 593 var changeablefields = self.form.querySelectorAll("input, textarea, select"); 594 for (let i = 0; i < changeablefields.length; i++) { 595 const field = changeablefields[i]; 596 field.addEventListener(self.triggerConditionsCheckOn, function () { 597 populateFieldValues(self.form, self.values, self.dataTypes); 598 //process the conditions 599 self.run(); 600 }.bind(field)); 601 } 602 603 //register all values from the current fields on the page 604 populateFieldValues(self.form, self.values, self.dataTypes); 605 606 //the initial run-through of all the conditions 607 self.run(); 608 }; 609 610 self.run = function () { 611 var pageId, 612 htmlFieldId, 613 fsId, 614 fieldId, 615 616 /* 617 fsConditions = params.fsConditions || {}, 618 fieldConditions = params.fieldConditions || {}, 619 values = params.values || {},*/ 620 621 cachedResults = {}; 622 623 function evaluateRuleInstance(rule) { 624 var value = self.values[self.formElementHtmlIdPrefix + rule.field], 625 dataType = self.dataTypes[rule.field], 626 func = self.operators[rule.operator], 627 result = value !== null && func(value, rule.value, dataType); 628 return result; 629 } 630 631 function evaluateRule(rule) { 632 var dependencyIsVisible = true; 633 634 if (self.fieldConditions[rule.field]) { 635 dependencyIsVisible = isVisible(rule.field, self.fieldConditions[rule.field]); 636 } 637 638 if (dependencyIsVisible) { 639 return evaluateRuleInstance(rule); 640 } 641 else { 642 return false; 643 } 644 } 645 646 function evaluateCondition(id, condition) { 647 // This was once pretty. Now it needs refactoring again. :) 648 649 var any = condition.logicType === "Any", 650 all = condition.logicType === "All", 651 fieldsetVisibilities = {}, 652 hasHiddenFieldset = false, 653 success = true, 654 rule, 655 i; 656 657 // If we don't have any rules defined, we must return false (as neither 'any' nor 'all' of the conditions 658 // can be considered passing). 659 if (condition.rules.length === 0) { 660 return false; 661 } 662 663 for (i = 0; i < condition.rules.length; i++) { 664 rule = condition.rules[i]; 665 666 if (id === rule.field || id === rule.fieldsetId) { 667 throw new Error("Field or fieldset " + id + " has a condition on itself."); 668 } 669 670 if (fieldsetVisibilities[rule.fieldsetId] !== undefined) { 671 continue; 672 } 673 674 if (self.fieldsetConditions[rule.fieldsetId]) { 675 676 fieldsetVisibilities[rule.fieldsetId] = 677 isVisible(rule.fieldsetId, self.fieldsetConditions[rule.fieldsetId]); 678 679 if (!fieldsetVisibilities[rule.fieldsetId]) { 680 hasHiddenFieldset = true; 681 } 682 } 683 else { 684 fieldsetVisibilities[rule.fieldsetId] = true; 685 } 686 } 687 688 if (all && hasHiddenFieldset) { 689 return false;
690 } 691 692 for (i = 0; i < condition.rules.length; i++) { 693 rule = condition.rules[i]; 694 695 if (fieldsetVisibilities[rule.fieldsetId]) { 696 success = evaluateRule(condition.rules[i]); 697 } 698 else { 699 success = false; 700 } 701 702 if (any && success) { 703 break; 704 } 705 if (all && !success) { 706 break; 707 } 708 } 709 return success; 710 } 711 712 function evaluateConditionVisibility(id, condition) { 713 var show = condition.actionType === "Show", 714 cachedResult = cachedResults[id]; 715 716 var success; 717 if (cachedResult === undefined) { 718 cachedResults[id] = show; // set default value to avoid circular issues 719 success = (cachedResults[id] = evaluateCondition(id, condition)); 720 } else { 721 success = cachedResult; 722 } 723 724 var visible = !(success ^ show); 725 return visible; 726 } 727 728 function isVisible(id, condition) { 729 if (condition) { 730 return evaluateConditionVisibility(id, condition); 731 } 732 return true; 733 } 734 735 function handleCondition(element, id, condition) { 736 var shouldShow = isVisible(id, condition); 737 if (element) { 738 if (shouldShow) { 739 element.style.display = ""; 740 } 741 else { 742 element.style.display = "none"; 743 } 744 } 745 } 746 747 for (pageId in self.pageButtonConditions) { 748 if (Object.prototype.hasOwnProperty.call(self.pageButtonConditions, pageId)) { 749 var pageElem = document.getElementById(pageId); 750 if (pageElem) { 751 handleCondition(pageElem.querySelector("input[name='__next'], button[name='__next'], input[data-form-navigate='next'], button[data-form-navigate='next']"), pageId, self.pageButtonConditions[pageId], "Page"); 752 } 753 } 754 } 755 756 for (fsId in self.fieldsetConditions) { 757 if (Object.prototype.hasOwnProperty.call(self.fieldsetConditions, fsId)) { 758 htmlFieldId = self.formElementHtmlIdPrefix + fsId; 759 handleCondition(document.getElementById(htmlFieldId), fsId, self.fieldsetConditions[fsId], "Fieldset");// sadly we cant use querySelector with current mark-up (would need to prefix IDs) 760 } 761 } 762 763 for (fieldId in self.fieldConditions) { 764 if (Object.prototype.hasOwnProperty.call(self.fieldConditions, fieldId)) { 765 htmlFieldId = self.formElementHtmlIdPrefix + fieldId; 766 if (document.getElementById(htmlFieldId)) { 767 handleCondition(document.getElementById(htmlFieldId).closest(".umbraco-forms-field"),// sadly we cant use querySelector with current mark-up (would need to prefix IDs) 768 fieldId, 769 self.fieldConditions[fieldId], 770 "Field"); 771 } 772 } 773 } 774 }; 775 776 return self; 777 } 778})();
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.