1"use strict"; 2 3//version: 1.11 4 5function UnlimitedElementsForm(){ 6 7 var t = this; 8 9 //selectors 10 var ueInputFieldSelector, ueNumberSelector, ueNumberErrorSelector, ueOptionFieldSelector; 11 12 //objects 13 var g_objCalcInputs; 14 15 //helpers 16 var g_allowedSymbols, g_parents = []; 17 18 /** 19 * trace 20 */ 21 function trace(str){ 22 console.log(str); 23 } 24 25 /** 26 * show custom error 27 */ 28 function showCustomError(objError, errorText, consoleErrorText){ 29 30 objError.text(errorText); 31 32 objError.show(); 33 34 var objErrorParent = objError.parents(".debug-wrapper"); 35 36 if(!objErrorParent.length) 37 throw new Error(consoleErrorText); 38 39 objErrorParent.addClass("ue_error_true"); 40 41 throw new Error(consoleErrorText); 42 43 } 44 45 /** 46 * get formula names 47 */ 48 function getFormulaNames(expr, objError){ 49 50 var regex = /\[(.*?)\]/g; 51 52 var matches = expr.match(regex); 53 54 var names; 55 56 if(matches) 57 names = matches.map(match => match.substring(1, match.length - 1)); 58 59 if(names == undefined) 60 return(false); 61 62 //check for space inside name 63 names.forEach(function(name, index){ 64 65 for (var i = 0; i < name.length; i++) { 66 67 var currentChar = name[i]; 68 69 if(currentChar === " "){ 70 71 var errorText = 'Unlimited Elements Form Error: Name option must not contain spaces inside. Found in name: '+name; 72 var consoleErrorText = "Space character in name found"; 73 74 showCustomError(objError, errorText, consoleErrorText); 75 76 } 77 78 } 79 80 }); 81 82 //remove spacing in case they were not removed before 83 expr = expr.replace(/\s+/g, ""); 84 85 var unmatches = expr.replace(regex, "").split(/[\[\]]/); 86 87 //exclude allowed symbols and check if array is empty, if not - then in formula some fields written without square parentacess 88 unmatches = unmatches[0].replace(g_allowedSymbols, "").split(/[\[\]]/); 89 90 if(unmatches[0].length > 0){ 91 92 var errorText = 'Unlimited Elements Form Error: Input Name should be surrounded by square parentheses inside Formula'; 93 var consoleErrorText = "Missing square parentheses inside Formula"; 94 95 showCustomError(objError, errorText, consoleErrorText); 96 97 } 98 99 return(names); 100 101 } 102 103 /** 104 * replace fields name with its values 105 */ 106 function replaceNamesWithValues(expr, objError, objCalcInput){ 107 108 var names = getFormulaNames(expr, objError); 109 110 if(names == undefined || names == false) 111 return(expr); 112 113 names.forEach(function(name, index){ 114 115 var objInpput = jQuery(ueInputFieldSelector+'[name="'+name+'"]'); 116 117 if(!objInpput.length){ 118 119 var errorText = 'Unlimited Elements Form Error: couldn"t find Number Field Widget with name: '+name; 120 var consoleErrorText = "Invalid Number Field Widget Name"; 121 122 showCustomError(objError, errorText, consoleErrorText); 123 124 } 125 126 if(objInpput.length > 1){ 127 128 var errorText = 'Unlimited Elements Form Error: Name option must be unique. Found '+objInpput.length+' Number Field Widgets with name: '+name; 129 var consoleErrorText = "Invalid Number Field Widget Name"; 130 131 showCustomError(objError, errorText, consoleErrorText); 132 133 } 134 135 //check if uppercase characters are in name 136 for (var i = 0; i < name.length; i++) { 137 138 var currentChar = name[i]; 139 140 if (currentChar === currentChar.toUpperCase() && currentChar !== currentChar.toLowerCase()){ 141 142 var errorText = 'Unlimited Elements Form Error: Name option must not contain Uppercase characters. Found in name: '+name; 143 var consoleErrorText = "Uppercase in name found"; 144 145 showCustomError(objError, errorText, consoleErrorText); 146 147 } 148 149 if(currentChar === " "){ 150 151 var errorText = 'Unlimited Elements Form Error: Name option must not contain spaces inside. Found in name: '+name; 152 var consoleErrorText = "Space character in name found"; 153 154 showCustomError(objError, errorText, consoleErrorText); 155 156 } 157 158 } 159 160 var dataDateMode = objCalcInput.data("date-mode"); 161
162 //set formula input to date type 163 if(dataDateMode == true) 164 objCalcInput.attr("type", "date"); 165 166 var inputType = objInpput.attr("type"); 167 var inputValue; 168 169 if(inputType != "date"){ 170 171 inputValue = objInpput.val(); 172 173 //if input is empty then count it as 0 174 if(inputValue.length == 0) 175 inputValue = 0; 176 177 //see if input value is round number, if so - make sure the number is unformatted 178 var dataSeparateThousandsFormat = objInpput.data("separate-thousands-format"); 179 180 if(dataSeparateThousandsFormat == "de-DE"){ 181 182 inputValue = Number(inputValue.replace(".", "").replace(",", "")); 183 184 }else{ 185 186 //make sure value is number type (usefull for separating thousand option) 187 inputValue = Number(inputValue.toString().replace(",", '')); 188 189 } 190 191 //add parentheses if valus is less then 0 192 if(inputValue < 0) 193 inputValue = "("+inputValue+")"; 194 195 }else{ 196 197 inputValue = new Date(objInpput.val()).getTime(); 198 } 199 200 expr = expr.replace(name, inputValue); 201 expr = expr.replace('[', ''); 202 expr = expr.replace(']', ''); 203 }); 204 205 return(expr); 206 } 207 208 /* 209 * validate the expression 210 */ 211 function validateExpression(expr){ 212 213 //allow Math.something (math js operation), numbers, float numbers, math operators, dots, comas 214 var matches = expr.match(g_allowedSymbols); 215 216 var result = ""; 217 218 if (matches) 219 result = matches.join(''); 220 221 expr = result; 222 223 return(expr); 224 } 225 226 /** 227 * get result from expression 228 */ 229 function getResult(expr, objError, objCalcInput) { 230 231 //if space just erase it 232 expr = expr.replace(/\s+/g, ""); 233 234 //replace inputs name with its values 235 expr = replaceNamesWithValues(expr, objError, objCalcInput); 236 237 var result; 238 239 //returan closest value from lookup table if needed 240 var dataLookupTableMode = objCalcInput.data("lookup-table"); 241 242 if(dataLookupTableMode == true){ 243 244 result = getClosestValue(objCalcInput, objError); 245 246 return(result); 247 } 248 249 var dataDateMode = objCalcInput.data("date-mode"); 250 251 if(dataDateMode == true){ 252 253 result = new Date(eval(expr)); 254 255 return(result); 256 } 257 258 //validate espression 259 expr = validateExpression(expr); 260 261 var errorText = `Unlimited Elements Form Error: wrong math operation: ${expr}`; 262 var consoleErrorText = `Invalid operation: ${expr}`; 263 264 //catch math operation error 265 try{ 266 267 result = eval(expr); 268 269 //hide error message after successful calculation 270 objError.hide(); 271 } 272 273 catch{ 274 275 showCustomError(objError, errorText, consoleErrorText); 276 } 277 278 if(isNaN(result) == true){ 279 280 showCustomError(objError, errorText, consoleErrorText); 281 } 282 283 return result; 284 285 } 286 287 /** 288 * get number formated in fractional number 289 */ 290 function getFractionalResult(result, objCalcInput){ 291 292 var dataCharNum = objCalcInput.data("char-num"); 293 294 //replace coma woth period if needed here 295 var dataPeriod = objCalcInput.data("dot-instead-coma"); 296 297 if(dataPeriod == true){ 298 299 //change type of the field to "text" (this makes coma change to dot) 300 objCalcInput.attr("type", "text"); 301 302 return(result.toFixed(dataCharNum)); 303 304 } else{ 305 306 return(result.toFixed(dataCharNum)) 307 308 } 309 310 } 311 312 /** 313 * format result number 314 */ 315 function formatResultNumber(result, objCalcInput){ 316 317 var dataDateMode = objCalcInput.data("date-mode"); 318 319 if(dataDateMode == true){ 320 321 result = result.toISOString().split('T')[0] 322 323 return(result); 324 } 325 326 var dataFormat = objCalcInput.data("format"); 327 328 if(dataFormat == "round") 329 return(Math.round(result)) 330 331 if(dataFormat == "floor") 332 return(Math.floor(result)) 333 334 if(dataFormat == "ceil") 335 return(Math.ceil(result)) 336 337 if(dataFormat == "fractional") 338 return(getFractionalResult(result, objCalcInput)); 339 340 } 341 342 /** 343 * add coma to separate thousands 344 */ 345 function getValueWithSeparatedThousands(val, objCalcInput){ 346 347 //input can be "text" or "number" type (some old versions of Text Field widget has calculation mode) 348 349 var dataSeparateThousands = objCalcInput.data("separate-thousands"); 350 351 //if no such attribute exit function 352 if(!dataSeparateThousands) 353 return(val) 354 355 //if it set to false exit too 356 if(dataSeparateThousands == false) 357 return(val); 358 359 var inputType = objCalcInput.attr("type"); 360 361 //if type is not "text" then make it "text" 362 if(inputType != "text") 363 objCalcInput.attr("type", "text"); 364 365 var dataSeparateThousandsFormat = objCalcInput.data("separate-thousands-format"); 366 367 if(!dataSeparateThousandsFormat) 368 dataSeparateThousandsFormat = "en-US"; 369 370 val = val.toString().split("."); 371
372 //different format available only for round numbers, if number isn't round then format only with coma 373 if(val.length > 1 && dataSeparateThousandsFormat == "en-US") 374 val = parseFloat(val[0]).toLocaleString(dataSeparateThousandsFormat) + '.' + val[1]; 375 else 376 val = parseFloat(val[0]).toLocaleString(dataSeparateThousandsFormat) 377 378 return(val); 379 380 } 381 382 /** 383 * init calc mode 384 */ 385 function setResult(objCalcInput, objError){ 386 387 //if data formula is empty 388 var dataFormula = objCalcInput.data("formula"); 389 390 if(dataFormula == undefined) 391 return(false); 392 393 //get result with numbers instead of fields name 394 var result = getResult(dataFormula, objError, objCalcInput); 395 396 //format result 397 result = formatResultNumber(result, objCalcInput); 398 399 //separate thousands 400 result = getValueWithSeparatedThousands(result, objCalcInput); 401 402 //set result to input 403 objCalcInput.val(result); 404 405 //set readonly attr if needed 406 var dataRemoveReadonlyCalcMode = objCalcInput.data("remove-readonly-for-calc-mode"); 407 var inputType = objCalcInput.attr("type"); 408 409 if(dataRemoveReadonlyCalcMode == false || inputType != "number") 410 objCalcInput.attr('readonly', ''); 411 412 } 413 414 /** 415 * input change controll 416 */ 417 function onInputChange(objCalcInput){ 418 419 objCalcInput.trigger("input_calc"); 420 421 } 422 423 /** 424 * get parent object 425 */ 426 function getParentInput(dataName){ 427 428 dataName = dataName.replace('[', ''); 429 dataName = dataName.replace(']', ''); 430 431 var objInput = jQuery(ueInputFieldSelector+'[name="'+dataName+'"]'); 432 433 return(objInput); 434 435 } 436 437 /** 438 * assign parent for lookup table fields 439 */ 440 function assignParentsForLookupTable(objParent, parentAttrName){ 441 442 var parentIdAttribute = objParent.attr("id"); 443 var objFormula = objParent.find("[data-formula]"); 444 445 var dataXField = objFormula.data("field-name-x"); 446 var dataYField = objFormula.data("field-name-y"); 447 448 var objXField = getParentInput(dataXField); 449 var objYField = getParentInput(dataYField); 450 451 objXField.attr(parentAttrName, parentIdAttribute); 452 objYField.attr(parentAttrName, parentIdAttribute); 453 454 } 455 456 /** 457 * remove duplicated values from array 458 */ 459 function removeDuplicatesFromArray(arr) { 460 461 var uniqueArray = []; 462 463 jQuery.each(arr, function(index, value) { 464 465 if (jQuery.inArray(value, uniqueArray) === -1) 466 uniqueArray.push(value); 467 468 }); 469 470 return uniqueArray; 471 } 472 473 /** 474 * assign parent calc number field input to each input inside formula 475 */ 476 function assignParentNumberField(objParent, objError){ 477 478 var objFormula = objParent.find("[data-formula]"); 479 var expr = objFormula.data("formula"); 480 var parentIdAttribute = objParent.attr("id"); 481 var parentAttrName = "data-parent-formula-input"; 482 var dataLookup = objFormula.data("lookup-table"); 483 484 if(dataLookup == true){ 485 486 assignParentsForLookupTable(objParent, parentAttrName); 487 488 return(false); 489 490 } 491 492 var names = getFormulaNames(expr, objError); 493 494 if(names == undefined || names == false) 495 return(false); 496 497 for(let i=0;i<names.length;i++){ 498 499 var objInpput = getParentInput(names[i]); 500 501 g_parents.push(parentIdAttribute); 502 503 g_parents = removeDuplicatesFromArray(g_parents); 504 505 objInpput.attr(parentAttrName, g_parents); 506 507 } 508 509 } 510 511 /** 512 * Parse the CSV data into a two-dimensional array 513 */ 514 function getLookupTable(csvData){ 515 516 csvData = csvData.split('\n').map(function (row) { 517 return row.split(','); 518 }); 519 520 return(csvData); 521 522 } 523 524 // Function to calculate the Euclidean distance between two points (width, height) 525 function euclideanDistance(x1, y1, x2, y2) { 526 527 return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); 528 529 } 530 531 /** 532 * find closest value 533 */ 534 function getClosestValue(objCalcInput, objError) { 535 536 var dataX = objCalcInput.data("field-name-x"); 537 var dataY = objCalcInput.data("field-name-y"); 538 var objXField = getParentInput(dataX); 539 var objYField = getParentInput(dataY); 540 541 var csvData = objCalcInput.data("csv"); 542 var xValue = objXField.val(); 543 var yValue = objYField.val(); 544 545 //format csv table 546 var lookupTable = getLookupTable(csvData); 547 548 if(!xValue){ 549 550 var errorText = 'Unlimited Elements Form Error: no x-value found.'; 551 var consoleErrorText = 'Unlimited Elements Form Error: no x-value found.'; 552 553 showCustomError(objError, errorText, consoleErrorText); 554 555 } 556 557 if(!yValue){ 558 559 var errorText = 'Unlimited Elements Form Error: no x-value found.'; 560 var consoleErrorText = 'Unlimited Elements Form Error: no x-value found.'; 561 562 showCustomError(objError, errorText, consoleErrorText); 563 564 } 565
566 //hide error object in case of successful calculation 567 objError.hide(); 568 569 var closestValue = null; 570 var closestDistance = Infinity; 571 572 for (var row = 1; row < lookupTable.length; row++) { 573 574 for (var col = 1; col < lookupTable[row].length; col++) { 575 576 var tableValue = lookupTable[row][col]; 577 var tableX = lookupTable[0][col]; 578 var tableY = lookupTable[row][0]; 579 var distance = euclideanDistance(xValue, yValue, tableX, tableY); 580 581 if (distance < closestDistance) { 582 583 closestDistance = distance; 584 closestValue = tableValue; 585 586 } 587 588 } 589 590 } 591 592 return +closestValue; 593 594 } 595 596 /** 597 * get parent input calc 598 */ 599 function getParentCalcInput(objInput){ 600 601 var parentsArray = objInput.attr("data-parent-formula-input"); 602 603 var objParentsArray = []; 604 605 //make sure attr is an array 606 if(parentsArray != undefined){ 607 608 parentsArray = parentsArray.split(","); 609 610 parentsArray.forEach(function(id, index){ 611 612 var parentId = id; 613 var objParentCalcInput = jQuery("#"+parentId).find("[data-calc-mode='true']"); 614 615 objParentsArray.push(objParentCalcInput); 616 617 }); 618 619 return(objParentsArray); 620 621 } 622 623 } 624 625 /** 626 * show main input 627 */
628 function showField(objFieldWidget, classHidden){ 629 630 objFieldWidget.removeClass(classHidden); 631 632 } 633 634 /** 635 * hide main input 636 */ 637 function hideField(objFieldWidget, classHidden){ 638 639 objFieldWidget.addClass(classHidden); 640 641 } 642 643 /** 644 * get condition 645 */ 646 function getConditions(visibilityCondition, condition, objFieldValue, fieldValue){ 647 648 switch (condition) { 649 case "=": 650 651 visibilityCondition = objFieldValue == fieldValue; 652 653 break; 654 case ">": 655 656 visibilityCondition = objFieldValue > fieldValue; 657 658 break; 659 case ">=": 660 661 visibilityCondition = objFieldValue >= fieldValue; 662 663 break; 664 case "<": 665 666 visibilityCondition = objFieldValue < fieldValue; 667 668 break; 669 case "<=": 670 671 visibilityCondition = objFieldValue <= fieldValue; 672 673 break; 674 case "!=": 675 676 visibilityCondition = objFieldValue != fieldValue; 677 678 break; 679 680 } 681 682 return(visibilityCondition); 683 684 } 685 686 /** 687 * get operator 688 */ 689 function getOperators(operator, visibilityOperator){ 690 691 switch (operator){ 692 693 case "and": 694 695 visibilityOperator = "&&"; 696 697 break; 698 case "or": 699 700 visibilityOperator = "||"; 701 702 break; 703 704 } 705 706 return(visibilityOperator); 707 708 } 709 710 711 /** 712 * get names 713 */ 714 function getNames(arrNames, fieldName){ 715 716 arrNames = []; 717 arrNames.push(fieldName); 718 719 return(arrNames); 720 721 } 722 723 /** 724 * equal condition and input names error 725 */ 726 function equalConditionInputNameError(objField, arrNames, classError){ 727 728 var inputName = objField.attr("name"); 729 730 var isNamesEqual = arrNames.indexOf(inputName) != -1; 731 732 if(isNamesEqual == true){ 733 734 var errorHtml = "<div class="+classError+">Unlimited Field Error: can't set condition. Condition Item Name equals Field Name: [ " + inputName + " ]. Please use different names.</div>"; 735 736 jQuery(errorHtml).insertBefore(objField.parent()); 737 738 } 739 740 } 741 742 /** 743 * set visibility in editor 744 */ 745 function setVisibilityInEditor(objFieldWidget, classError, classHidden
745){ 746 747 var hiddenHtml = "<div class="+classError+">Unlimited Field is hidden due to Visibility Condition Options. <br> This message shows only in editor.</div>"; 748 var objError = objFieldWidget.find("."+classError); 749 750 if(objFieldWidget.hasClass(classHidden) == true){ 751 752 if(!objError || !objError.length) 753 objFieldWidget.prepend(hiddenHtml); 754 755 }else{ 756 757 if(objError && objError.length) 758 objError.remove(); 759 760 } 761 762 } 763 764 /** 765 * check if calculator input includes invisible inputs 766 */ 767 function checkInvisibleInputsInFormula(){ 768 769 //if no calc mode inpu found on page - do nothing 770 if(!g_objCalcInputs.length) 771 return(false); 772 773 //look after each calc mode input field on a page 774 g_objCalcInputs.each(function(){ 775 776 var objCalcInput = jQuery(this); 777 778 //find main warapper of the widget 779 var objCalcWidget = objCalcInput.parents(ueNumberSelector); 780 var objError = objCalcWidget.find(ueNumberErrorSelector); 781 var formula = objCalcInput.data('formula'); 782 783 if(!formula) 784 return(true); 785 786 var names = getFormulaNames(formula, objError); 787 788 if(names == undefined || names == false) 789 return(false); 790 791 names.forEach(function(name, index){ 792 793 var objInpput = jQuery(ueInputFieldSelector+'[name="'+name+'"]'); 794 795 //check if field is hidden due to condition 796 // if(objInpput.is(':visible') == false){ 797 798 // var errorText = 'Unlimited Elements Form Error: Field is invisible on the page, but contains in formula: '+name+'.'; 799 // var consoleErrorText = `Field is invisible on the page, but contains in formula: ${name}`; 800 801 // showCustomError(objError, errorText, consoleErrorText); 802 803 // } 804 805 }); 806 807 }); 808 809 } 810 811 /** 812 * recalculate parent inputs 813 */ 814 function recalculateParentInputs(objParentCalkInputs){ 815 816 if(objParentCalkInputs != undefined){ 817 818 objParentCalkInputs.forEach(function(parent, index){ 819 820 onInputChange(parent); 821 822 }); 823 824 } 825 826 } 827 828 /* 829 * process the visibility array 830 */ 831 t.setVisibility = function(conditionArray, widgetId){ 832 833 var objFieldWidget = jQuery("#"+widgetId); 834 var classHidden = "ucform-has-conditions"; 835 var classError = "ue-error"; 836 837 var conditions = conditionArray.visibility_conditions; 838 var conditionsNum = conditions.length; 839 840 if(conditionsNum == 0) 841 return(false); 842 843 var totalVisibilityCondition; 844 845 //create val to contain all the names for errors catching purposes 846 var arrNames; 847 848 for(let i=0; i<conditionsNum; i++){ 849 850 var conditionArray = conditions[i]; 851 var condition = conditionArray.condition; 852 var fieldName = conditionArray.field_name; 853 var fieldValue = parseInt(conditionArray.field_value); 854 var operator = conditionArray.operator; 855 var id = conditionArray._id; 856 857 var objField = jQuery(ueInputFieldSelector+'[name="'+fieldName+'"]'); 858 859 var objFieldValue = parseInt(objField.val()); 860 861 //sets the condition: "==", ">", "<" ... 862 var visibilityCondition = getConditions(visibilityCondition, condition, objFieldValue, fieldValue); 863 864 //set the conditions: "&&", "||" 865 var visibilityOperator = getOperators(operator, visibilityOperator); 866 867 //if only one item exist - ignore the condition ("&&", "||") 868 if(i == 0) 869 totalVisibilityCondition = visibilityCondition; 870 871 if(i > 0) 872 totalVisibilityCondition += visibilityOperator + visibilityCondition; 873 874 //show error if condition name equals input field name 875 arrNames = getNames(arrNames, fieldName); 876 877 var objInputField = objFieldWidget.find(ueInputFieldSelector); 878 879 equalConditionInputNameError(objInputField, arrNames, classError); 880 881 } 882 883 var isInEditor = objField.data("editor"); 884 885 if(eval(totalVisibilityCondition) == true){ 886
887 showField(objFieldWidget, classHidden); 888 889 if(isInEditor == "yes") 890 setVisibilityInEditor(objFieldWidget, classError, classHidden); 891 892 } 893 894 if(eval(totalVisibilityCondition) == false){ 895 896 hideField(objFieldWidget, classHidden); 897 898 if(isInEditor == "yes") 899 setVisibilityInEditor(objFieldWidget, classError, classHidden); 900 901 } 902 903 //check if in formula exists invisible field 904 checkInvisibleInputsInFormula(); 905 906 } 907 908 /** 909 * init the form 910 */ 911 t.init = function(){ 912 913 //if no calc mode inpu found on page - do nothing 914 if(!g_objCalcInputs.length) 915 return(false); 916 917 //look after each calc mode input field on a page 918 g_objCalcInputs.each(function(){ 919 920 var objCalcInput = jQuery(this); 921 922 //find main warapper of the widget 923 var objCalcWidget = objCalcInput.parents(ueNumberSelector); 924 var objError = objCalcWidget.find(ueNumberErrorSelector); 925 926 //assign parent calc input number field widget for each ue field input that is inside formula of the number filed 927 assignParentNumberField(objCalcWidget, objError); 928 929 //set result in input 930 setResult(objCalcInput, objError); 931 932 //set result on custom shange event 933 objCalcInput.on('input_calc', function(){ 934 935 var objInput = jQuery(this); //triggered input 936 937 setResult(objInput, objError); 938 939 var objParentCalkInputs = getParentCalcInput(objInput); //parent calc input with formula attr 940 941 if(objParentCalkInputs != undefined){ 942 943 objParentCalkInputs.forEach(function(parent, index){ 944 945 var objParentError = parent.find(ueNumberErrorSelector); 946 947 setResult(parent, objParentError); 948 949 }); 950 951 } 952 953 954 }); 955 956 }); 957 958 //init events 959 var objAllInputFields = jQuery(ueInputFieldSelector); 960 961 //on input change trigger only parent calc number field, not all of them 962 objAllInputFields.on('input', function(){ 963 964 var objInput = jQuery(this); //triggered input 965 var objParentCalkInputs = getParentCalcInput(objInput); //parent calc input with formula attr 966 967 recalculateParentInputs(objParentCalkInputs); 968 969 }); 970 971 objAllInputFields.each(function(){ 972 973 var objInput = jQuery(this); //triggered input 974 var objParentCalkInputs = getParentCalcInput(objInput); //parent calc input with formula attr 975 var dataCalcMode = objInput.data("calc-mode"); 976 977 if(dataCalcMode === false) 978 return(true); 979 980 recalculateParentInputs(objParentCalkInputs); 981 982 }); 983 984 } 985 986 /** 987 * init vars 988 */ 989 function initVars(){ 990 991 //selector 992 ueInputFieldSelector = ".ue-input-field"; 993 ueNumberSelector = ".ue-number, .ue-content"; 994 ueNumberErrorSelector = ".ue-number-error"; 995 ueOptionFieldSelector = ".ue-option-field"; 996 997 //objects 998 g_objCalcInputs = jQuery(ueInputFieldSelector+'[data-calc-mode="true"]'); 999 1000 //helpers 1001 g_allowedSymbols = /Math\.[a-zA-Z]+|\d+(?:\.\d+)?|[-+*/().,]+/g; 1002 1003 } 1004 1005 initVars(); 1006 1007} 1008 1009var g_ucUnlimitedForms = new UnlimitedElementsForm(); 1010 1011g_ucUnlimitedForms.init(); 1012 1013jQuery( document ).on( 'elementor/popup/show', (event, id, objPopup) => { 1014 1015 var g_ucUnlimitedForms = new UnlimitedElementsForm(); 1016 1017 g_ucUnlimitedForms.init(); 1018 1019});
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.