1/* globals jQuery, SUPER, super_elements_i18n */ 2"use strict"; 3(function($) { // Hide scope, no $ conflict 4 // Switch between multiparts (prev/next or clicking on step) 5 SUPER.switchMultipart = function(e, target, dir){ 6 // First get active part 7 var i, index, validate, result, skip, progress, multipart, 8 form = target.closest('.super-form'), 9 stepParams = (form.dataset.stepParams ? form.dataset.stepParams : ''), // default 10 nodes = form.querySelectorAll('.super-multipart'), 11 steps = form.querySelectorAll('.super-multipart-step'), 12 formId = form.querySelector('input[name="hidden_form_id"]').value, 13 activeMultipart = form.querySelector('.super-multipart-step.super-active'), 14 children = Array.prototype.slice.call(activeMultipart.parentNode.children), 15 total = form.querySelectorAll('.super-multipart').length, 16 currentStep = children.indexOf(activeMultipart); 17 18 if(dir==='prev'){ 19 // From first to last? 20 if(currentStep===0){ 21 index = nodes.length-1; 22 }else{ 23 index = currentStep-1; 24 } 25 } 26 if(dir==='next'){ 27 // From last to first? 28 if(total===currentStep+1){ 29 index = 0; 30 }else{ 31 // @since 2.0.0 - validate multi-part before going to next step 32 validate = form.querySelector('.super-multipart.super-active').dataset.validate; 33 if(validate=='true'){ 34 result = SUPER.validate_form({el: target, form: form.querySelector('.super-multipart.super-active'), submitButton: target, validateMultipart: true, event: e}); 35 if(result!==true) return false; 36 } 37 index = currentStep+1; 38 } 39 } 40 for( i = 0; i < nodes.length; i++){ 41 nodes[i].classList.remove('super-active'); 42 steps[i].classList.remove('super-active'); 43 if(i===index){ 44 nodes[i].classList.add('super-active'); 45 steps[i].classList.add('super-active'); 46 } 47 } 48 49 // Required for toggle field and other possible elements to rerender proper size 50 SUPER.init_super_responsive_form_fields({form: form}); 51 52 // Update URL parameters 53 if(stepParams!=='false'){ 54 window.location.hash = 'step-'+formId+'-'+(parseInt(index,10)+1); 55 } 56 57 // Make sure to skip the multi-part if no visible elements are found 58 skip = SUPER.skipMultipart(target, form); 59 if(skip===true) return false; 60 61 // Update progress bar 62 progress = 100 / total; 63 progress = progress * (index+1); 64 form.querySelector('.super-multipart-progress-bar').style.width = progress+'%'; 65 index = 0; 66 67 nodes = form.querySelectorAll('.super-multipart'); 68 for( i = 0; i < nodes.length; i++){ 69 if(!nodes[i].querySelector('.super-error-active')){ 70 form.querySelectorAll('.super-multipart-steps .super-multipart-step')[index].classList.remove('super-error'); 71 } 72 index++; 73 } 74 // Disable scrolling for multi-part prev/next 75 multipart = form.querySelector('.super-multipart.super-active'); 76 if(typeof multipart.dataset.disableScrollPn === 'undefined'){ 77 if(e && !e.shiftKey){ 78 if(form.closest('.super-popup-content')){ 79 $(form.closest('.super-popup-content')).animate({ 80 scrollTop: $(form).offset().top - 30 81 }, 500); 82 }else{ 83 $('html, body').animate({ 84 scrollTop: $(form).offset().top - 30 85 }, 500); 86 } 87 } 88 } 89 // Focus first TAB index field in next multi-part 90 SUPER.focusFirstTabIndexField(e, form, multipart); 91 92 }; 93 // Make sure to skip the multi-part if no visible elements are found 94 SUPER.skipMultipart = function(el, form, index, activeIndex){ 95 var i, nodes, multipart, field, skip = true; 96 97 nodes = form.querySelectorAll('.super-multipart.super-active .super-field:not(.super-button)'); 98 for( i = 0; i < nodes.length; i++ ) { 99 field = nodes[i].querySelector('.super-shortcode-field'); 100 if(field){ // This is a field 101 if(!SUPER.has_hidden_parent(field)) skip = false; 102 }else{ // This is either a HTML element or something else without a field
103 if(!SUPER.has_hidden_parent(nodes[i])) skip = false; 104 } 105 if(skip===false) return false; 106 } 107 if(skip){ // Only skip if no visible fields where to be found 108 multipart = form.querySelector('.super-multipart.super-active'); 109 if( (el.classList.contains('super-prev-multipart')) || (el.classList.contains('super-next-multipart')) ){ 110 if(el.classList.contains('super-prev-multipart')){ 111 if(multipart.querySelector('.super-prev-multipart')) multipart.querySelector('.super-prev-multipart').click(); 112 }else{ 113 if(multipart.querySelector('.super-next-multipart')) multipart.querySelector('.super-next-multipart').click(); 114 } 115 }else{ 116 if(index < activeIndex){ 117 if(multipart.querySelector('.super-prev-multipart')) multipart.querySelector('.super-prev-multipart').click(); 118 }else{ 119 if(multipart.querySelector('.super-next-multipart')) multipart.querySelector('.super-next-multipart').click(); 120 } 121 } 122 } 123 return skip; 124 }; 125 SUPER.focusFirstTabIndexField = function(e, form, multipart) { 126 var fields,highestIndex,lowestIndex,index,next, disableAutofocus = multipart.dataset.disableAutofocus; 127 128 if( typeof disableAutofocus === 'undefined' ) { 129 fields = $(multipart).find('.super-field:not('+super_elements_i18n.tab_index_exclusion+')[data-super-tab-index]'); 130 highestIndex = 0; 131 fields.each(function(){ 132 index = parseFloat($(this).attr('data-super-tab-index')); 133 if( index > highestIndex ) { 134 highestIndex = index; 135 } 136 }); 137 lowestIndex = highestIndex; 138 fields.each(function(){ 139 index = parseFloat($(this).attr('data-super-tab-index')); 140 if( index < lowestIndex ) { 141 lowestIndex = index; 142 } 143 }); 144 next = $(multipart).find('.super-field:not('+super_elements_i18n.tab_index_exclusion+')[data-super-tab-index="'+lowestIndex+'"]'); 145 SUPER.focusNextTabField(e, next[0], form, next[0]); 146 } 147 }; 148 149 // @since 3.2.0 - function to return next field based on TAB index 150 SUPER.nextTabField = function(e, field, form, nextTabIndex){ 151 if(!field) return false; 152 var nextTabIndexSmallIncrement, 153 nextField, 154 nextFieldSmallIncrement, 155 nextCustomField, 156 customTabIndex, 157 incNext = 1, 158 incNextSmall = 0.001; 159 160 if(e.shiftKey){ 161 incNext = -incNext; 162 incNextSmall = -incNextSmall; 163 } 164 if(typeof nextTabIndex === 'undefined'){ 165 nextTabIndexSmallIncrement = parseFloat(parseFloat(field.dataset.superTabIndex)+incNextSmall).toFixed(3); 166 nextTabIndex = parseFloat(field.dataset.superTabIndex)+incNext; 167 } 168 if(typeof field.dataset.superCustomTabIndex !== 'undefined'){ 169 nextTabIndex = parseFloat(field.dataset.superCustomTabIndex)+incNext; 170 } 171 172 nextTabIndexSmallIncrement = parseFloat(nextTabIndexSmallIncrement); 173 nextTabIndex = parseFloat(parseFloat(nextTabIndex).toFixed(0)); 174 nextFieldSmallIncrement = form.querySelector('.super-field[data-super-tab-index="'+nextTabIndexSmallIncrement+'"]'); 175 if(nextFieldSmallIncrement){ 176 nextField = nextFieldSmallIncrement; 177 }else{ 178 nextField = form.querySelector('.super-field[data-super-tab-index="'+nextTabIndex+'"]'); 179 } 180 nextCustomField = form.querySelector('.super-field[data-super-custom-tab-index="'+nextTabIndex+'"]'); 181 182 // If custom index TAB field was found, and is not currently focussed 183 if( (nextCustomField) && (!nextCustomField.classList.contains('super-focus')) ) { 184 nextField = nextCustomField; 185 } 186 187 if(!nextField) return false; 188 189 if(nextField.dataset.superCustomTabIndex){ 190 customTabIndex = nextField.dataset.superCustomTabIndex; 191 if(typeof customTabIndex !== 'undefined') { 192 if(nextTabIndex < parseFloat(customTabIndex)){ 193 nextField = SUPER.nextTabField(e, field, form, nextTabIndex+incNext); 194 } 195 } 196 } 197 if(SUPER.has_hidden_parent(nextField)){ 198 // Exclude conditionally 199 nextField = SUPER.nextTabField(e, field, form, nextTabIndex+incNext); 200 } 201 return nextField; 202 }; 203 204 SUPER.init_adaptive_placeholder = function(){ 205 var nodes = document.querySelectorAll('.super-adaptive-placeholder'); 206 for (var i = 0; i < nodes.length; i++) { 207 var input = nodes[i].parentNode.querySelector('.super-shortcode-field'); 208 if(!input) continue; 209 210 input.onclick = input.onfocus = function () { 211 } 212 input.onblur = function () { 213 } 214 input.addEventListener('keyup', function () { 215 var wrapper = this.closest('.super-field-wrapper'); 216 var placeholder = wrapper.querySelector('.super-adaptive-placeholder'); 217 var span = placeholder.children[0]; 218 var filled = true, 219 parent = this.closest('.super-field'); 220 if(parent.classList.contains('super-currency')){ 221 if($(this).maskMoney('unmasked')[0]===0){ 222 filled = false; 223 } 224 } 225 if (this.value.length === 0) filled = false; 226 if(filled){ 227 parent.classList.add('super-filled'); 228 span.innerHTML = placeholder.dataset.placeholderfilled; 229 }else{ 230 parent.classList.remove('super-filled'); 231 span.innerHTML = placeholder.dataset.placeholder; 232 } 233 }); 234 input.oncut = input.onpaste = function (event) { 235 var wrapper = this.closest('.super-field-wrapper'); 236 var placeholder = wrapper.querySelector('.super-adaptive-placeholder'); 237 var span = placeholder.children[0]; 238 var filled = true, 239 input = event.target, 240 parent = event.target.closest('.super-field'); 241 242 if(parent.classList.contains('super-currency')){ 243 if($(input).maskMoney('unmasked')[0]===0){ 244 filled = false; 245 } 246 } 247 if (event.type == 'cut' || event.type == 'paste') { 248 setTimeout(function () { 249 if (input.value.length === 0) filled = false; 250 if(filled){ 251 parent.classList.add('super-filled'); 252 span.innerHTML = placeholder.dataset.placeholderfilled; 253 }else{ 254 parent.classList.remove('super-filled'); 255 span.innerHTML = placeholder.dataset.placeholder; 256 } 257 }, 100); 258 } 259 } 260 } 261 }; 262 263 // @since 1.3 - input mask 264 SUPER.init_masked_input = function(){ 265 $('.super-shortcode-field[data-mask]').each(function(){ 266 $(this).mask($(this).data('mask')); 267 }); 268 }; 269 270 // @since 2.1.0 - currency field 271 SUPER.init_currency_input = function(){ 272 $('.super-currency .super-shortcode-field').each(function(){ 273 var $currency = $(this).data('currency'); 274 var $format = $(this).data('format'); 275 var $decimals = $(this).data('decimals'); 276 var $thousand_separator = $(this).data('thousand-separator'); 277 var $decimal_seperator = $(this).data('decimal-separator'); 278 $(this).maskMoney({ 279 prefix: $currency, 280 suffix: $format, 281 affixesStay: true, 282 allowNegative: true,
283 thousands: $thousand_separator, 284 decimal: $decimal_seperator, 285 precision: $decimals 286 }); 287 if(this.dataset.defaultValue!==''){ 288 $(this).maskMoney('mask', this.dataset.defaultValue); 289 $(this).parents('.super-currency').addClass('super-filled'); 290 }else{ 291 $(this).parents('.super-currency').removeClass('super-filled'); 292 } 293 }); 294 }; 295 296 // @since 2.0 - initialize color picker(s) 297 SUPER.init_colorpicker = function(){ 298 $('.super-color .super-shortcode-field').each(function(){ 299 if(typeof $.fn.spectrum === "function") { 300 if(!$(this).hasClass('super-picker-initialized')){ 301 var $value = $(this).val(); 302 if($value==='') $value = '#FFFFFF'; 303 $(this).spectrum({ 304 containerClassName: 'super-forms', 305 replacerClassName: 'super-forms', 306 color: $value, 307 preferredFormat: "hex", 308 showInput: true, 309 chooseText: "Accept", 310 cancelText: "Cancel", 311 change: function(color) { 312 this.value = color.toHexString(); 313 }, 314 move: function(color) { 315 this.value = color.toHexString(); 316 }, 317 beforeShow: function(){ 318 SUPER.focusForm(this); 319 SUPER.focusField(this); 320 } 321 }).addClass('super-picker-initialized'); 322 } 323 } 324 }); 325 }; 326 327 // @since 2.0 - calculate age in years, months and days 328 SUPER.init_datepicker_get_age = function(dateString, return_value){ 329 var now = new Date(), 330 yearNow = now.getYear(), 331 monthNow = now.getMonth(), 332 dateNow = now.getDate(), 333 dob = new Date(dateString.substring(6,10), dateString.substring(0,2)-1, dateString.substring(3,5)), 334 yearDob = dob.getYear(), 335 monthDob = dob.getMonth(), 336 dateDob = dob.getDate(), 337 age = {}, 338 yearAge = yearNow - yearDob, 339 monthAge, 340 dateAge; 341 if(monthNow >= monthDob){ 342 monthAge = monthNow - monthDob; 343 }else{ 344 yearAge--; 345 monthAge = 12 + monthNow -monthDob; 346 } 347 if(dateNow >= dateDob){ 348 dateAge = dateNow - dateDob; 349 }else{ 350 monthAge--; 351 dateAge = 31 + dateNow - dateDob; 352 if (monthAge < 0) { 353 monthAge = 11; 354 yearAge--; 355 } 356 } 357 age = { 358 years: yearAge, 359 months: monthAge, 360 days: dateAge 361 }; 362 if(return_value=='years'){ 363 return age.years; 364 } 365 if(return_value=='months'){ 366 return age.months; 367 } 368 if(return_value=='days'){ 369 return age.days; 370 } 371 }; 372 373 // init connected datepickers 374 SUPER.init_connected_datepicker = function($this, selectedDate, $parse_format, oneDay, skipFieldChangeForElement){ 375 if(selectedDate===''){ 376 $this.closest('.super-field').classList.remove('super-filled'); 377 }else{ 378 $this.closest('.super-field').classList.add('super-filled'); 379 } 380 381 var original_selectedDate = selectedDate, 382 $format = $this.dataset.jsformat, 383 d, 384 year,month,day, 385 firstDate, 386 $connected_min, 387 $connected_date, 388 $connected_min_days, 389 min_date, 390 $parse, 391 $connected_max, 392 $connected_max_days, 393 max_date; 394 395 if(original_selectedDate!==''){ 396 d = Date.parseExact(original_selectedDate, $parse_format); 397 if(d!==null){ 398 year = d.toString('yyyy');
399 month = d.toString('MM'); 400 day = d.toString('dd'); 401 $this.dataset.mathYear = year; 402 $this.dataset.mathMonth = month; 403 $this.dataset.mathDay = day; 404 firstDate = new Date(Date.UTC(year, month-1, day)); 405 $this.dataset.mathDiff = firstDate.getTime(); 406 $this.dataset.mathAge = SUPER.init_datepicker_get_age(month+'/'+day+'/'+year, 'years'); 407 $this.dataset.mathAgeMonths = SUPER.init_datepicker_get_age(month+'/'+day+'/'+year, 'months'); 408 $this.dataset.mathAgeDays = SUPER.init_datepicker_get_age(month+'/'+day+'/'+year, 'days'); 409 $connected_min = $this.dataset.connectedMin; 410 if( typeof $connected_min !== 'undefined' ) { 411 if( $connected_min!=='' ) { 412 $connected_date = document.querySelector('.super-shortcode-field.super-datepicker[name="'+$connected_min+'"]'); 413 if($connected_date){ 414 $format = $connected_date.dataset.jsformat; 415 $connected_min_days = parseInt($this.dataset.connectedMinDays, 10); 416 min_date = Date.parseExact(original_selectedDate, $parse_format).add({ days: $connected_min_days }).toString($format); 417 $($connected_date).datepicker('option', 'minDate', min_date ); 418 var maxPicks =($this.dataset.maxpicks ? parseInt($this.dataset.maxpicks, 10) : 1); 419 if(maxPicks<=1){ 420 if($connected_date.value===''){ 421 $connected_date.value = min_date; 422 } 423 if($connected_date.value===''){ 424 $connected_date.closest('.super-field').classList.remove('super-filled'); 425 }else{ 426 $connected_date.closest('.super-field').classList.add('super-filled'); 427 } 428 $parse = Date.parseExact($connected_date.value, $parse_format); 429 if($parse!==null){ 430 selectedDate = $parse.toString($format); 431 d = Date.parseExact(selectedDate, $format); 432 year = d.toString('yyyy'); 433 month = d.toString('MM'); 434 day = d.toString('dd'); 435 selectedDate = new Date(Date.UTC(year, month-1, day)); 436 $connected_date.dataset.mathDiff = selectedDate.getTime(); 437 SUPER.init_connected_datepicker($connected_date, $connected_date.value, $parse_format, oneDay); 438 } 439 } 440 } 441 } 442 } 443 $connected_max = $this.dataset.connectedMax; 444 if(typeof $connected_max !== 'undefined'){ 445 if( $connected_max!=='' ) { 446 $connected_date = document.querySelector('.super-shortcode-field.super-datepicker[name="'+$connected_max+'"]'); 447 if($connected_date){ 448 $format = $connected_date.dataset.jsformat; 449 $connected_max_days = parseInt($this.dataset.connectedMaxDays, 10); 450 max_date = Date.parseExact(original_selectedDate, $parse_format).add({ days: $connected_max_days }).toString($format); 451 $($connected_date).datepicker('option', 'maxDate', max_date ); 452 if($connected_date.value===''){ 453 $connected_date.value = max_date; 454 } 455 if($connected_date.value===''){ 456 $connected_date.closest('.super-field').classList.remove('super-filled'); 457 }else{ 458 $connected_date.closest('.super-field').classList.add('super-filled'); 459 } 460 $parse = Date.parseExact($connected_date.value, $parse_format); 461 if($parse!==null){ 462 selectedDate = $parse.toString($format); 463 d = Date.parseExact(selectedDate, $format); 464 year = d.toString('yyyy');
465 month = d.toString('MM'); 466 day = d.toString('dd'); 467 selectedDate = new Date(Date.UTC(year, month-1, day)); 468 $connected_date.dataset.mathDiff = selectedDate.getTime(); 469 SUPER.init_connected_datepicker($connected_date, $connected_date.value, $parse_format, oneDay); 470 } 471 } 472 } 473 } 474 } 475 } 476 SUPER.after_field_change_blur_hook({el: $this}); 477 }; 478 479 // init Datepicker 480 SUPER.init_datepicker = function(skipFieldChangeForElement){ 481 if(typeof skipFieldChangeForElement === 'undefined') skipFieldChangeForElement = '' 482 var i; 483 484 // Init datepickers 485 var oneDay = 24*60*60*1000, // hours*minutes*seconds*milliseconds 486 nodes = document.querySelectorAll('.super-datepicker'); 487 488 for (i = 0; i < nodes.length; ++i) { 489 if(typeof datepicker === "function"){ 490 $(nodes[i]).datepicker('destroy'); 491 } 492 } 493 494 nodes = document.querySelectorAll('.super-datepicker:not(.super-picker-initialized)'); 495 for (i = 0; i < nodes.length; ++i) { 496 var el = nodes[i], 497 form = SUPER.get_frontend_or_backend_form({el: el}), 498 format = el.dataset.format, //'MM/dd/yyyy'; 499 jsformat = el.dataset.jsformat, //'MM/dd/yyyy'; 500 isRTL = (el.closest('.super-form') ? el.closest('.super-form').classList.contains('super-rtl') : false), 501 min = el.dataset.minlength, 502 max = el.dataset.maxlength, 503 workDays, 504 weekends, 505 regex = /{([^\\\/\s"'+]*?)}/g, 506 range = el.dataset.range, 507 maxPicks =(el.dataset.maxpicks ? parseInt(el.dataset.maxpicks, 10) : 1), 508 firstDay = el.dataset.firstDay, 509 localization = el.dataset.localization, 510 widget,connectedMinDays,minDate,connectedMaxDays,maxDate, 511 parse,year,month,firstDate,$date,days,found,date,fullDate,dateFrom, 512 dateTo,d1,d2,from,to,check,day,exclDays,exclDaysOverride,exclDaysOverrideReplaced,exclDates,exclDatesReplaced, 513 changeMonth =(el.dataset.changeMonth==='true' ? true : false), 514 changeYear =(el.dataset.changeYear==='true' ? true : false), 515 showMonthAfterYear = (el.dataset.showMonthAfterYear==='true' ? true : false), 516 showWeek = (el.dataset.showWeek==='true' ? true : false), 517 numberOfMonths = parseInt(el.dataset.numberOfMonths, 10), 518 showOtherMonths = (el.dataset.showOtherMonths==='true' ? true : false), 519 selectOtherMonths = (el.dataset.selectOtherMonths==='true' ? true : false), 520 521 // @since 2.5.0 - Date.parseExact compatibility 522 parseFormat = [ 523 jsformat 524 ]; 525 526 // If localization is being used, use this date format instead 527 // Make sure to convert to correct format before using, plus update data attribute 528 if(localization!==''){ 529 if(typeof $.datepicker.regional[localization] !== 'undefined'){ 530 format = $.datepicker.regional[localization].dateFormat; 531 jsformat = format; 532 jsformat = jsformat.replace('DD', 'dddd'); 533 regex = /MM/i; 534 if(regex.test(jsformat)){ 535 jsformat = jsformat.replace('MM', 'MMMM'); 536 }else{ 537 regex = /M/i; 538 if(regex.test(jsformat)){ 539 jsformat = jsformat.replace('M', 'MMM'); 540 } 541 } 542 jsformat = jsformat.replace('mm', 'MM'); 543 regex = /yy/i; 544 if(regex.test(jsformat)){ 545 jsformat = jsformat.replace('yy', 'yyyy'); 546 }else{ 547 regex = /y/i; 548 if(regex.test(jsformat)){ 549 jsformat = jsformat.replace('y', 'yy'); 550 } 551 } 552 parseFormat = [ 553 jsformat 554 ]; 555 el.dataset.format = format; 556 el.dataset.jsformat = jsformat; 557 } 558 } 559 560 // Check if range is valid value, if not set to default one 561 if(range.indexOf(':')===-1){ 562 range = '-100:+5'; 563 } 564 565 // yy = short year 566 // yyyy = long year 567 // M = month (1-12) 568 // MM = month (01-12) 569 // MMM = month abbreviation (Jan, Feb ... Dec) 570 // MMMM = long month (January, February ... December) 571 // d = day (1 - 31) 572 // dd = day (01 - 31) 573 // ddd = day of the week in words (Monday, Tuesday ... Sunday) 574 // E = short day of the week in words (Mon, Tue ... Sun) 575 // D - Ordinal day (1st, 2nd, 3rd, 21st, 22nd, 23rd, 31st, 4th...) 576 // h = hour in am/pm (0-12) 577 // hh = hour in am/pm (00-12) 578 // H = hour in day (0-23) 579 // HH = hour in day (00-23) 580 // mm = minute 581 // ss = second 582 // SSS = milliseconds 583 // a = AM/PM marker 584 // p = a.m./p.m. marker 585 586 if(typeof min !== 'undefined') min = min.toString(); 587 if(typeof max !== 'undefined') max = max.toString(); 588 589 el.classList.add('super-picker-initialized'); 590 if( el.value!=='' ) { 591 parse = Date.parseExact(el.value, parseFormat); 592 if( parse!==null ) { 593 year = parse.toString('yyyy');
594 month = parse.toString('MM'); 595 day = parse.toString('dd'); 596 el.dataset.mathYear = year; 597 el.dataset.mathMonth = month; 598 el.dataset.mathDay = day; 599 firstDate = new Date(Date.UTC(year, month-1, day)); 600 el.dataset.mathDiff = firstDate.getTime(); 601 el.dataset.mathAge = SUPER.init_datepicker_get_age(month+'/'+day+'/'+year, 'years'); 602 el.dataset.mathAgeMonths = SUPER.init_datepicker_get_age(month+'/'+day+'/'+year, 'months'); 603 el.dataset.mathAgeDays = SUPER.init_datepicker_get_age(month+'/'+day+'/'+year, 'days'); 604 $date = Date.parseExact(day+'-'+month+'-'+year, parseFormat); 605 if($date!==null){ 606 $date = $date.toString("dd-MM-yyyy"); 607 SUPER.init_connected_datepicker(el, $date, parseFormat, oneDay, skipFieldChangeForElement); 608 } 609 } 610 }else{ 611 el.dataset.mathYear = '0'; 612 el.dataset.mathMonth = '0'; 613 el.dataset.mathDay = '0'; 614 el.dataset.mathDiff = '0'; 615 el.dataset.mathAge = '0'; 616 } 617 618 var multiDatesClassName = 'super-datepicker-multidates', 619 singleDatesClassName = 'super-datepicker-singledates'; 620 var options = { 621 onClose: function( selectedDate ) { 622 SUPER.init_connected_datepicker(this, selectedDate, parseFormat, oneDay, skipFieldChangeForElement); 623 }, 624 beforeShowDay: function(dt) { 625 workDays = (this.dataset.workDays == 'true'); 626 weekends = (this.dataset.weekends == 'true'); 627 day = dt.getDay(); 628 exclDays = this.dataset.exclDays; 629 exclDates = (typeof this.dataset.exclDates !=='undefined' ? this.dataset.exclDates : undefined); 630 exclDaysOverride = this.dataset.exclDaysOverride; 631 exclDaysOverride = (typeof this.dataset.exclDaysOverride !=='undefined' ? this.dataset.exclDaysOverride : undefined); 632 633 if(typeof exclDays !== 'undefined'){ 634 days = exclDays.split(','); 635 found = (days.indexOf(day.toString()) > -1); 636 if(found){ 637 if(typeof exclDaysOverride !== 'undefined'){ 638 regex = /{([^\\\/\s"'+]*?)}/g; 639 exclDaysOverrideReplaced = SUPER.update_variable_fields.replace_tags({form: form, regex: regex, value: exclDaysOverride}); 640 exclDaysOverrideReplaced = exclDaysOverrideReplaced.split("\n"); 641 date = ('0' + dt.getDate()).slice(-2); 642 month = ('0' + (dt.getMonth()+1)).slice(-2); 643 fullDate = dt.getFullYear() + '-' + month + '-' + date; 644 var x; 645 for( x=0; x < exclDaysOverrideReplaced.length; x++ ) { 646 if(exclDaysOverrideReplaced[x]==='') continue; 647 // If excluding a fixed day of month 648 if(exclDaysOverrideReplaced[x].length<=2){ 649 if(exclDaysOverrideReplaced[x]==day){ 650 return [true, ""]; 651 } 652 } 653 // If excluding a specific month 654 if(exclDaysOverrideReplaced[x].length===3){ 655 if(exclDaysOverrideReplaced[x].toLowerCase()==dt.toString('MMM').toLowerCase()){ 656 return [true, ""]; 657 } 658 } 659 // If excluding a date range 660 if(exclDaysOverrideReplaced[x].split(';').length>1){ 661 dateFrom = exclDaysOverrideReplaced[x].split(';')[0]; 662 dateTo = exclDaysOverrideReplaced[x].split(';')[1]; 663 d1 = dateFrom.split("-"); 664 d2 = dateTo.split("-"); 665 from = new Date(d1[0], parseInt(d1[1], 10)-1, d1[2]); // -1 because months are from 0 to 11 666 to = new Date(d2[0], parseInt(d2[1], 10)-1, d2[2]); 667 check = new Date(dt.getFullYear(), parseInt(month, 10)-1, date); 668 if(check >= from && check <= to){ 669 return [true, ""]; 670 } 671 } 672 // If excluding single date 673 if(exclDaysOverrideReplaced[x]==fullDate){ 674 return [true, ""]; 675 } 676 } 677 // Be default we disable this day 678 return [false, "super-disabled-day"]; 679 }else{ 680 return [false, "super-disabled-day"]; 681 } 682 } 683 } 684 if(typeof exclDates !== 'undefined'){ 685 regex = /{([^\\\/\s"'+]*?)}/g; 686 exclDatesReplaced = SUPER.update_variable_fields.replace_tags({form: form, regex: regex, value: exclDates}); 687 exclDatesReplaced = exclDatesReplaced.split("\n"); 688 date = ('0' + dt.getDate()).slice(-2);
689 month = ('0' + (dt.getMonth()+1)).slice(-2); 690 fullDate = dt.getFullYear() + '-' + month + '-' + date; 691 var y; 692 for( y=0; y < exclDatesReplaced.length; y++ ) { 693 if(exclDatesReplaced[y]==='') continue; 694 // If excluding a fixed day of month 695 if(exclDatesReplaced[y].length<=2){ 696 if(exclDatesReplaced[y]==day){ 697 return [false, "super-disabled-day"]; 698 } 699 } 700 // If excluding a specific month 701 if(exclDatesReplaced[y].length===3){ 702 if(exclDatesReplaced[y].toLowerCase()==dt.toString('MMM').toLowerCase()){ 703 return [false, "super-disabled-day"]; 704 } 705 } 706 // If excluding a date range 707 if(exclDatesReplaced[y].split(';').length>1){ 708 dateFrom = exclDatesReplaced[y].split(';')[0]; 709 dateTo = exclDatesReplaced[y].split(';')[1]; 710 d1 = dateFrom.split("-"); 711 d2 = dateTo.split("-"); 712 from = new Date(d1[0], parseInt(d1[1], 10)-1, d1[2]); // -1 because months are from 0 to 11 713 to = new Date(d2[0], parseInt(d2[1], 10)-1, d2[2]); 714 check = new Date(dt.getFullYear(), parseInt(month, 10)-1, date); 715 if(check >= from && check <= to){ 716 return [false, "super-disabled-day"]; 717 } 718 } 719 // If excluding single date 720 if(exclDatesReplaced[y]==fullDate){ 721 return [false, "super-disabled-day"]; 722 } 723 } 724 } 725 if( (weekends===true) && (workDays===true) ) { 726 return [true, ""]; 727 }else{ 728 if(weekends===true){ 729 return [day === 0 || day == 6, ""]; 730 } 731 if(workDays===true){ 732 return [day == 1 || day == 2 || day == 3 || day == 4 || day == 5, ""]; 733 } 734 } 735 return []; 736 }, 737 beforeShow: function(input, inst) { 738 var maxPicks = (inst.settings.maxPicks ? inst.settings.maxPicks : 1); 739 widget = $(inst).datepicker('widget'); 740 widget[0].classList.add('super-datepicker-dialog'); 741 if(maxPicks<=1){ 742 widget[0].classList.remove(multiDatesClassName); 743 widget[0].classList.add(singleDatesClassName); 744 $('.super-datepicker[data-connected-min="'+$(this).attr('name')+'"]').each(function(){ 745 if($(this).val()!==''){ 746 connectedMinDays = $(this).data('connected-min-days'); 747 minDate = Date.parseExact($(this).val(), parseFormat).add({ days: connectedMinDays }).toString(jsformat); 748 $(el).datepicker('option', 'minDate', minDate ); 749 } 750 }); 751 }else{ 752 widget[0].classList.add(multiDatesClassName); 753 widget[0].classList.remove(singleDatesClassName); 754 } 755 $('.super-datepicker[data-connected-max="'+$(this).attr('name')+'"]').each(function(){ 756 if($(this).val()!==''){ 757 connectedMaxDays = $(this).data('connected-max-days'); 758 maxDate = Date.parseExact($(this).val(), parseFormat).add({ days: connectedMaxDays }).toString(jsformat); 759 $(el).datepicker('option', 'maxDate', maxDate ); 760 } 761 }); 762 }, 763 yearRange: range, //'-100:+5', // specifying a hard coded year range
764 showAnim: '', 765 showOn: $(this).parent().find('.super-icon'), 766 minDate: min, 767 maxDate: max, 768 dateFormat: format, //mm/dd/yy - yy-mm-dd - d M, y - d MM, y - DD, d MM, yy - 'day' d 'of' MM 'in the year' yy 769 firstDay: firstDay, 770 isRTL: isRTL, 771 closeText: super_elements_i18n.closeText, 772 prevText: super_elements_i18n.prevText, 773 nextText: super_elements_i18n.nextText, 774 currentText: super_elements_i18n.currentText, 775 monthNames: super_elements_i18n.monthNames, // set month names 776 monthNamesShort: super_elements_i18n.monthNamesShort, // set short month names 777 dayNames: super_elements_i18n.dayNames, // set days names 778 dayNamesShort: super_elements_i18n.dayNamesShort, // set short day names 779 dayNamesMin: super_elements_i18n.dayNamesMin, // set more short days names 780 weekHeader: super_elements_i18n.weekHeader, 781 changeMonth: changeMonth, 782 changeYear: changeYear, 783 showMonthAfterYear: showMonthAfterYear, 784 showWeek: showWeek, 785 numberOfMonths: numberOfMonths, 786 yearSuffix: '', 787 showOtherMonths: showOtherMonths, 788 selectOtherMonths: selectOtherMonths 789 }; 790 791 // Do a try catch because otherwise user might be locked out from the builder page if they made a mistake in entering for instance the "range" (yearRange) 792 try { 793 if(maxPicks>1){ 794 options.maxPicks = maxPicks; 795 $(el).multiDatesPicker(options); 796 // @since 4.9.583 - Fixes issue where the month would change back to January after selecting a second date or more 797 $.datepicker._selectDateOverload = $.datepicker._selectDate; 798 $.datepicker._selectDate = function (id, dateStr) { 799 var target = $(id); 800 var inst = this._getInst(target[0]); 801 inst.inline = true; 802 $.datepicker._selectDateOverload(id, dateStr); 803 inst.inline = false; 804 if (target[0].multiDatesPicker != null) { 805 target[0].multiDatesPicker.changed = false; 806 } else { 807 target.multiDatesPicker.changed = false; 808 } 809 this._updateDatepicker(inst); 810 // Close datepicker if it isn't a so called Multi-datepicker, or when maxPicks is set to 1 811 if(typeof inst.settings.maxPicks==='undefined' || inst.settings.maxPicks<=1 ){ 812 $(target).datepicker('hide'); 813 } 814 }; 815 }else{ 816 $(el).datepicker(options); 817 } 818 if(typeof min !== 'undefined'){ 819 $(el).datepicker('option', 'minDate', min ); 820 } 821 822 // @since 4.9.3 - Datepicker localization (language and format) 823 if(localization!==''){ 824 if(typeof $.datepicker.regional[localization] !== 'undefined'){ 825 $.datepicker.regional[localization].yearSuffix = ''; 826 $(el).datepicker( "option", $.datepicker.regional[localization] ); 827 } 828 } 829 } catch (error) { 830 // eslint-disable-next-line no-console 831 console.log(error); 832 alert(error); 833 } 834 835 $(el).parent().find('.super-icon').css('cursor','pointer'); 836 } 837 $('.super-datepicker').parent().find('.super-icon').on('click',function(){ 838 $(this).parent().find('.super-datepicker').datepicker('show'); 839 }); 840 $('.super-datepicker').on('click focus',function(){ 841 if($('.super-timepicker').length){ 842 $('.super-timepicker').timepicker('hide'); 843 } 844 $(this).datepicker('show'); 845 }); 846 847 848 function set_timepicker_dif($this){ 849 var $value = $this.val(), 850 hours,minutes,AMPM,sHours,sMinutes, 851 $h,$m,$s,today,dd,mm,yyyy,d,$timestamp; 852 853 // @since 3.4.0 - If Ante/Post meridiem 12 hour format make sure to convert it to 24 hour format 854 if( $this.data('format')=='h:i A' ) { 855 if($value==='') $value = '12:00 AM'; 856 hours = Number($value.match(/^(\d+)/)[1]); 857 minutes = Number($value.match(/:(\d+)/)[1]); 858 AMPM = $value.match(/\s(.*)$/)[1]; 859 if(AMPM == 'PM' && hours<12) hours = hours+12; 860 if(AMPM == 'AM' && hours==12) hours = hours-12; 861 sHours = hours.toString(); 862 sMinutes = minutes.toString(); 863 if( hours<10 ) sHours = '0' + sHours; 864 if( minutes<10 ) sMinutes = '0' + sMinutes; 865 $value = sHours + ':' + sMinutes; 866 } 867 868 $value = $value.split(':'); 869 if(typeof $value[0] === 'undefined') $value[0] = '00'; 870 if(typeof $value[1] === 'undefined') $value[1] = '00'; 871 $h = $value[0]; 872 $m = $value[1].split(' '); 873 $m = $m[0];
874 if(typeof $value[2] === 'undefined'){ 875 $s = '00'; 876 }else{ 877 $s = $value[2]; 878 } 879 today = new Date(); 880 dd = today.getDate(); 881 mm = today.getMonth(); 882 yyyy = today.getFullYear(); 883 d = new Date(Date.UTC(yyyy, mm, dd, $h, $m, $s)); 884 $timestamp = d.getTime(); 885 $this[0].dataset.mathDiff = $timestamp; 886 SUPER.after_field_change_blur_hook({el: $this[0]}); 887 } 888 889 // Init timepickers 890 $('.super-timepicker:not(.ui-timepicker-input)').each(function(){ 891 // Only if timepicker is a function 892 if (typeof $.fn.timepicker !== 'function') return false; 893 var $this = $(this), 894 form = SUPER.get_frontend_or_backend_form({el: this}), 895 regex = /{([^\\\/\s"'+]*?)}/g, 896 $is_rtl = form.classList.contains('super-rtl'), 897 $orientation = 'l', 898 format = $this.data('format'), 899 step = $this.data('step'), 900 range = $this.data('range'), 901 min = $this.data('minlength'), 902 max = $this.data('maxlength'), 903 duration = $this.data('duration'), 904 finalrange = [], 905 $form_id, 906 $form_size; 907 908 if(min==='') min = '00:00'; 909 if(max==='') max = '23:59'; 910 if(typeof min !== 'undefined') { 911 min = min.toString(); 912 min = SUPER.update_variable_fields.replace_tags({form: form, regex: regex, value: min}); 913 if(min.indexOf(':')===-1){ 914 if(min !== parseInt(min, 10)){ 915 min = parseInt(min, 10); 916 var prevMin = min - (min % (step*60)); 917 min = prevMin + 1800; 918 } 919 } 920 } 921 if(typeof max !== 'undefined') { 922 max = max.toString(); 923 max = SUPER.update_variable_fields.replace_tags({form: form, regex: regex, value: max}); 924 if(max.indexOf(':')===-1){ 925 if(max !== parseInt(max, 10)){ 926 max = parseInt(max, 10); 927 var prevMax = max - (max % (step*60)); 928 max = prevMax + 1800; 929 } 930 } 931 } 932 if((range!=='') && (typeof range !== 'undefined')){ 933 range = range.split('\n'); 934 $.each(range, function(key, value ) { 935 finalrange.push(value.split('|')); 936 }); 937 } 938 $form_id = form.id; 939 $form_size = form.dataset.fieldSize; 940 if($is_rtl===true){ 941 $orientation = 'r'; 942 } 943 944 945 $this.timepicker({ 946 className: $form_id+' super-timepicker-dialog super-field-size-'+$form_size, 947 timeFormat: format, 948 step: step, 949 disableTimeRanges: finalrange, 950 minTime: min, 951 maxTime: max, 952 showDuration: duration, 953 orientation: $orientation 954 }); 955 $this.parent().find('.super-icon').css('cursor','pointer'); 956 set_timepicker_dif($this); 957 }); 958 959 $('.super-timepicker').on('changeTime', function() { 960 set_timepicker_dif($(this)); 961 if(this.value===''){ 962 this.closest('.super-field').classList.remove('super-filled'); 963 }else{ 964 this.closest('.super-field').classList.add('super-filled'); 965 } 966 }); 967 $('.super-timepicker').parent().find('.super-icon').on('click',function(){ 968 $(this).parent().find('.super-timepicker').timepicker('show'); 969 }); 970 }; 971 972 // Initialize button colors 973 SUPER.init_button_colors = function( el ) { 974 var i, nodes, type, color, light, dark, font, fontHover, wrap, icon, btnName, btnNameIcon; 975 976 if(!el){ 977 nodes = document.querySelectorAll('.super-button .super-button-wrap'); 978 for( i = 0; i < nodes.length; i++){ 979 SUPER.init_button_colors(nodes[i]); 980 } 981 }else{ 982 el = el.parentNode; 983 type = el.dataset.type; 984 color = el.dataset.color; 985 light = el.dataset.light; 986 dark = el.dataset.dark; 987 font = el.dataset.font; 988 fontHover = el.dataset.fontHover; 989 wrap = el.querySelector('.super-button-wrap'); 990 icon = wrap.querySelector('.super-before'); 991 btnName = wrap.querySelector('.super-button-name'); 992 btnNameIcon = btnName.querySelector('i'); 993 if(type=='diagonal'){ 994 if(typeof color !== 'undefined'){ 995 wrap.style.borderColor = color; 996 }else{ 997 wrap.style.borderColor = ''; 998 } 999 if(typeof font !== 'undefined'){ 1000 if(icon) icon.style.color = font; 1001 btnName.style.color = font; 1002 if(btnNameIcon) btnNameIcon.style.color = font; 1003 }else{ 1004 if(icon) icon.style.color = ''; 1005 btnName.style.color = ''; 1006 if(btnNameIcon) btnNameIcon.style.color = ''; 1007 } 1008 el.querySelector('.super-button-wrap .super-after').style.backgroundColor = color; 1009 } 1010 if(type=='outline'){
1011 if(typeof color !== 'undefined'){ 1012 wrap.style.borderColor = color; 1013 }else{ 1014 wrap.style.borderColor = ''; 1015 } 1016 wrap.style.backgroundColor = ''; 1017 if(typeof font !== 'undefined'){ 1018 if(icon) icon.style.color = font; 1019 btnName.style.color = font; 1020 if(btnNameIcon) btnNameIcon.style.color = font; 1021 }else{ 1022 if(icon) icon.style.color = ''; 1023 btnName.style.color = ''; 1024 if(btnNameIcon) btnNameIcon.style.color = ''; 1025 } 1026 } 1027 if(type=='2d'){ 1028 wrap.style.backgroundColor = color; 1029 wrap.style.borderColor = light; 1030 if(icon) icon.style.color = font; 1031 btnName.style.color = font; 1032 if(btnNameIcon) btnNameIcon.style.color = font; 1033 } 1034 if(type=='3d'){ 1035 wrap.style.backgroundColor = color; 1036 wrap.style.color = dark; 1037 wrap.style.borderColor = light; 1038 if(typeof fontHover !== 'undefined'){ 1039 if(icon) icon.style.color = font; 1040 btnName.style.color = font; 1041 if(btnNameIcon) btnNameIcon.style.color = font; 1042 }else{ 1043 if(typeof font !== 'undefined'){ 1044 if(icon) icon.style.color = font; 1045 btnName.style.color = font; 1046 if(btnNameIcon) btnNameIcon.style.color = font; 1047 }else{ 1048 if(icon) icon.style.color = ''; 1049 btnName.style.color = ''; 1050 if(btnNameIcon) btnNameIcon.style.color = ''; 1051 } 1052 } 1053 } 1054 if(type=='flat'){ 1055 wrap.style.backgroundColor = color; 1056 if(icon) icon.style.color = font; 1057 btnName.style.color = font; 1058 if(btnNameIcon) btnNameIcon.style.color = font; 1059 } 1060 } 1061 }; 1062 1063 // Init button hover colors 1064 SUPER.init_button_hover_colors = function( el ) { 1065 var type = el.dataset.type, 1066 color = el.dataset.color, 1067 hoverColor = el.dataset.hoverColor, 1068 hoverLight = el.dataset.hoverLight, 1069 hoverDark = el.dataset.hoverDark, 1070 font = el.dataset.font, 1071 fontHover = el.dataset.fontHover, 1072 wrap = el.querySelector('.super-button-wrap'), 1073 icon = wrap.querySelector('.super-before'), 1074 btnName = wrap.querySelector('.super-button-name'), 1075 btnNameIcon = btnName.querySelector('i'); 1076 if(type=='2d'){ 1077 wrap.style.backgroundColor = hoverColor; 1078 wrap.style.borderColor = hoverLight; 1079 if(icon) icon.style.color = fontHover; 1080 btnName.style.color = fontHover; 1081 if(btnNameIcon) btnNameIcon.style.color = fontHover; 1082 } 1083 if(type=='flat'){ 1084 wrap.style.backgroundColor = hoverColor; 1085 if(icon) icon.style.color = fontHover; 1086 btnName.style.color = fontHover; 1087 if(btnNameIcon) btnNameIcon.style.color = fontHover; 1088 } 1089 if(type=='outline'){ 1090 if(typeof hoverColor !== 'undefined'){ 1091 wrap.style.backgroundColor = hoverColor; 1092 }else{ 1093 if(typeof color !== 'undefined'){ 1094 wrap.style.backgroundColor = color; 1095 }else{ 1096 wrap.style.backgroundColor = ''; 1097 } 1098 } 1099 wrap.style.borderColor = hoverColor; 1100 if(typeof fontHover !== 'undefined'){ 1101 if(icon) icon.style.color = fontHover; 1102 btnName.style.color = fontHover; 1103 if(btnNameIcon) btnNameIcon.style.color = fontHover; 1104 }else{ 1105 if(typeof font !== 'undefined'){ 1106 if(icon) icon.style.color = font; 1107 btnName.style.color = font; 1108 if(btnNameIcon) btnNameIcon.style.color = font; 1109 }else{ 1110 if(icon) icon.style.color = ''; 1111 btnName.style.color = ''; 1112 if(btnNameIcon) btnNameIcon.style.color = ''; 1113 } 1114 } 1115 } 1116 if(type=='diagonal'){ 1117 if(typeof color !== 'undefined'){ 1118 wrap.style.borderColor = hoverColor; 1119 }else{ 1120 wrap.style.borderColor = ''; 1121 } 1122 if(typeof font !== 'undefined'){ 1123 if(icon) icon.style.color = fontHover; 1124 btnName.style.color = fontHover; 1125 if(btnNameIcon) btnNameIcon.style.color = fontHover; 1126 }else{ 1127 if(icon) icon.style.color = ''; 1128 btnName.style.color = ''; 1129 if(btnNameIcon) btnNameIcon.style.color = ''; 1130 } 1131 wrap.querySelector('.super-after').style.backgroundColor = hoverColor; 1132 return false; 1133 } 1134 if(type=='2d'){ 1135 return false; 1136 } 1137 if(typeof hoverColor !== 'undefined'){ 1138 wrap.style.backgroundColor = hoverColor; 1139 if(type=='3d'){ 1140 wrap.style.color = hoverDark; 1141 wrap.style.borderColor = hoverLight; 1142 if(typeof fontHover !== 'undefined'){ 1143 if(icon) icon.style.color = fontHover; 1144 btnName.style.color = fontHover; 1145 if(btnNameIcon) btnNameIcon.style.color = fontHover; 1146 }else{ 1147 if(typeof font !== 'undefined'){ 1148 if(icon) icon.style.color = font; 1149 btnName.style.color = font; 1150 if(btnNameIcon) btnNameIcon.style.color = font; 1151 }else{ 1152 if(icon) icon.style.color = ''; 1153 btnName.style.color = ''; 1154 if(btnNameIcon) btnNameIcon.style.color = ''; 1155 } 1156 } 1157 } 1158 } 1159 }; 1160 1161 // Retrieve amount of decimals based on a numberic value 1162 SUPER.get_decimal_places = function($number){
1163 var $match = (''+$number).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/); 1164 if (!$match) { return 0; } 1165 return Math.max(0, ($match[1] ? $match[1].length : 0) - ($match[2] ? +$match[2] : 0)); 1166 }; 1167 SUPER.getAllUrlParams = function(url) { 1168 var queryString = url ? url.split('?')[1] : window.location.search.slice(1); 1169 var obj = {}; 1170 if (queryString) { 1171 queryString = queryString.split('#')[0]; 1172 var arr = queryString.split('&'); 1173 for (var i = 0; i < arr.length; i++) { 1174 var a = arr[i].split('='); 1175 var paramName = a[0]; 1176 var paramValue = typeof (a[1]) === 'undefined' ? true : a[1]; 1177 paramName = paramName.toLowerCase(); 1178 if (typeof paramValue === 'string') paramValue = paramValue.toLowerCase(); 1179 if (paramName.match(/\[(\d+)?\]$/)) { 1180 var key = paramName.replace(/\[(\d+)?\]/, ''); 1181 if (!obj[key]) obj[key] = []; 1182 if (paramName.match(/\[\d+\]$/)) { 1183 var index = /\[(\d+)\]/.exec(paramName)[1]; 1184 obj[key][index] = paramValue; 1185 } else { 1186 obj[key].push(paramValue); 1187 } 1188 } else { 1189 if (!obj[paramName]) { 1190 obj[paramName] = paramValue; 1191 } else if (obj[paramName] && typeof obj[paramName] === 'string'){ 1192 obj[paramName] = [obj[paramName]]; 1193 obj[paramName].push(paramValue); 1194 } else { 1195 obj[paramName].push(paramValue); 1196 } 1197 } 1198 } 1199 } 1200 return obj; 1201 }; 1202 // Get index of element based on parent node 1203 SUPER.index = function (node, class_name) { 1204 var index = 0; 1205 while (node.previousElementSibling) { 1206 node = node.previousElementSibling; 1207 // Based on specified class name 1208 if (class_name) { 1209 if (node.classList.contains(class_name)) { 1210 index++; 1211 } 1212 } else { 1213 index++; 1214 } 1215 1216 } 1217 return index; 1218 }; 1219 SUPER.get_dynamic_column_depth = function(field, nameSuffix, clone, cloneIndex){ 1220 if(typeof nameSuffix === 'undefined') nameSuffix = ''; 1221 if(typeof cloneIndex === 'undefined') cloneIndex = 0; 1222 var allParents = $(field).parents('.super-duplicate-column-fields'); 1223 var suffix = []; 1224 $(allParents).each(function(key){ 1225 if(key===0){ 1226 if(clone===this){ 1227 if(cloneIndex>0){ 1228 return; 1229 } 1230 } 1231 } 1232 var currentParent = this; 1233 var currentParentIndex = SUPER.index(this, 'super-duplicate-column-fields'); 1234 if(currentParentIndex===0 && key===0){ 1235 // Skip it 1236 return; 1237 } 1238 suffix.push('['+currentParentIndex+']'); 1239 }); 1240 return suffix.reverse().join(''); 1241 } 1242 SUPER.append_dynamic_column_depth = function(clone){ 1243 var added_fields = {}, 1244 added_fields_with_suffix = {}, 1245 added_fields_without_suffix = [], 1246 i, field, parent, last_tab_index, 1247 nodes = clone.querySelectorAll('.super-shortcode-field[name]'); 1248 1249 for (i = 0; i < nodes.length; ++i) { 1250 field = nodes[i]; 1251 parent = field.closest('.super-field'); 1252 if(field.classList.contains('super-fileupload')){ 1253 field.classList.remove('super-rendered'); 1254 field = field.parentNode.querySelector('.super-active-files'); 1255 } 1256 // Keep valid TAB index 1257 if( (typeof parent.dataset.superTabIndex !== 'undefined') && (last_tab_index!=='') ) { 1258 last_tab_index = parseFloat(parseFloat(last_tab_index)+0.001).toFixed(3); 1259 parent.dataset.superTabIndex = last_tab_index; 1260 } 1261 added_fields[field.name] = field; 1262 1263 // Figure out how deep this node is inside dynamic columns 1264 var cloneIndex = $(clone).index(); 1265 var dynamicParent = field.closest('.super-duplicate-column-fields'); 1266 var nameSuffix = ''; 1267 if(cloneIndex>0 && clone===dynamicParent){ 1268 nameSuffix = '_'+(cloneIndex+1); 1269 } 1270 var levels = SUPER.get_dynamic_column_depth(field, nameSuffix, clone, cloneIndex); 1271 var originalFieldName = field.dataset.oname; 1272 field.name = originalFieldName+levels+nameSuffix; 1273 //field.value = field.name; 1274 field.dataset.levels = levels; 1275 added_fields_with_suffix[originalFieldName] = field.name; 1276 added_fields_without_suffix.push(field.name); 1277 if( field.classList.contains('hasDatepicker') ) field.classList.remove('hasDatepicker'); field.id = ''; 1278 if( field.classList.contains('ui-timepicker-input') ) field.classList.remove('ui-timepicker-input'); 1279 } 1280 1281 1282 // Now replace {tags} inside conditional logic/variable logic 1283 // Update conditional logic names 1284 // Update validate condition names 1285 // Update variable condition names 1286 nodes = clone.querySelectorAll('.super-conditional-logic, .super-validate-conditions, .super-variable-conditions'); 1287 for(i=0; i<nodes.length; ++i){ 1288 // Before we continue replace any foreach(file_upload_fieldname) 1289 var regex = /{([-_a-zA-Z0-9]{1,})(\[.*?\])?(_\d{1,})?(?:;([a-zA-Z0-9]{1,}))?}/g; 1290 var m; 1291 var conditions = nodes[i].value; 1292 var replaceTagsWithValue = {}; 1293 while ((m = regex.exec(conditions)) !== null) { 1294 // This is necessary to avoid infinite loops with zero-width matches 1295 if (m.index === regex.lastIndex) { 1296 regex.lastIndex++; 1297 } 1298 var $o = (m[0] ? m[0] : ''); // original tag 1299 var $n = (m[1] ? m[1] : ''); // name 1300 var $d = (m[2] ? m[2] : ''); // depth 1301 var $dr = $d.replace(/[0-9]/g, "0") // depth reset to 0 1302 var $c = (m[3] ? m[3] : ''); // counter e.g: _2 or _3 etc. 1303 var $s = (m[4] ? m[4] : ''); // suffix 1304 if($s!=='') $s = ';'+$s; 1305 var currentFieldParent = $(nodes[i]).parents('.super-duplicate-column-fields:eq(0)');
1306 var findChildField = $(currentFieldParent).find('.super-shortcode-field[data-oname="'+$n+'"][data-olevels="'+$dr+'"]').first(); 1307 if(findChildField.length===0) continue; 1308 var allParents = $(findChildField).parents('.super-duplicate-column-fields'); 1309 var childParentIndex = $(findChildField).parents('.super-duplicate-column-fields:eq(0)').index(); 1310 var suffix = []; 1311 $(allParents).each(function(key){ 1312 var currentParentIndex = $(this).index(); // e.g: 0, 1, 2 1313 if(key===0 && currentParentIndex===0){ 1314 return; 1315 } 1316 suffix.push('['+currentParentIndex+']'); 1317 }); 1318 if(childParentIndex!==0){ 1319 delete suffix[0]; 1320 } 1321 levels = suffix.reverse().join(''); 1322 if(childParentIndex!==0){ 1323 replaceTagsWithValue[$o] = '{'+$n+levels+'_'+(childParentIndex+1)+$s+'}'; 1324 continue; 1325 } 1326 replaceTagsWithValue[$o] = '{'+$n+levels+$c+$s+'}'; 1327 } 1328 var key; 1329 for(key in replaceTagsWithValue) { 1330 nodes[i].value = SUPER.replaceAll(nodes[i].value, key, replaceTagsWithValue[key]); 1331 } 1332 } 1333 $.each(added_fields, function(name, field) { 1334 SUPER.after_field_change_blur_hook({form: clone, el: field}); 1335 }); 1336 return { 1337 added_fields: added_fields, 1338 added_fields_with_suffix: added_fields_with_suffix, 1339 added_fields_without_suffix: added_fields_without_suffix 1340 } 1341 }; 1342 1343 jQuery(document).ready(function ($) { 1344 1345 SUPER.init_common_fields(); 1346 1347 var $doc = $(document); 1348 1349 // When Elementor popup is opened re-init super forms 1350 $doc.on('elementor/popup/show', () => { 1351 SUPER.init_super_form_frontend(); 1352 }); 1353 1354 $doc.on('focusin', function(e){ 1355 var i, nodes; 1356 if(!e.target.tagName || typeof e.target.closest !== 'function') return true; 1357 if(e.target.closest('.super-timepicker-dialog')){ 1358 // timepicker element was clicked 1359 SUPER.focusForm(e.relatedTarget); 1360 return true; 1361 } 1362 if(e.target.closest('.super-datepicker-dialog')){ 1363 // datepicker element was clicked 1364 SUPER.focusForm(e.relatedTarget); 1365 return true; 1366 } 1367 if(SUPER.lastTabKey){ 1368 if(e.target.tagName==='FORM' && e.target.closest('.super-form')){ 1369 // Check if form is already focussed 1370 if(e.target.classList.contains('super-form-focussed')){ 1371 // form is already focussed, just continue 1372 return true; 1373 } 1374 // Focus form 1375 // is a super form, lets focus it by adding super-form-focussed class 1376 SUPER.focusForm(e.target); 1377 SUPER.lastFocussedForm = e.target; 1378 var form = SUPER.lastFocussedForm; 1379 var field, visibleNodes = []; 1380 if(SUPER.lastTabKey==='tab'){ 1381 e.target.blur(); 1382 // the form became focus via regular tab, so we must focus the first field 1383 nodes = form.querySelectorAll('.super-field:not('+super_common_i18n.tab_index_exclusion+')'); 1384 for (i = 0; i < nodes.length; i++) { 1385 if(SUPER.has_hidden_parent(nodes[i])) continue; 1386 visibleNodes.push(nodes[i]); 1387 break; 1388 } 1389 field = visibleNodes[0]; 1390 SUPER.focusNextTabField(e, field, form, field); 1391 } 1392 if(SUPER.lastTabKey==='shift+tab'){ 1393 if(SUPER.firstFocussedField){ 1394 // the form has focus, and the last focussed field was the first, so we do a regular shift+tab 1395 return true; 1396 } 1397 e.target.blur(); 1398 // the form became focus via shift+tab, so we must focus the last field 1399 nodes = form.querySelectorAll('.super-field:not('+super_common_i18n.tab_index_exclusion+')'); 1400 for (i = 0; i < nodes.length; i++) { 1401 if(SUPER.has_hidden_parent(nodes[i])
1401) continue; 1402 visibleNodes.push(nodes[i]); 1403 } 1404 field = visibleNodes[visibleNodes.length-1]; 1405 SUPER.focusNextTabField(e, field, form, field); 1406 } 1407 e.preventDefault(); 1408 return false; 1409 }else{ 1410 // Check if the element is part of the last focussed form 1411 if(SUPER.lastFocussedForm && e.target.closest('form') && e.target.closest('form')===SUPER.lastFocussedForm){ 1412 // element is part of last focussed form, focus the element 1413 SUPER.focusForm(e.target); 1414 if(!e.target.classList.contains('super-placeholder')){ 1415 SUPER.focusField(e.target); 1416 } 1417 }else{ 1418 // element is not part of last focussed form, removing super-form-focussed class 1419 if(SUPER.lastFocussedForm){ 1420 SUPER.lastFocussedForm.classList.remove('super-form-focussed'); 1421 SUPER.lastFocussedForm.tabIndex = 0; 1422 // Make sure to remove focus/open classes 1423 nodes = SUPER.lastFocussedForm.querySelectorAll('.super-focus'); 1424 for(i = 0; i < nodes.length; i++){ 1425 nodes[i].classList.remove('super-focus'); 1426 nodes[i].classList.remove('super-open'); 1427 } 1428 nodes = SUPER.lastFocussedForm.querySelectorAll('.super-open'); 1429 for(i = 0; i < nodes.length; i++){ 1430 nodes[i].classList.remove('super-open'); 1431 } 1432 } 1433 } 1434 } 1435 }else{ 1436 if(e.target.tagName==='FORM' && e.target.closest('.super-form')){ 1437 SUPER.focusForm(e.target); 1438 SUPER.lastFocussedForm = e.target; 1439 SUPER.lastFocussedForm.tabIndex = -1; 1440 }else{ 1441 // Might be a field inside the form 1442 if(e.target.closest('.super-form')){ 1443 SUPER.focusField(e.target); 1444 SUPER.focusForm(e.target.closest('form')); 1445 } 1446 } 1447 } 1448 }); 1449 $doc.keydown(function(e){ 1450 SUPER.lastTabKey = undefined; 1451 var i, nodes, 1452 field, 1453 form, 1454 item, 1455 current, 1456 submitButton, 1457 nextSibling, 1458 keyCode = e.keyCode || e.which; 1459 1460 // 32 = space 1461 if (keyCode == 32) { 1462 field = document.querySelector('.super-focus'); 1463 if(field){ 1464 form = field.closest('.super-form'); 1465 // If checkbox or radio, then we check/uncheck the current focussed item 1466 if(field.classList.contains('super-checkbox') || field.classList.contains('super-radio')){ 1467 if(field.querySelector('.super-focus')){ 1468 if(field.classList.contains('super-checkbox')){ 1469 SUPER.simulateCheckboxItemClicked(e, field.querySelector('.super-focus')); 1470 }else{ 1471 SUPER.simulateRadioItemClicked(e, field.querySelector('.super-focus')); 1472 } 1473 } 1474 e.preventDefault(); 1475 return false; 1476 } 1477 // If toggle 1478 if(field.classList.contains('super-toggle')){ 1479 field.querySelector('.super-toggle-switch').click(); 1480 e.preventDefault(); 1481 return false; 1482 } 1483 } 1484 } 1485 1486 // 13 = enter 1487 if (keyCode == 13) { 1488 field = document.querySelector('.super-focus'); 1489 if(field){ 1490 if(field.classList.contains('super-text')){ 1491 var countryList = field.querySelector('.super-int-phone_country-list'); 1492 if(countryList){ 1493 if(!countryList.classList.contains('.super-int-phone_hide')){ 1494 e.preventDefault(); 1495 return false; 1496 } 1497 } 1498 } 1499 if(field.classList.contains('super-dropdown')){ 1500 item = field.querySelector('.super-focus'); 1501 if(item) item.click(); 1502 e.preventDefault(); 1503 return false; 1504 } 1505 if(field.classList.contains('super-file')){ 1506 field.querySelector('.super-fileupload-button').click(); 1507 e.preventDefault(); 1508 return false; 1509 } 1510 if( field.classList.contains('super-textarea') ) { 1511 // Allow to add line breaks on textarea elements 1512 return true; 1513 } 1514 form = field.closest('.super-form'); 1515 // @since 3.3.0 - Do not submit form if Enter is disabled 1516 if(form && form.dataset.disableEnter=='true'){ 1517 e.preventDefault(); 1518 return false; 1519 } 1520 if(!form.querySelector('.super-form-button.super-loading')){ 1521 submitButton = form.querySelector('.super-form-button .super-button-wrap .super-button-name[data-action="submit"]'); 1522 if(submitButton) { 1523 var args = { 1524 el: undefined, 1525 form: form, 1526 submitButton: submitButton.parentNode, 1527 validateMultipart: undefined, 1528 event: e, 1529 doingSubmit: true 1530 }; 1531 SUPER.validate_form(args); 1532 } 1533 } 1534 e.preventDefault(); 1535 } 1536 } 1537 // 37 = left arrow 1538 // 38 = up arrow 1539 // 39 = right arrow 1540 // 40 = down arrow 1541 if ( keyCode == 37 || keyCode == 38 || keyCode == 39 || keyCode == 40 ) { 1542 field = document.querySelector('.super-focus'); 1543 if(field){ 1544 // If toggle 1545 if(field.classList.contains('super-toggle')){ 1546 field.querySelector('.super-toggle-switch').click(); 1547 e.preventDefault(); 1548 return false; 1549 } 1550 // Slider field 1551 if(field.classList.contains('super-slider')){ 1552 var inputField = field.querySelector('.super-shortcode-field'); 1553 var value = inputField.value; 1554 var steps = inputField.dataset.steps; 1555 var newValue; 1556 if(keyCode == 37 || keyCode == 38){ 1557 // Reverse 1558 newValue = parseFloat(value)-parseFloat(steps); 1559 }else{ 1560 newValue = parseFloat(value)+parseFloat(steps); 1561 } 1562 SUPER.reposition_slider_amount_label(inputField, newValue); 1563 e.preventDefault(); 1564 return false; 1565 } 1566 // Star rating 1567 if(field.classList.contains('super-rating')){ 1568 // First find last active star 1569 nodes = field.querySelectorAll('.super-active'); 1570 if(keyCode == 37 || keyCode == 38){ 1571 // Reverse 1572 if(nodes.length) nodes[nodes.length-2].click(); 1573 }else{ 1574 if(nodes.length){ 1575 // If it isn't last star, set next star to active 1576 if(nodes[nodes.length-1].nextSibling && nodes[nodes.length-1].nextSibling.tagName==='I'){ 1577 nodes[nodes.length-1].nextSibling.click(); 1578 } 1579 }else{ 1580 // No active star yet 1581 field.querySelector('i.super-rating-star').
1581click(); 1582 } 1583 } 1584 e.preventDefault(); 1585 return false; 1586 } 1587 1588 // Dropdown 1589 if(field.classList.contains('super-dropdown')){ 1590 var all = field.querySelectorAll('.super-item:not(.super-placeholder)'); 1591 current = field.querySelector('.super-focus'); 1592 if(!current){ 1593 // If no item is focussed we grab the active item 1594 current = field.querySelector('.super-active'); 1595 } 1596 if(keyCode == 37 || keyCode == 38){ 1597 // go up (reverse) 1598 if(current){ 1599 var prev = current.previousSibling; 1600 if(prev && !prev.classList.contains('super-placeholder')){ 1601 current.classList.remove('super-focus'); 1602 prev.classList.add('super-focus'); 1603 }else{ 1604 // continue at bottom (last item) 1605 all[0].classList.remove('super-focus'); 1606 all[all.length-1].classList.add('super-focus'); 1607 } 1608 }else{ 1609 // none selected yet, focus last 1610 all[all.length-1].classList.add('super-focus'); 1611 } 1612 }else{ 1613 // go down 1614 if(current){ 1615 var next = current.nextSibling; 1616 if(next){ 1617 current.classList.remove('super-focus'); 1618 next.classList.add('super-focus'); 1619 }else{ 1620 // continue at top (first item) 1621 all[all.length-1].classList.remove('super-focus'); 1622 all[0].classList.add('super-focus'); 1623 } 1624 }else{ 1625 // none selected yet, focus first 1626 all[0].classList.add('super-focus'); 1627 } 1628 } 1629 current = field.querySelector('.super-focus'); 1630 current.scrollIntoView({behavior: "auto", block: "center", inline: "center"}); 1631 e.preventDefault(); 1632 return false; 1633 } 1634 1635 // Checkbox / Radio 1636 if(field.classList.contains('super-checkbox') || field.classList.contains('super-radio')){ 1637 if(field.querySelector('.super-focus')){ 1638 current = field.querySelector('.super-item.super-focus'); 1639 if(current){ 1640 // 37 = left arrow 1641 // 38 = up arrow 1642 if(keyCode == 37 || keyCode == 38){ 1643 // prev 1644 nextSibling = current.previousSibling; 1645 }else{ 1646 // next 1647 nextSibling = current.nextSibling; 1648 } 1649 current.classList.remove('super-focus'); 1650 if(nextSibling && nextSibling.classList.contains('super-item')){ 1651 nextSibling.classList.add('super-focus'); 1652 if(field.classList.contains('super-radio')){ 1653 nextSibling.click(); 1654 } 1655 }else{ 1656 // left, up 1657 var innerNodes = field.querySelectorAll('.super-item'); 1658 if(keyCode == 37 || keyCode == 38){
1659 innerNodes[innerNodes.length-1].classList.add('super-focus'); 1660 if(field.classList.contains('super-radio')){ 1661 innerNodes[innerNodes.length-1].click(); 1662 } 1663 }else{ 1664 innerNodes[0].classList.add('super-focus'); 1665 if(field.classList.contains('super-radio')){ 1666 innerNodes[0].click(); 1667 } 1668 } 1669 } 1670 e.preventDefault(); 1671 return false; 1672 } 1673 } 1674 e.preventDefault(); 1675 return false; 1676 } 1677 } 1678 } 1679 1680 // 37 = left arrow 1681 // 39 = right arrow 1682 // TABs left/right navigation through keyboard keys 1683 if( (keyCode == 37) || (keyCode == 39) ) { 1684 nodes = document.querySelectorAll('.super-form .super-tabs-contents'); 1685 for (i = 0; i < nodes.length; i++) { 1686 field = nodes[i].closest('.super-shortcode'); 1687 if(!SUPER.has_hidden_parent(field, true)){ // Also include Multi-part for this check 1688 // Only if no focussed field is found 1689 // First get the currently active TAB 1690 var activeTab = field.querySelector('.super-tabs-contents > .super-tabs-content.super-active'); 1691 var focusFound = activeTab.querySelectorAll('.super-focus').length; 1692 if(focusFound) continue; // Do not go to next/prev TAB if there is a focussed field 1693 // Only if not inside other TAB element 1694 if(!field.closest('.super-tabs-contents')){ 1695 // Go left 1696 if( keyCode == 37 ) nodes[i].querySelector(':scope > .super-content-prev').click(); 1697 // Go right 1698 if( keyCode == 39 ) nodes[i].querySelector(':scope > .super-content-next').click(); 1699 } 1700 } 1701 } 1702 } 1703 1704 // 9 = TAB 1705 if (keyCode == 9) { 1706 SUPER.firstFocussedField = false; 1707 SUPER.lastTabKey = 'tab'; 1708 if(e.shiftKey){ 1709 SUPER.lastTabKey = 'shift+tab'; 1710 } 1711 // Check if we have a focussed form 1712 form = document.querySelector('.super-form-focussed') 1713 if(form){ 1714 // Check if we can find a currently focussed field 1715 field = form.querySelector('.super-field.super-focus'); 1716 if(field){ 1717 // Check if first field of form 1718 nodes = form.querySelectorAll('.super-field:not('+super_common_i18n.tab_index_exclusion+')'); 1719 var visibleNodes = []; 1720 for (i = 0; i < nodes.length; i++) { 1721 if(SUPER.has_hidden_parent(nodes[i])) continue; 1722 visibleNodes.push(nodes[i]); 1723 } 1724 // if we shift+tab from second visible field to first visible field, we must set tabindex on form to -1 1725 if(field===visibleNodes[1]){ 1726 if(SUPER.lastTabKey==='shift+tab'){ 1727 form.tabIndex = -1; 1728 SUPER.focusNextTabField(e, field, form); 1729 e.preventDefault(); 1730 return false; 1731 } 1732 } 1733 if(field===visibleNodes[0]){ 1734 // The current field is the first field in the form 1735 SUPER.firstFocussedField = true; 1736 if(SUPER.lastTabKey==='shift+tab'){ 1737 // Unfocus current field 1738 SUPER.resetFocussedFields(); 1739 return true; 1740 } 1741 } 1742 if(field===visibleNodes[visibleNodes.length-1]){ 1743 // The current field is the last field in the form 1744 if(SUPER.lastTabKey==='tab'){ 1745 // If this is the last field then we do a normal tab to get out of form focus 1746 // Unfocus current field 1747 field.classList.remove('super-focus'); 1748 if( field.classList.contains('super-form-button') ) { 1749 // Check if it's a button 1750 SUPER.init_button_colors(field.querySelector('.super-button-wrap')); 1751 }else{ 1752 // If not a button 1753 innerNodes = field.querySelectorAll('.super-focus'); 1754 for ( i = 0; i < innerNodes.length; i++){ 1755 innerNodes[i].classList.remove('super-focus'); 1756 } 1757 } 1758 return true; 1759 } 1760 } 1761 1762 SUPER.focusNextTabField(e, field, form); 1763 e.preventDefault(); 1764 return false; 1765 }else{ 1766 // No focussed field yet, let's focus the first field or last depending on tab, or shift+tab 1767 if(SUPER.lastTabKey==='tab'){ 1768 SUPER.firstFocussedField = true; 1769 nodes = form.querySelectorAll('.super-field:not('+super_common_i18n.tab_index_exclusion+')'); 1770 for (i = 0; i < nodes.length; i++) { 1771 if(SUPER.has_hidden_parent(nodes[i])
1771) continue; 1772 SUPER.focusNextTabField(e, nodes[i], form, nodes[i]); 1773 e.preventDefault(); 1774 return false; 1775 } 1776 } 1777 if(SUPER.lastTabKey==='shift+tab'){ 1778 return true; 1779 } 1780 } 1781 e.preventDefault(); 1782 return false; 1783 }else{ 1784 // no focussed form found, just let the TAB event execute 1785 } 1786 } 1787 }); 1788 1789 1790 // @SINCE 4.9.0 - TABS content next/prev switching 1791 $doc.on('click', '.super-content-prev, .super-content-next', function(e){ 1792 // Make sure we stop any other events from being triggered 1793 e.preventDefault(); 1794 var $this = $(this), 1795 $tab_menu = $this.parents('.super-shortcode:eq(0)').children('.super-tabs-menu'), 1796 $tab_content = $this.parents('.super-tabs-contents:eq(0)'), 1797 $total = $tab_menu.children('.super-tabs-tab').length, 1798 $index = $tab_content.children('.super-tabs-content.super-active').index(); 1799 // Next 1800 if($this.hasClass('super-content-next')){ 1801 $index++; 1802 if($index >= $total) { 1803 $index = $total-1; 1804 } 1805 if($index >= $total-1){ 1806 $tab_menu.find('.super-tab-next').hide(); 1807 }else{ 1808 $tab_menu.find('.super-tab-next').show(); 1809 } 1810 $tab_menu.find('.super-tab-prev').show(); 1811 } 1812 // Prev 1813 if($this.hasClass('super-content-prev')){ 1814 $index--; 1815 if($index < 0) { 1816 $index = 0; 1817 } 1818 if($index===0){ 1819 $tab_menu.find('.super-tab-prev').hide(); 1820 }else{ 1821 $tab_menu.find('.super-tab-prev').show(); 1822 } 1823 $tab_menu.find('.super-tab-next').show(); 1824 } 1825 $tab_menu.children('.super-tabs-tab').removeClass('super-active'); 1826 $tab_menu.children('.super-tabs-tab:eq('+($index)+')').addClass('super-active'); 1827 $tab_content.children('.super-tabs-content').removeClass('super-active'); 1828 $tab_content.children('.super-tabs-content:eq('+($index)+')').addClass('super-active'); 1829 return false; 1830 }); 1831 // @SINCE 4.8.0 - TABS next/prev switching 1832 $doc.on('click', '.super-tab-prev, .super-tab-next', function(e){ 1833 // Make sure we stop any other events from being triggered 1834 e.preventDefault(); 1835 var $this = $(this), 1836 $tab_menu = $this.parents('.super-tabs-menu:eq(0)'), 1837 $tab_content = $tab_menu.parent().children('.super-tabs-contents'), 1838 $total = $this.parents('.super-tabs-menu:eq(0)').children('.super-tabs-tab').length, 1839 $index = $this.parents('.super-tabs-menu:eq(0)').children('.super-tabs-tab.super-active').index(); 1840 // Next 1841 if($this.hasClass('super-tab-next')){ 1842 $index++; 1843 if($index >= $total) { 1844 $index = $total-1; 1845 } 1846 if($index >= $total-1){ 1847 $tab_menu.find('.super-tab-next').hide(); 1848 }else{ 1849 $tab_menu.find('.super-tab-next').show(); 1850 } 1851 $tab_menu.find('.super-tab-prev').show(); 1852 1853 } 1854 // Prev 1855 if($this.hasClass('super-tab-prev')){ 1856 $index--; 1857 if($index < 0) { 1858 $index = 0; 1859 } 1860 if($index===0){ 1861 $tab_menu.find('.super-tab-prev').hide(); 1862 }else{ 1863 $tab_menu.find('.super-tab-prev').show(); 1864 } 1865 $tab_menu.find('.super-tab-next').show(); 1866 } 1867 $tab_menu.children('.super-tabs-tab').removeClass('super-active'); 1868 $tab_menu.children('.super-tabs-tab:eq('+($index)+')').addClass('super-active'); 1869 $tab_content.children('.super-tabs-content').removeClass('super-active'); 1870 $tab_content.children('.super-tabs-content:eq('+($index)+')').addClass('super-active'); 1871 return false; 1872 }); 1873 // @since 4.8.0 - TABS switching 1874 $doc.on('click', '.super-shortcode .super-tabs-tab', function(e){
1875 // Make sure we stop any other events from being triggered 1876 e.preventDefault(); 1877 var $this = $(this), 1878 $index = $this.index(), 1879 $tab_menu = $this.parent('.super-tabs-menu'), 1880 $tab_content = $tab_menu.parent().children('.super-tabs-contents'); 1881 $tab_menu.children('.super-tabs-tab').removeClass('super-active'); 1882 $this.addClass('super-active'); 1883 $tab_content.children('.super-tabs-content').removeClass('super-active'); 1884 $tab_content.children('.super-tabs-content:eq('+$index+')').addClass('super-active'); 1885 }); 1886 1887 // @since 4.8.0 - Accordion toggles 1888 $doc.on('click', '.super-accordion-item .super-accordion-header', function(){ 1889 var $this = $(this).parent(), 1890 $parent = $this.parent(); 1891 if($this.hasClass('super-active')){ 1892 // Close all accordion 1893 $parent.children('.super-accordion-item').removeClass('super-active'); 1894 }else{ 1895 // Close other accordions, then open this one 1896 $parent.children('.super-accordion-item').removeClass('super-active'); 1897 // Open current one 1898 $this.addClass('super-active'); 1899 // Make sure to correclty set the slider dragger when accordion is opened 1900 var i, nodes = $this[0].querySelectorAll('.super-shortcode.super-slider'); 1901 for(i=0; i<nodes.length; i++){ 1902 if(nodes[i].querySelector('.slider')){ 1903 var field = nodes[i].querySelector('.super-shortcode-field'); 1904 SUPER.reposition_slider_amount_label(field, field.value, true); 1905 } 1906 } 1907 } 1908 SUPER.init_super_responsive_form_fields({form: $parent[0]}); 1909 }); 1910 1911 // @since 3.1.0 - auto transform to uppercase 1912 $doc.on('input', '.super-form .super-uppercase .super-shortcode-field', function() { 1913 $(this).val(function(_, val) { 1914 return val.toUpperCase(); 1915 }); 1916 }); 1917 1918 // @since 1.7 - count words on textarea field (useful for translation estimates) 1919 var word_count_timeout = null; 1920 $doc.on('keyup blur', 'textarea.super-shortcode-field', function(e) { 1921 var $this = $(this), 1922 $time = 250, 1923 $text, 1924 $words, 1925 $removeNoneChars, 1926 $chars, 1927 $allChars; 1928 if(e.type!='keyup') $time = 0; 1929 if (word_count_timeout !== null) { 1930 clearTimeout(word_count_timeout); 1931 } 1932 word_count_timeout = setTimeout(function () { 1933 $text = $this.val(); 1934 $words = $text.match(/\S+/g); 1935 $words = $words ? $words.length : 0; 1936 $removeNoneChars = $text.replace(/\s/g, ""); // use the \s quantifier to remove all white space, is equivalent to [\r\n\t\f\v ] 1937 $chars = $removeNoneChars.length; // count only characters after removing any whitespace, tabs, linebreaks etc. 1938 $allChars = $text.length; // count all characters 1939 $this.attr('data-word-count', $words); 1940 $this.attr('data-chars-count', $chars); 1941 $this.attr('data-allchars-count', $allChars); 1942 SUPER.after_field_change_blur_hook({el: $this[0]}); 1943 }, $time); 1944 }); 1945 1946 // Upon opening color picker 1947 $doc.on('click', '.super-color', function(){ 1948 SUPER.focusField(this); 1949 }); 1950 1951 // @since 1.2.4 1952 $doc.on('click', '.super-quantity .super-minus-button, .super-quantity .super-plus-button', function(){ 1953 SUPER.focusField(this); 1954 var $this = $(this), 1955 $input_field = $this.parent().find('.super-shortcode-field'), 1956 $min = parseFloat($input_field.data('minnumber')), 1957 $max = parseFloat($input_field.data('maxnumber')), 1958 $field_value = $input_field.val(), 1959 $new_value, 1960 $steps = parseFloat($input_field.data('steps')), 1961 $decimals = SUPER.get_decimal_places($steps); 1962 1963 if($field_value==='') $field_value = 0; 1964 $field_value = parseFloat($field_value); 1965 if($this.hasClass('super-plus-button')){ 1966 $new_value = $field_value + $steps; 1967 $new_value = parseFloat($new_value.toFixed($decimals)); 1968 if($new_value > $max) return false; 1969 }else{ 1970 $new_value = $field_value - $steps; 1971 $new_value = parseFloat($new_value.toFixed($decimals)); 1972 if($new_value < $min) return false; 1973 } 1974 $input_field.val($new_value); 1975 SUPER.after_field_change_blur_hook({el: $input_field[0]}); 1976 }); 1977 // @since 4.9.0 - Quantity field only allow number input 1978 $doc.on('blur', '.super-quantity .super-shortcode-field', function() { 1979 // Remove empty decimal place 1980 if(this.value.indexOf('.')!==-1){ 1981 var split = this.value.split("."), before = split[0], after = split[1]; 1982 var result = before; 1983 if(after!=='') result += '.'+after; 1984 this.value = result; 1985 } 1986 }); 1987 $doc.on('input', '.super-quantity .super-shortcode-field', function() { 1988 // Exception when using steps with decimals, then allow to enter decimal number 1989 if(this.dataset.steps.indexOf('.')!==-1){ 1990 // Count decimals 1991 var decimals = this.dataset.steps.toString().split(".")[1].length || 0; 1992 var floor = Math.floor(this.dataset.steps); 1993 if(floor===this.dataset.steps) decimals = 0; 1994 this.value = (this.value.indexOf(".")!==-1) ? (this.value.substr(0, this.value.indexOf(".")) + this.value.substr(this.value.indexOf("."), (decimals+1))) : this.value; 1995 return; 1996 } 1997 // Only allow whole numbers 1998 this.value = this.value.replace(/[^0-9]/g, ''); 1999 }); 2000 2001 // @since 2.9.0 - toggle button 2002 $doc.on('click', '.super-toggle-switch', function(){ 2003 var $this = $(this), 2004 $input_field = $this.parent().find('.super-shortcode-field'), 2005 $new_value = $this.find('.super-toggle-on').data('value'); 2006 if( $this.hasClass('super-active')) { 2007 $new_value = $this.find('.super-toggle-off').data('value'); 2008 } 2009 $this.toggleClass('super-active'); 2010 $input_field.val($new_value); 2011 SUPER.focusField(this); 2012 SUPER.after_field_change_blur_hook({el: $input_field[0]}); 2013 }); 2014 2015 // @since 2.1 - trigger field change hook after currency field value has changed 2016 // @since 4.2 - trigger field change hook after quantity field value has changed 2017 var $calculation_threshold = null; 2018 $doc.on('keyup blur', '.super-form .super-currency .super-shortcode-field, .super-form .super-quantity .super-shortcode-field', function(e) { 2019 var $this = $(this); 2020 var $threshold = 0; 2021 if( (typeof $this.attr('data-threshold') !== 'undefined') && (e.type=='keyup') ) { 2022 $threshold = parseFloat($this.attr('data-threshold')); 2023 if ($calculation_threshold !== null) { 2024 clearTimeout($calculation_threshold); 2025 } 2026 $calculation_threshold = setTimeout(function () { 2027 SUPER.after_field_change_blur_hook({el: $this[0]}); 2028 }, $threshold); 2029 }else{ 2030 SUPER.after_field_change_blur_hook({el: $this[0]}); 2031 } 2032 }); 2033 2034 $doc.on('click', '.super-form .super-duplicate-column-fields .super-add-duplicate', function(){ 2035 2036 var i, x, y, 2037 nodes, 2038 v,vv, 2039 found_field, 2040 el, 2041 parent, 2042 column, 2043 form, 2044 firstColumn, 2045 lastColumn, 2046 found, 2047 limit, 2048 unique_field_names = {}, 2049 field_names = {}, 2050 field_name, 2051 field_labels = {}, 2052 counter = 0, 2053 field, 2054 clone, 2055 last_tab_index, 2056 added_fields = {}, 2057 added_fields_with_suffix = {}, 2058 added_fields_without_suffix = [], 2059 //field_counter = 0, 2060 element, 2061 foundElements = [], 2062 html_fields, 2063 data_fields, 2064 conditions, 2065 new_data_attr, 2066 new_data_fields, 2067 new_text, 2068 condition, 2069 replace_names, 2070 new_field, 2071 new_count, 2072 suffix, 2073 superMath, 2074 value_n, 2075 names, 2076 name, 2077 values, 2078 array, 2079 match, 2080 number, 2081 regex = /{([^\\\/\s"'+]*?)}/g, 2082 oldv, 2083 duplicate_dynamically; 2084 2085 el = $(this)[0]; 2086 parent = el.closest('.super-duplicate-column-fields'); 2087 // If custom padding is being used set $column to be the padding wrapper `div` 2088 column = ( parent.parentNode.classList.contains('super-column-custom-padding') ? el.closest('.super-column-custom-padding') : parent.closest('.super-column') ); 2089 form = SUPER.get_frontend_or_backend_form({el: el, form: form}); 2090 var duplicateColumns = column.querySelectorAll('.super-duplicate-column-fields'); 2091 firstColumn = duplicateColumns[0]; 2092 found = column.querySelectorAll(':scope > .super-duplicate-column-fields').length; 2093 limit = parseInt(column.dataset.duplicateLimit, 10); 2094 if( (limit!==0) && (found >= limit) ) { 2095 return false; 2096 } 2097 2098 2099 unique_field_names = {}; // @since 2.4.0 2100 field_names = {}; 2101 field_labels = {}; 2102 counter = 0; 2103 nodes = firstColumn.querySelectorAll('.super-shortcode-field[name]'); 2104 for (i = 0; i < nodes.length; ++i) { 2105 field = nodes[i];
2106 if(field.classList.contains('super-fileupload')){ 2107 field = field.parentNode.querySelector('.super-active-files'); 2108 } 2109 name = field.name; 2110 unique_field_names[name] = name; 2111 field_names[counter] = name; 2112 field_labels[counter] = field.dataset.email; 2113 counter++; 2114 } 2115 2116 counter = column.querySelectorAll(':scope > .super-duplicate-column-fields').length; 2117 clone = firstColumn.cloneNode(true); 2118 lastColumn = duplicateColumns[(found-1)]; 2119 lastColumn.parentNode.insertBefore(clone, lastColumn.nextElementSibling); 2120 2121 // @since 3.3.0 - hook after appending new column 2122 SUPER.after_appending_duplicated_column_hook(form, unique_field_names, clone); 2123 2124 // Now reset field values to default 2125 SUPER.init_clear_form({form: form, clone: clone}); 2126 2127 // @since 3.2.0 - increment for tab index fields when dynamic column is cloned 2128 if($(clone).find('.super-shortcode[data-super-tab-index]').last().length){ 2129 last_tab_index = $(clone).find('.super-shortcode[data-super-tab-index]').last().attr('data-super-tab-index'); 2130 }else{ 2131 last_tab_index = ''; 2132 } 2133 last_tab_index = parseFloat(last_tab_index); 2134 2135 // First rename then loop through conditional logic and update names, otherwise we might think that the field didn't exist! 2136 // Loop over all fields that are inside dynamic column and rename them accordingly 2137 var $info = SUPER.append_dynamic_column_depth(clone); 2138 added_fields_with_suffix = $info.added_fields_with_suffix; 2139 2140 // @since 4.6.0 - update html field tags attribute 2141 // @since 4.6.0 - update accordion title and description field tags attribute 2142 // @since 4.9.6 - update google maps field tags attribute 2143 // Get all elements based on field tag attribute that contain one of these field names 2144 // Then convert it to an array and append the missing field names 2145 // @IMPORTANT: Only do this for elements that are NOT inside a dynamic column 2146 foundElements = []; 2147 $.each(added_fields_with_suffix, function( index ) { 2148 html_fields = form.querySelectorAll('[data-tags*="{'+index+'}"], .super-google-map[data-fields*="{'+index+'}"], .super-html-content[data-fields*="{'+index+'}"]'); 2149 for (i = 0; i < html_fields.length; ++i) { 2150 found = false; 2151 for (x=0; x<foundElements.length; x++) { 2152 if($(foundElements[x]).is(html_fields[i])) found = true; 2153 } 2154 if(!found) foundElements.push(html_fields[i]); 2155 } 2156 }); 2157 2158 var formId = 0; 2159 if(form.querySelector('input[name="hidden_form_id"]')){ 2160 formId = form.querySelector('input[name="hidden_form_id"]').value; 2161 } 2162 for(i=0; i<foundElements.length; i++) { 2163 if(!foundElements[i].parentNode.querySelector('textarea')) continue; 2164 var html = foundElements[i].parentNode.querySelector('textarea').value; 2165 html = SUPER.filter_foreach_statements(foundElements[i], 0, 0, html, undefined, formId, form); 2166 html = SUPER.replaceAll(html, '<%', '{'); 2167 html = SUPER.replaceAll(html, '%>', '}'); 2168 foundElements[i].innerHTML = html; 2169 } 2170 2171 // Now replace {tags} inside HTML element 2172 for(i=0; i<foundElements.length; i++) { 2173 var html; 2174 // @since 4.9.0 - accordion title description {tags} compatibility 2175 if( foundElements[i].dataset.tags ) { 2176 html = foundElements[i].dataset.original; 2177 }else{ 2178 if(!foundElements[i].parentNode.querySelector('textarea')) continue; 2179 html = foundElements[i].parentNode.querySelector('textarea').value; 2180 } 2181 // If empty skip 2182 if(html===''){ 2183 continue; 2184 } 2185 // Before we continue replace any foreach(file_upload_fieldname) 2186 var regex = /{([-_a-zA-Z0-9]{1,})(\[.*?\])?(_\d{1,})?(?:;([a-zA-Z0-9]{1,}))?}/g; 2187 var m; 2188 var replaceTagsWithValue = {}; 2189 while ((m = regex.exec(html)) !== null) { 2190 // This is necessary to avoid infinite loops with zero-width matches 2191 if (m.index === regex.lastIndex) { 2192 regex.lastIndex++; 2193 } 2194 var $o = (m[0] ? m[0] : ''); // original tag 2195 var $n = (m[1] ? m[1] : ''); // name 2196 var $d = (m[2] ? m[2] : ''); // depth 2197 var $dr = $d.replace(/[0-9]/g, "0") // depth reset to 0 2198 var $c = (m[3] ? m[3] : ''); // counter e.g: _2 or _3 etc. 2199 var $s = (m[4] ? m[4] : ''); // suffix 2200 if($s!=='') $s = ';'+$s; 2201 var currentFieldParent = $(foundElements[i]).parents('.super-duplicate-column-fields:eq(0)');
2202 var findChildField = $(currentFieldParent).find('.super-shortcode-field[data-oname="'+$n+'"][data-olevels="'+$dr+'"]').first(); 2203 if(findChildField.length===0) continue; 2204 var allParents = $(findChildField).parents('.super-duplicate-column-fields'); 2205 var childParentIndex = $(findChildField).parents('.super-duplicate-column-fields:eq(0)').index(); 2206 var suffix = []; 2207 $(allParents).each(function(key){ 2208 var currentParentIndex = $(this).index(); // e.g: 0, 1, 2 2209 if(key===0 && currentParentIndex===0){ 2210 return; 2211 } 2212 suffix.push('['+currentParentIndex+']'); 2213 }); 2214 if(childParentIndex!==0){ 2215 delete suffix[0]; 2216 } 2217 var levels = suffix.reverse().join(''); 2218 if(childParentIndex!==0){ 2219 replaceTagsWithValue[$o] = '{'+$n+levels+'_'+(childParentIndex+1)+$s+'}'; 2220 continue; 2221 } 2222 replaceTagsWithValue[$o] = '{'+$n+levels+$c+$s+'}'; 2223 } 2224 var key; 2225 for(key in replaceTagsWithValue) { 2226 html = SUPER.replaceAll(html, key, replaceTagsWithValue[key]); 2227 } 2228 if( foundElements[i].dataset.tags ) { 2229 if(foundElements[i].value || foundElements[i].dataset.value){ 2230 if(foundElements[i].value) foundElements[i].value = html; 2231 if(foundElements[i].dataset.value) foundElements[i].dataset.value = html; 2232 }else{ 2233 foundElements[i].dataset.original = html; 2234 } 2235 }else{ 2236 if(!foundElements[i].parentNode.querySelector('textarea')) continue; 2237 foundElements[i].parentNode.querySelector('textarea').value = html; 2238 } 2239 2240 } 2241 // Required to update calculations after adding dynamic column 2242 SUPER.after_field_change_blur_hook({form: form, el: undefined}); 2243 2244 SUPER.init_replace_html_tags({el: undefined, form: form, foundElements: foundElements}); 2245 2246 // @since 2.4.0 - hook after adding new column 2247 SUPER.after_duplicating_column_hook(form, unique_field_names, clone); 2248 2249 SUPER.init_common_fields(); 2250 }); 2251 2252 // Delete dynamic column 2253 $doc.on('click', '.super-duplicate-column-fields .super-delete-duplicate', function(){ 2254 var parent = this.closest('.super-duplicate-column-fields'), 2255 siblingRows = parent.parentNode.children, 2256 rowCount = 0, 2257 rowIndex; 2258 for(rowIndex=0; rowIndex<siblingRows.length; rowIndex++){ 2259 if(siblingRows[rowIndex].classList.contains('super-duplicate-column-fields')) rowCount++; 2260 } 2261 if(rowCount<=1) return; 2262 2263 var i, x, nodes, found, 2264 form = this.closest('.super-form'), 2265 removedFields = {}, 2266 dataFields, 2267 foundElements = []; 2268 nodes = parent.querySelectorAll('.super-shortcode-field'); 2269 for (i = 0; i < nodes.length; ++i) { 2270 // Check if this is a file upload element, if so make sure we delete all files from the files object 2271 var fieldName = SUPER.get_field_name(nodes[i]); //SUPER.get_original_field_name = function(field){ 2272 var fieldType = SUPER.get_field_type(form, fieldName); 2273 if(fieldType.type==='file'){ 2274 var w = nodes[i].closest('.super-field-wrapper'); 2275 var x, d = w.querySelectorAll('.super-fileupload-delete'); 2276 for(x=0; x<d.length; x++){ 2277 d[x].click(); 2278 } 2279 } 2280 var $this = $(nodes[i]); 2281 var $fieldWrapper = $this.parents('.super-field-wrapper:eq(0)'); 2282 var $fieldName = $fieldWrapper.find('.super-active-files').attr('name'); 2283 var $index = $this.parents('div:eq(0)').index(); 2284 // Modify file list, and remove one element at $index 2285 // We use splice() instead of delete() because we don't want to leave the old index with an `undefined` value 2286 if(SUPER.files){ 2287 if(SUPER.files[formId]){ 2288 if(SUPER.files[formId][$fieldName]){ 2289 SUPER.files[formId][$fieldName].splice($index, 1); 2290 } 2291 } 2292 } 2293 var $parent = $this.parents('.super-fileupload-files:eq(0)'); 2294 var $wrapper = $parent.parents('.super-field-wrapper:eq(0)'); 2295 var total = $wrapper.children('.super-fileupload').data('total-file-sizes') - $this.parents('div:eq(0)').data('file-size'); 2296 $wrapper.children('.super-fileupload').data('total-file-sizes', total); 2297 $wrapper.children('input[type="hidden"]').val(''); 2298 $this.parents('div:eq(0)').remove(); 2299 var field = $fieldWrapper.find('.super-active-files')[0]; 2300 SUPER.after_field_change_blur_hook({el: field, form: form}); 2301 removedFields[nodes[i].dataset.oname] = nodes[i];
2302 } 2303 2304 // Now we can remove the dynamic column 2305 parent.remove(); 2306 2307 // @since 4.6.0 - update html field tags attribute 2308 // @since 4.6.0 - update accordion title and description field tags attribute 2309 // @since 4.9.6 - update google maps field tags attribute 2310 // Get all elements based on field tag attribute that contain one of these field names 2311 // Then convert it to an array and append the missing field names 2312 // @IMPORTANT: Only do this for elements that are NOT inside a dynamic column 2313 foundElements = []; 2314 $.each(removedFields, function( index ) { 2315 var html_fields = form.querySelectorAll('[data-tags*="{'+index+'}"], .super-google-map[data-fields*="{'+index+'}"], .super-html-content[data-fields*="{'+index+'}"]'); 2316 for (i = 0; i < html_fields.length; ++i) { 2317 if(!html_fields[i].closest('.super-duplicate-column-fields')){ 2318 found = false; 2319 for(x=0; x<foundElements.length; x++) { 2320 if($(foundElements[x]).is(html_fields[i])) found = true; 2321 } 2322 if(!found) foundElements.push(html_fields[i]); 2323 } 2324 } 2325 }); 2326 2327 var formId = 0; 2328 if(form.querySelector('input[name="hidden_form_id"]')){ 2329 formId = form.querySelector('input[name="hidden_form_id"]').value; 2330 } 2331 for (i = 0; i < foundElements.length; ++i) { 2332 var html = foundElements[i].parentNode.querySelector('textarea').value; 2333 html = SUPER.filter_foreach_statements(foundElements[i], 0, 0, html, undefined, formId, form); 2334 html = SUPER.replaceAll(html, '<%', '{'); 2335 html = SUPER.replaceAll(html, '%>', '}'); 2336 foundElements[i].innerHTML = html; 2337 } 2338 2339 // @IMPORTANT 2340 // The below hook should come before the field change hook 2341 // This is because it will update the fields attribute on for instance the calculator element 2342 // If this hook is placed below the field change hook it would cause incorrect results 2343 SUPER.after_duplicating_column_hook(form, removedFields); 2344 2345 // Now we need to update the html elements 2346 SUPER.init_replace_html_tags({el: undefined, form: form, foundElements: foundElements}); 2347 2348 // Reload google maps 2349 SUPER.google_maps_api.initMaps({form: form}); 2350 2351 }); 2352 2353 // Close messages 2354 $doc.on('click', '.super-msg .super-close', function(){ 2355 $(this).parents('.super-msg:eq(0)').fadeOut(500); 2356 }); 2357 2358 $doc.on('click', '.super-fileupload-button', function(){ 2359 SUPER.focusForm(this); 2360 SUPER.focusField(this); 2361 $(this).parents('.super-field-wrapper:eq(0)').find('.super-fileupload').trigger('click'); 2362 }); 2363 $doc.on('click', '.super-fileupload-delete', function(){ 2364 var form = SUPER.get_frontend_or_backend_form({el: this}); 2365 var formId = 0; 2366 if(form.querySelector('input[name="hidden_form_id"]')){ 2367 formId = form.querySelector('input[name="hidden_form_id"]').value; 2368 } 2369 var $this = $(this); 2370 var $fieldWrapper = $this.parents('.super-field-wrapper:eq(0)'); 2371 var $fieldName = $fieldWrapper.find('.super-active-files').attr('name'); 2372 var fileNode = $this.parents('div:eq(0)')[0]; 2373 // Only browser-pending File objects live in SUPER.files. Existing entry files and 2374 // server-issued receipts are represented by the DOM and must not shift that queue. 2375 if(fileNode && !fileNode.classList.contains('super-uploaded') && !fileNode.hasAttribute('data-upload-token')){ 2376 var pendingIndex = 0; 2377 var sibling = fileNode.previousElementSibling; 2378 while(sibling){ 2379 if(!sibling.classList.contains('super-uploaded') && !sibling.hasAttribute('data-upload-token')) pendingIndex++; 2380 sibling = sibling.previousElementSibling; 2381 } 2382 if(SUPER.files && SUPER.files[formId] && SUPER.files[formId][$fieldName]){ 2383 SUPER.files[formId][$fieldName].splice(pendingIndex, 1); 2384 } 2385 } 2386 var $parent = $this.parents('.super-fileupload-files:eq(0)'); 2387 var $wrapper = $parent.parents('.super-field-wrapper:eq(0)'); 2388 var total = $wrapper.children('.super-fileupload').data('total-file-sizes') - $this.parents('div:eq(0)').data('file-size'); 2389 $wrapper.children('.super-fileupload').data('total-file-sizes', total); 2390 $wrapper.children('input[type="hidden"]').val(''); 2391 $this.parents('div:eq(0)').remove(); 2392 var field = $fieldWrapper.find('.super-active-files')[0]; 2393 SUPER.after_field_change_blur_hook({el: field, form: form}); 2394 }); 2395 2396 // @since 1.2.4 - autosuggest text field 2397 // @since 4.4.0 - autosuggest speed improvements 2398 var autosuggestTimeout = null; 2399 $doc.on('keyup', '.super-auto-suggest .super-shortcode-field', function () { 2400 var i, 2401 el = this, 2402 parent = el.closest('.super-field'), 2403 itemsToShow = [], 2404 itemsToHide = [], 2405 value, 2406 text = '', 2407 searchValue, 2408 regex,
2409 stringBold, 2410 wrapper = el.closest('.super-field-wrapper'), 2411 nodes = wrapper.querySelectorAll('.super-dropdown-list .super-item'); 2412 2413 if (autosuggestTimeout !== null) clearTimeout(autosuggestTimeout); 2414 autosuggestTimeout = setTimeout(function () { 2415 value = el.value.toString(); 2416 if (value === '') { 2417 parent.classList.remove('super-string-found'); 2418 return false; 2419 } 2420 for (i = 0; i < nodes.length; i++) { 2421 var stringValue = nodes[i].dataset.searchValue.toString(); 2422 var stringValue_l = stringValue.toLowerCase(); 2423 var isMatch = false; 2424 if(el.dataset.logic=='start'){ 2425 // Starts with filter logic: 2426 isMatch = stringValue_l.startsWith(value); 2427 }else{ 2428 // Contains filter logic: 2429 isMatch = stringValue_l.indexOf(value) !== -1; 2430 } 2431 if( isMatch===true ) { 2432 itemsToShow.push(nodes[i]); 2433 regex = RegExp([value].join('|'), 'gi'); 2434 text = stringValue.split(';')[0]; 2435 stringBold = text.replace(regex, '<span>$&</span>'); 2436 stringBold = stringBold.replace(/ /g, '\u00a0'); 2437 nodes[i].innerHTML = stringBold; 2438 }else{ 2439 itemsToHide.push(nodes[i]); 2440 } 2441 } 2442 [].forEach.call(itemsToShow, function (el) { 2443 el.classList.add('super-match'); 2444 }); 2445 [].forEach.call(itemsToHide, function (el) { 2446 el.classList.remove('super-match'); 2447 }); 2448 if (itemsToShow.length>0) { 2449 parent.classList.add('super-string-found'); 2450 parent.classList.add('super-focus'); 2451 } else { 2452 parent.classList.remove('super-string-found'); 2453 } 2454 }, 250); 2455 }); 2456 2457 // Focus dropdowns 2458 $doc.on('click', '.super-dropdown-list:not(.super-autosuggest-tags-list)', function(e){ 2459 var i, nodes, field = e.target.closest('.super-field'); 2460 if(field.classList.contains('super-auto-suggest')) return false; 2461 SUPER.focusForm(field); 2462 if(!field.classList.contains('super-open')){ 2463 nodes = document.querySelectorAll('.super-focus'); 2464 for(i=0; i<nodes.length; i++){ 2465 nodes[i].classList.remove('super-focus'); 2466 nodes[i].classList.remove('super-open'); 2467 } 2468 field.classList.add('super-open'); 2469 SUPER.focusField(field); 2470 var searchField = e.target.closest('.super-field-wrapper').querySelector('input[name="super-dropdown-search"]'); 2471 if(searchField) searchField.focus(); 2472 }else{ 2473 if(e.target.classList.contains('super-placeholder')){ 2474 field.classList.remove('super-open'); 2475 } 2476 } 2477 }); 2478 // Unfocus dropdown 2479 document.addEventListener('click', function(e){ 2480 if(e.target.closest('.super-multipart-step')) return true; 2481 var i, nodes; 2482 if(!e.target.closest('.super-form')){ 2483 // Timepicker list is outside form element because it is 2484 // appended dynamically at the bottom of the page 2485 // hence we have to skip it explicitly 2486 if(e.target.closest('.super-timepicker-dialog')){ 2487 return true; 2488 } 2489 // If searching in dropdown, do not close it 2490 if(e.target.closest('.super-dropdown-search')){ 2491 return true; 2492 } 2493 2494 nodes = document.querySelectorAll('.super-form-focussed'); 2495 for(i = 0; i < nodes.length; i++){ 2496 nodes[i].classList.remove('super-form-focussed'); 2497 nodes[i].tabIndex = 0; 2498 SUPER.lastTabKey = undefined; 2499 } 2500 nodes = document.querySelectorAll('.super-focus'); 2501 for(i = 0; i < nodes.length; i++){ 2502 if(nodes[i].classList.contains('super-keyword-tags')){ 2503 var f = nodes[i].querySelector('.super-keyword-filter'); 2504 if(f) f.value = ''; // empty value 2505 } 2506 nodes[i].classList.remove('super-focus'); 2507 nodes[i].classList.remove('super-open'); 2508 } 2509 nodes = document.querySelectorAll('.super-open'); 2510 for(i = 0; i < nodes.length; i++){ 2511 nodes[i].classList.remove('super-open'); 2512 } 2513 if(e.target.closest('.super-setting')){ 2514 if(e.target.classList.contains('super-dropdown-placeholder')){ 2515 e.target.parentNode.classList.add('super-focus'); 2516 e.target.parentNode.classList.add('super-open'); 2517 } 2518 } 2519 }else{ 2520 if(!e.target.closest('.super-dropdown')){ 2521 nodes = document.querySelectorAll('.super-dropdown.super-focus'); 2522 for(i = 0; i < nodes.length; i++){ 2523 nodes[i].classList.remove('super-focus'); 2524 nodes[i].classList.remove('super-open'); 2525 } 2526 nodes = document.querySelectorAll('.super-dropdown.super-open'); 2527 for(i = 0; i < nodes.length; i++){ 2528 nodes[i].classList.remove('super-open'); 2529 } 2530 if(e.target.classList.contains('super-shortcode') && !e.target.classList.contains('super-field')){ 2531 SUPER.resetFocussedFields(); 2532 } 2533 } 2534 } 2535 }); 2536 2537 // @since 1.2.8 - filter dropdown options based on keyboard press 2538 var timeout = null; 2539 $doc.on('keyup', 'input[name="super-dropdown-search"]', function(e){
2540 var i, nodes, el = this, stringValue, stringValue_l, words, regex, replacement, dropdownUI, stringBold, value, field, wrapper, found = false, firstFound=null, isMatch, keyCode = e.keyCode || e.which; 2541 if( (keyCode == 13) || (keyCode == 40) || (keyCode == 38) ) { 2542 return false; 2543 } 2544 if (timeout !== null) clearTimeout(timeout); 2545 timeout = setTimeout(function () { 2546 el.value = ''; 2547 }, 1000); 2548 2549 value = el.value.toString().toLowerCase(); 2550 field = el.closest('.super-field'); 2551 wrapper = el.closest('.super-field-wrapper'); 2552 if( value==='' ) { 2553 field.classList.remove('super-string-found'); 2554 }else{ 2555 nodes = wrapper.querySelectorAll('.super-dropdown-list .super-item:not(.super-placeholder)'); 2556 for(i=0; i<nodes.length; i++){ 2557 stringValue = nodes[i].dataset.searchValue.toString(); 2558 stringValue_l = stringValue.toLowerCase(); 2559 if(el.dataset.logic=='start'){ 2560 // Starts with filter logic: 2561 isMatch = stringValue_l.startsWith(value); 2562 }else{ 2563 // Contains filter logic: 2564 isMatch = stringValue_l.indexOf(value) !== -1; 2565 } 2566 if( isMatch===true ) { 2567 if( firstFound===null ) { 2568 firstFound = nodes[i]; 2569 } 2570 found = true; 2571 words = [value]; 2572 regex = RegExp(words.join('|'), 'gi'); 2573 replacement = '<span>$&</span>'; 2574 stringBold = nodes[i].dataset.searchValue.replace(regex, replacement); 2575 stringBold = stringBold.replace(/ /g, '\u00a0'); 2576 nodes[i].innerHTML = stringBold; 2577 nodes[i].classList.add('super-focus'); 2578 }else{ 2579 nodes[i].innerHTML = stringValue; 2580 nodes[i].classList.remove('super-focus'); 2581 } 2582 } 2583 if( found===true ) { 2584 nodes = field.querySelectorAll('.super-dropdown-list .super-item.super-focus'); 2585 for(i=0; i<nodes.length; i++){ 2586 nodes[i].classList.remove('super-focus'); 2587 } 2588 // If only one found, make it selected option by default 2589 if(nodes.length===1){ 2590 field.classList.remove('super-string-found'); 2591 }else{ 2592 field.classList.add('super-string-found'); 2593 } 2594 if(firstFound) firstFound.classList.add('super-focus'); 2595 field.classList.add('super-focus'); 2596 dropdownUI = $(field).find('.super-dropdown-list'); 2597 dropdownUI.scrollTop(dropdownUI.scrollTop() - dropdownUI.offset().top + $(firstFound).offset().top - 50); 2598 }else{ 2599 // Nothing found, clear timeout 2600 el.value = ''; 2601 field.classList.remove('super-string-found'); 2602 } 2603 } 2604 }); 2605 2606 // On choosing item, populate form with data 2607 $doc.on('click', '.super-wc-order-search .super-field-wrapper:not(.super-overlap) .super-dropdown-list .super-item, .super-auto-suggest .super-field-wrapper:not(.super-overlap) .super-dropdown-list .super-item', function(){ 2608 var i, items, 2609 wrapper = this.closest('.super-field-wrapper'), 2610 parent = this.parentNode, 2611 field = this.closest('.super-field'), 2612 value = this.innerText, 2613 populate = wrapper.querySelector('.super-shortcode-field').dataset.wcosp; 2614 2615 items = parent.querySelectorAll('.super-item.super-active'); 2616 for( i = 0; i < items.length; i++ ) { 2617 items[i].classList.remove('super-active'); 2618 } 2619 this.classList.add('super-active'); 2620 wrapper.querySelector('.super-shortcode-field').value = value; 2621 field.classList.remove('super-focus'); 2622 field.classList.remove('super-open'); 2623 field.classList.remove('super-string-found'); 2624 wrapper.classList.add('super-overlap'); 2625 field.classList.add('super-filled'); 2626 SUPER.after_field_change_blur_hook({el: wrapper.querySelector('.super-shortcode-field')}); 2627 if(populate=='true'){ 2628 SUPER.populate_form_data_ajax({el: field, clear: false}); 2629 } 2630 }); 2631 // On removing item 2632 $doc.on('click', '.super-wc-order-search .super-field-wrapper.super-overlap li, .super-auto-suggest .super-field-wrapper.super-overlap li', function(){ 2633 var i,items, 2634 el = this.closest('.super-field'), 2635 wrapper = this.closest('.super-field-wrapper'), 2636 field = wrapper.querySelector('.super-shortcode-field'); 2637 2638 field.value = ''; 2639 items = wrapper.querySelectorAll('.super-active'); 2640 for( i = 0; i < items.length; i++ ) { 2641 items[i].classList.remove('super-active'); 2642 } 2643 wrapper.classList.remove('super-overlap'); 2644 el.classList.remove('super-filled'); 2645 field.focus(); 2646 SUPER.after_field_change_blur_hook({el: field}); 2647 }); 2648 2649 // Update dropdown 2650 $doc.on('click', '.super-dropdown .super-dropdown-list .super-item:not(.super-placeholder)', function(e){
2651 SUPER.focusForm(this); 2652 SUPER.focusField(this); 2653 var i, nodes, 2654 form, 2655 field = this.closest('.super-field'), 2656 input, 2657 wrapper, 2658 parent, 2659 placeholder, 2660 value, 2661 name, 2662 validation, 2663 max, 2664 total, 2665 names, 2666 values, 2667 counter; 2668 2669 e.stopPropagation(); 2670 form = SUPER.get_frontend_or_backend_form({el: this}); 2671 wrapper = this.closest('.super-field-wrapper'); 2672 input = wrapper.querySelector('.super-shortcode-field'); 2673 parent = this.closest('.super-dropdown-list'); 2674 placeholder = parent.querySelector('.super-placeholder'); 2675 if(!parent.classList.contains('multiple')){ 2676 value = this.dataset.value; 2677 name = this.innerHTML; 2678 placeholder.innerHTML = name; 2679 placeholder.dataset.value = value; 2680 placeholder.classList.add('super-active'); 2681 nodes = parent.querySelectorAll('.super-item'); 2682 for ( i = 0; i < nodes.length; i++){ 2683 nodes[i].classList.remove('super-active'); 2684 } 2685 this.classList.add('super-active'); 2686 if(input) input.value = value; 2687 field.classList.remove('super-open'); 2688 }else{ 2689 max = (input.dataset.maxlength ? parseInt(input.dataset.maxlength, 10) : 1); 2690 total = parent.querySelectorAll('.super-item.super-active:not(.super-placeholder').length; 2691 if(this.classList.contains('super-active')){ 2692 this.classList.remove('super-active'); 2693 }else{ 2694 if(total >= max) return false; 2695 this.classList.add('super-active'); 2696 if(total+1 >= max){ 2697 field.classList.remove('super-open'); 2698 } 2699 } 2700 names = ''; 2701 values = ''; 2702 nodes = parent.querySelectorAll('.super-item.super-active:not(.super-placeholder'); 2703 total = nodes.length; 2704 counter = 1; 2705 for ( i = 0; i < nodes.length; i++){ 2706 if((total == counter) || (total==1)){ 2707 names += nodes[i].innerHTML; 2708 values += nodes[i].dataset.value; 2709 }else{ 2710 names += nodes[i].innerHTML+','; 2711 values += nodes[i].dataset.value+','; 2712 } 2713 counter++; 2714 } 2715 placeholder.innerHTML = names; 2716 if(input) input.value = values; 2717 } 2718 2719 // Switch to different language when clicked 2720 if(field.closest('.super-i18n-switcher')){ 2721 // Generate new nonce 2722 var $this = $(this), $form = $this.closest('.super-form'); 2723 // Remove initialized class 2724 $form.find('.super-button').remove(); 2725 $form.removeClass('super-initialized'); 2726 $.ajax({ 2727 url: super_elements_i18n.ajaxurl, 2728 type: 'post', 2729 data: { 2730 action: 'super_create_nonce' 2731 }, 2732 success: function (nonce) { 2733 $form.find('input[name="sf_nonce"]').val(nonce.trim()); 2734 }, 2735 complete: function(){ 2736 var $form_id = $form.find('input[name="hidden_form_id"]').val(), 2737 $sf_nonce = $form.find('input[name="sf_nonce"]').val(), 2738 $i18n = $this.attr('data-value'); 2739 2740 $this.parent().children('.super-item').removeClass('super-active'); 2741 $this.addClass('super-active'); 2742 // Also move to placeholder 2743 $this.parents('.super-dropdown').children('.super-dropdown-placeholder').html($this.html()); 2744 2745 // Get URL parameters 2746 var $queryString = window.location.search; 2747 var $parameters = SUPER.getAllUrlParams($queryString); 2748 $.ajax({
2749 url: super_elements_i18n.ajaxurl, 2750 type: 'post', 2751 data: { 2752 action: 'super_language_switcher', 2753 form_id: $form_id, 2754 i18n: $i18n, 2755 parameters: $parameters, 2756 sf_nonce: $sf_nonce, 2757 }, 2758 success: function (result) { 2759 var data = JSON.parse(result); 2760 if(data.error && data.error===true){ 2761 var i, nodes = document.querySelectorAll('.super-msg'); 2762 for (i = 0; i < nodes.length; i++) { 2763 nodes[i].remove(); 2764 } 2765 var $html = '<div class="super-msg super-error">'; 2766 $html += data.msg; 2767 $html += '<span class="super-close"></span>'; 2768 $html += '</div>'; 2769 $($html).prependTo($form); 2770 }else{ 2771 if(data.rtl==true){ 2772 $form.addClass('super-rtl'); 2773 }else{ 2774 $form.removeClass('super-rtl'); 2775 } 2776 $form.find('form').html(data.html); 2777 $form.data('i18n', $i18n); 2778 } 2779 }, 2780 complete: function(){ 2781 $form.removeClass('super-initialized'); 2782 $form.removeClass('super-rendered'); 2783 $form.find('.super-multipart-progress').remove(); 2784 $form.find('.super-multipart-steps').remove(); 2785 }, 2786 error: function (xhr, ajaxOptions, thrownError) { 2787 // eslint-disable-next-line no-console 2788 console.log(xhr, ajaxOptions, thrownError); 2789 alert(super_elements_i18n.failed_to_process_data); 2790 } 2791 }); 2792 }, 2793 error: function (xhr, ajaxOptions, thrownError) { 2794 // eslint-disable-next-line no-console 2795 console.log(xhr, ajaxOptions, thrownError); 2796 alert('Failed to generate nonce!'); 2797 } 2798 }); 2799 return true; 2800 } 2801 2802 if(input && input.value===''){ 2803 field.classList.remove('super-filled'); 2804 }else{ 2805 field.classList.add('super-filled'); 2806 } 2807 validation = input.dataset.validation; 2808 if(typeof validation !== 'undefined' && validation !== false){ 2809 SUPER.handle_validations({el: input, form: form, validation: validation}); 2810 } 2811 2812 SUPER.after_field_change_blur_hook({el: input}); 2813 }); 2814 2815 $doc.on('click','.super-back-to-top',function(){ 2816 var form = SUPER.get_frontend_or_backend_form({el: this}); 2817 if(form.closest('.super-popup-content')){ 2818 $(form.closest('.super-popup-content')).animate({ 2819 scrollTop: $(form).offset().top-200 2820 }, 1000); 2821 }else{ 2822 $('html, body').animate({ 2823 scrollTop: $(form).offset().top-200 2824 }, 1000); 2825 } 2826 }); 2827 2828 $doc.on('change', '.super-shortcode-field', function (e) { 2829 if(this.classList.contains('super-fileupload')) return false; 2830 var keyCode = e.keyCode || e.which; 2831 if (keyCode != 9) { 2832 var form = SUPER.get_frontend_or_backend_form({el: this}), 2833 validation = this.dataset.validation, 2834 conditionalValidation = this.dataset.conditionalValidation;
2835 SUPER.handle_validations({el: this, form: form, validation: validation, conditionalValidation: conditionalValidation}); 2836 SUPER.after_field_change_blur_hook({el: this}); 2837 } 2838 }); 2839 2840 SUPER.simulateRadioItemClicked = function(e, el){ 2841 var $form,$this,$parent,$field,$active,$validation; 2842 if( e.target.localName=='a' ) { 2843 if(e.target.target=='_blank'){ 2844 window.open( 2845 e.target.href, 2846 '_blank' // <- This is what makes it open in a new window. 2847 ); 2848 }else{ 2849 window.location.href = e.target.href; 2850 } 2851 }else{ 2852 $form = SUPER.get_frontend_or_backend_form({el: el}); 2853 SUPER.focusNextTabField(e, el, $form, el); 2854 $this = el.querySelector('input[type="radio"]'); 2855 if(el.classList.contains('super-active')) return true; 2856 $parent = el.closest('.super-field-wrapper'); 2857 $field = $parent.querySelector('.super-shortcode-field'); 2858 $active = $parent.querySelector('.super-item.super-active'); 2859 if($active){ 2860 $active.classList.remove('super-active'); 2861 $active.classList.remove('super-focus'); 2862 } 2863 el.classList.add('super-active'); 2864 el.classList.add('super-focus'); 2865 el.closest('.super-field').classList.add('super-focus'); 2866 $validation = $field.dataset.validation; 2867 $field.value = $this.value; 2868 if(typeof $validation !== 'undefined' && $validation !== false){ 2869 SUPER.handle_validations({el: $field, form: $form, validation: $validation}); 2870 } 2871 SUPER.after_field_change_blur_hook({el: $field}); 2872 } 2873 return false; 2874 }; 2875 $doc.on('click', '.super-form .super-radio > .super-field-wrapper .super-item', function (e) { 2876 return SUPER.simulateRadioItemClicked(e, this); 2877 }); 2878 2879 SUPER.simulateCheckboxItemClicked = function(e, el){ 2880 var i, 2881 $form, 2882 $checked, 2883 $value, 2884 $checkbox, 2885 $parent, 2886 $field, 2887 $counter, 2888 $maxlength, 2889 $validation; 2890 2891 if( e.target.localName=='a' ) { 2892 if(e.target.target=='_blank'){ 2893 window.open( 2894 e.target.href, 2895 '_blank' // <- This is what makes it open in a new window. 2896 ); 2897 }else{ 2898 window.location.href = e.target.href; 2899 } 2900 }else{ 2901 $form = SUPER.get_frontend_or_backend_form({el: el}); 2902 SUPER.focusNextTabField(e, el, $form, el); 2903 2904 $checkbox = el.querySelector('input[type="checkbox"]'); 2905 $parent = $checkbox.closest('.super-field-wrapper'); 2906 $field = $parent.querySelector('input[type="hidden"]'); 2907 $counter = 0; 2908 $maxlength = $parent.querySelector('.super-shortcode-field').dataset.maxlength; 2909 $checked = $parent.querySelectorAll('label.super-active'); 2910 if(el.classList.contains('super-active')){ 2911 el.classList.remove('super-active'); 2912 }else{ 2913 if($checked.length >= parseInt($maxlength, 10)){ 2914 if(parseInt($maxlength,10)===1){ 2915 for (i = 0; i < $checked.length; ++i) { 2916 $checked[i].classList.remove('super-active'); 2917 $checked[i].querySelector('input').checked = false; 2918 } 2919 }else{ 2920 return false; 2921 } 2922 } 2923 el.classList.add('super-active'); 2924 } 2925 $checked = $parent.querySelectorAll('label.super-active'); 2926 $value = ''; 2927 for (i = 0; i < $checked.length; ++i) { 2928 if ($counter === 0) $value = $checked[i].querySelector('input').value; 2929 if ($counter !== 0) $value = $value + ',' + $checked[i].querySelector('input').value; 2930 $counter++; 2931 } 2932 $field.value = $value; 2933 $validation = $field.dataset.validation; 2934 if(typeof $validation !== 'undefined' && $validation !== false){
2935 SUPER.handle_validations({el: $field, form: $form, validation: $validation}); 2936 } 2937 SUPER.after_field_change_blur_hook({el: $field}); 2938 } 2939 return false; 2940 }; 2941 $doc.on('click', '.super-form .super-checkbox > .super-field-wrapper .super-item', function (e) { 2942 return SUPER.simulateCheckboxItemClicked(e, this); 2943 }); 2944 2945 $doc.on('change', '.super-form select', function () { 2946 var $form = SUPER.get_frontend_or_backend_form({el: this}), 2947 $parent = this.closest('.super-field'), 2948 $min = this.dataset.minlength, 2949 $max = this.dataset.maxlength, 2950 $count, 2951 $validation; 2952 if($parent && (typeof this.options !== 'undefined')){ 2953 $count = SUPER.selection_value_count(this, $parent); 2954 if(($min>0) && ($count < parseInt($min, 10))){ 2955 SUPER.handle_errors(this); 2956 }else if(($max!=='') && ($count > parseInt($max, 10))){ 2957 SUPER.handle_errors(this); 2958 }else{ 2959 this.closest('.super-field').classList.remove('super-error-active'); 2960 } 2961 }else if(($min>0) && (SUPER.unicode_length(this.value) < parseInt($min, 10))){ 2962 SUPER.handle_errors(this); 2963 }else if(($max!=='') && (SUPER.unicode_length(this.value) > parseInt($max, 10))){ 2964 SUPER.handle_errors(this); 2965 }else{ 2966 this.closest('.super-field').classList.remove('super-error-active'); 2967 } 2968 $validation = this.dataset.validation; 2969 if(typeof $validation !== 'undefined' && $validation !== false){ 2970 SUPER.handle_validations({el: this, form: $form, validation: $validation}); 2971 } 2972 SUPER.after_field_change_blur_hook({el: this}); 2973 }); 2974 2975 $doc.on('mouseleave','.super-button .super-button-wrap',function(){ 2976 this.parentNode.classList.remove('super-focus'); 2977 SUPER.init_button_colors( this ); 2978 }); 2979 $doc.on('mouseover','.super-button .super-button-wrap',function(){ 2980 SUPER.init_button_hover_colors( this.parentNode ); 2981 }); 2982 2983 // Multi Part Columns 2984 $doc.on('click','.super-multipart-step',function(e){ 2985 var i, nodes, 2986 el = this, 2987 form = el.closest('.super-form'), 2988 stepParams = (form.dataset.stepParams ? form.dataset.stepParams : ''), // default 2989 form_id = form.querySelector('input[name="hidden_form_id"]').value, 2990 currentActive = form.querySelector('.super-multipart.super-active'), 2991 currentActiveTab = form.querySelector('.super-multipart-step.super-active'), 2992 activeChildren = Array.prototype.slice.call( currentActiveTab.parentNode.children ), 2993 activeIndex = activeChildren.indexOf(currentActiveTab), 2994 clickedChildren = Array.prototype.slice.call( el.parentNode.children ), 2995 index = clickedChildren.indexOf(el), 2996 total = form.querySelectorAll('.super-multipart').length, 2997 validate, 2998 result, 2999 progress, 3000 multipart, 3001 skip; 3002 3003 // @since 2.0.0 - validate multi-part before going to next step 3004 if(activeIndex < index){ // Always allow going to previous step 3005 validate = currentActive.dataset.validate; 3006 if(validate=='true'){ 3007 result = SUPER.validate_form({el: el, form: currentActive, submitButton: el, validateMultipart: true, event: e}); 3008 if(result!==true) return false; 3009 } 3010 } 3011 if(stepParams!=='false'){ 3012 window.location.hash = 'step-'+form_id+'-'+(parseInt(index,10)+1); 3013 } 3014 3015 progress = 100 / total; 3016 progress = progress * (index+1); 3017 multipart = form.querySelectorAll('.super-multipart')[index]; 3018 if(form.querySelector('.super-multipart-progress-bar')){ 3019 form.querySelector('.super-multipart-progress-bar').style.width = progress+'%'; 3020 } 3021 nodes = form.querySelectorAll('.super-multipart-step'); 3022 for ( i = 0; i < nodes.length; i++){ 3023 nodes[i].classList.remove('super-active'); 3024 } 3025 nodes = form.querySelectorAll('.super-multipart'); 3026 for ( i = 0; i < nodes.length; i++){ 3027 nodes[i].classList.remove('super-active'); 3028 } 3029 multipart.classList.add('super-active'); 3030 el.classList.add('super-active'); 3031 3032 // @since 3.3.0 - make sure to skip the multi-part if no visible elements are found 3033 skip = SUPER.skipMultipart(el, form, index, activeIndex); 3034 if(skip===true) return false; 3035 3036 // Focus first TAB index field in next multi-part 3037 SUPER.focusFirstTabIndexField(e, form, multipart); 3038 3039 // Update HTML element to reflect changes e.g foreach() and if statements 3040 SUPER.init_replace_html_tags({form: form}); 3041 3042 // Required for toggle field and other possible elements to rerender proper size 3043 SUPER.init_super_responsive_form_fields({form: form}); 3044 }); 3045 3046 // Multi Part Next Prev Buttons 3047 $doc.on('click','.super-prev-multipart, .super-next-multipart',function(e){
3048 if(this.classList.contains('super-prev-multipart')){ 3049 SUPER.switchMultipart(e, this, 'prev'); 3050 }else{ 3051 SUPER.switchMultipart(e, this, 'next'); 3052 } 3053 }); 3054 3055 // @since 4.9.3 - Adaptive Placeholders 3056 SUPER.init_adaptive_placeholder(); 3057 }); 3058 3059 3060 (function () { 3061 "use strict"; // Minimize mutable state :) 3062 // Define all the events for our elements 3063 var app = {}; 3064 // querySelector shorthand 3065 app.q = function (s) { 3066 return document.querySelector(s); 3067 }; 3068 // querySelectorAll shorthand 3069 app.qa = function (s) { 3070 return document.querySelectorAll(s); 3071 }; 3072 // querySelectorAll based on parent shorthand 3073 app.qap = function (s, p) { 3074 // If no parent provided, default to Top element 3075 if (typeof p === 'undefined') p = app.wrapper; 3076 if (typeof p === 'string') p = app.wrapper.querySelector(p); 3077 return p.querySelectorAll(s); 3078 }; 3079 // Remove all elements 3080 app.remove = function (e) { 3081 if (typeof e === 'undefined' || !e) return true; 3082 if (e.length) { 3083 for (var i = 0; i < e.length; i++) { 3084 e[i].remove(); 3085 } 3086 } else { 3087 e.remove(); 3088 } 3089 return true; 3090 }; 3091 // Remove class from elements 3092 app.removeClass = function (elements, class_name) { 3093 if (elements.length === 0) return true; 3094 if (elements.length) { 3095 for (var key = 0; key < elements.length; key++) { 3096 elements[key].classList.remove(class_name); 3097 } 3098 } else { 3099 elements.classList.remove(class_name); 3100 } 3101 }; 3102 // Add class from elements 3103 app.addClass = function (elements, class_name) { 3104 if (elements.length === 0) return true; 3105 if (elements.length) { 3106 for (var key = 0; key < elements.length; key++) { 3107 elements[key].classList.add(class_name); 3108 } 3109 } else { 3110 elements.classList.add(class_name); 3111 } 3112 }; 3113 // Get index of element based on parent node 3114 app.index = function (node, class_name) { 3115 var index = 0; 3116 while (node.previousElementSibling) { 3117 node = node.previousElementSibling; 3118 // Based on specified class name 3119 if (class_name) { 3120 if (node.classList.contains(class_name)) { 3121 index++; 3122 } 3123 } else { 3124 index++; 3125 } 3126 3127 } 3128 return index; 3129 }; 3130 // Check if clicked inside element, by looping over it's "path" 3131 app.inPath = function (e, class_name) { 3132 if (!e.path) return false; 3133 var found = false; 3134 Object.keys(e.path).forEach(function (key) { 3135 if (e.path[key].classList) { 3136 if (e.path[key].classList.contains(class_name)) { 3137 found = true; 3138 } 3139 } 3140 }); 3141 return found; 3142 }; 3143 3144 // Keyword element functions 3145 app.autosuggestTagsTimeout = null; 3146 app.keywords = { 3147 updateValue: function(field, tagsContainer, keywordField, filterField, wrapper){ 3148 var i, values=[], nodes = wrapper.querySelectorAll('.super-autosuggest-tags > span'); 3149 for(i=0; i<nodes.length; i++){ 3150 values.push(nodes[i].dataset.value); 3151 } 3152 keywordField.value = values.join(','); 3153 filterField.value = ''; 3154 filterField.focus(); 3155 if(!app.qap('span', tagsContainer).length){ 3156 field.classList.remove('super-filled'); 3157 }else{ 3158 field.classList.add('super-filled'); 3159 } 3160 // Scroll to bottom of tags container 3161 tagsContainer.scrollTop = tagsContainer.scrollHeight; 3162 SUPER.after_field_change_blur_hook({el: keywordField}); 3163 }, 3164 add: function(e, target){ 3165 var i, 3166 html = '', 3167 field = target.closest('.super-field'), 3168 value = target.dataset.value, // first_choice 3169 searchValue = target.dataset.searchValue, // First choice 3170 wrapper = target.closest('.super-field-wrapper'), 3171 keywordField = wrapper.querySelector('.super-shortcode-field'), 3172 tagsContainer = wrapper.querySelector('.super-autosuggest-tags'), 3173 tags = tagsContainer.querySelectorAll('.super-keyword-tag'), 3174 filterField = wrapper.querySelector('.super-keyword-filter'), 3175 maxlength = parseInt(keywordField.dataset.maxlength, 10), 3176 existingTags = []; 3177 3178 // Check if limit is reached 3179 if( maxlength!==0 && tags.length>=maxlength ) { 3180 field.classList.add('super-filled'); 3181 field.classList.remove('super-string-found'); 3182 field.classList.add('super-focus');
3183 app.keywords.updateValue(field, tagsContainer, keywordField, filterField, wrapper); 3184 return false; 3185 } 3186 // Loop over allready existing tags and add their value to an array 3187 for(i=0; i < tags.length; i++){ 3188 existingTags.push(tags[i].dataset.value); 3189 } 3190 // if this tag doesn't exists yet 3191 if(existingTags.indexOf(value)===-1){ 3192 var node = document.createElement('span'); 3193 node.className = 'super-noselect super-keyword-tag'; 3194 node.setAttribute('sfevents', '{"click":"keywords.remove"}'); 3195 node.dataset.value = value; 3196 node.title = 'remove this tag'; 3197 node.innerHTML = searchValue; 3198 filterField.parentNode.insertBefore(node, filterField.nextElementSibling); 3199 target.classList.add('super-active'); 3200 } 3201 if(!app.qap('span', tagsContainer).length){ 3202 field.classList.remove('super-filled'); 3203 }else{ 3204 field.classList.add('super-filled'); 3205 } 3206 field.classList.remove('super-string-found'); 3207 field.classList.add('super-focus'); 3208 app.keywords.updateValue(field, tagsContainer, keywordField, filterField, wrapper); 3209 }, 3210 remove: function(e, target){ 3211 var wrapper = target.closest('.super-field-wrapper'), 3212 keywordField = wrapper.querySelector('.super-shortcode-field'), 3213 filterField = wrapper.querySelector('.super-keyword-filter'), 3214 field = target.closest('.super-field'), 3215 tagsContainer = wrapper.querySelector('.super-autosuggest-tags'); 3216 3217 target.remove(); 3218 filterField.focus(); 3219 app.keywords.updateValue(field, tagsContainer, keywordField, filterField, wrapper); 3220 }, 3221 filter: function(e, target){ 3222 // On keyup filter any keyword tags from the list 3223 var i, 3224 parent = target.closest('.super-field'), 3225 counter = 0, 3226 html = '', 3227 tag, tags, 3228 duplicates = {}, 3229 method = target.dataset.method, 3230 splitMethod = target.dataset.splitMethod, 3231 itemsToShow = [], 3232 itemsToHide = [], 3233 value, 3234 text = '', 3235 searchValue, 3236 regex, 3237 stringBold, 3238 wrapper = target.closest('.super-field-wrapper'), 3239 field = target.closest('.super-field'), 3240 tagsContainer = wrapper.querySelector('.super-autosuggest-tags'), 3241 keywordField = wrapper.querySelector('.super-shortcode-field'), 3242 filterField = wrapper.querySelector('.super-keyword-filter'), 3243 max = (keywordField.dataset.maxlength ? parseInt(keywordField.dataset.maxlength, 10) : 0), 3244 nodes = wrapper.querySelectorAll('.super-dropdown-list .super-item'); 3245 3246 if(method=='free'){ 3247 if(splitMethod=='both') tags = target.value.split(/[ ,]+/); 3248 if(splitMethod=='comma') tags = target.value.split(/[,]+/); 3249 if(splitMethod=='space') tags = target.value.split(/[ ]+/); 3250 if(tags.length>1){ 3251 tag = tags[0]; 3252 // First check if already exists 3253 if(keywordField.value.split(',').indexOf(tag)===-1){ 3254 if(typeof duplicates[tag]==='undefined'){ 3255 counter = tagsContainer.querySelectorAll('.super-keyword-tag').length; 3256 if(max===0 || counter<max){ 3257 if(splitMethod!='comma') tag = tag.replace(/ /g,''); 3258 if( (tag!=='') && (tag.length>1) ) { 3259 var node = document.createElement('span'); 3260 node.className = 'super-noselect super-keyword-tag'; 3261 node.setAttribute('sfevents', '{"click":"keywords.remove"}'); 3262 node.dataset.value = tag; 3263 node.innerHTML = tag; 3264 filterField.parentNode.insertBefore(node, filterField); 3265 target.classList.add('super-active'); 3266 } 3267 } 3268 }
3269 duplicates[tag] = tag; 3270 } 3271 app.keywords.updateValue(field, tagsContainer, keywordField, target, wrapper); 3272 } 3273 }else{ 3274 if (app.autosuggestTagsTimeout !== null) clearTimeout(app.autosuggestTagsTimeout); 3275 app.autosuggestTagsTimeout = setTimeout(function () { 3276 value = target.value.toString().toLowerCase(); 3277 if (value === '') { 3278 parent.classList.remove('super-string-found'); 3279 parent.classList.remove('super-no-match'); 3280 return false; 3281 } 3282 for (i = 0; i < nodes.length; i++) { 3283 var stringValue = nodes[i].dataset.searchValue.toString(); 3284 var stringValue_l = stringValue.toLowerCase(); 3285 var isMatch = false; 3286 if(keywordField.dataset.logic=='start'){ 3287 // Starts with filter logic: 3288 isMatch = stringValue_l.startsWith(value); 3289 }else{ 3290 // Contains filter logic: 3291 isMatch = stringValue_l.indexOf(value) !== -1; 3292 } 3293 if( isMatch===true ) { 3294 itemsToShow.push(nodes[i]); 3295 regex = RegExp([value].join('|'), 'gi'); 3296 text = stringValue.split(';')[0]; 3297 stringBold = '<span class="super-wp-tag">'+text.replace(regex, '<span>$&</span>')+'</span>'; 3298 stringBold = stringBold.replace(/\r?\n|\r/g, ""); 3299 nodes[i].innerHTML = stringBold; 3300 }else{ 3301 itemsToHide.push(nodes[i]); 3302 } 3303 } 3304 [].forEach.call(itemsToShow, function (el) { 3305 el.style.display = 'inline-block'; 3306 el.classList.add('super-active'); 3307 }); 3308 [].forEach.call(itemsToHide, function (el) { 3309 el.style.display = 'none'; 3310 el.classList.remove('super-active'); 3311 }); 3312 if (itemsToShow.length>0) { 3313 parent.classList.add('super-string-found'); 3314 parent.classList.add('super-focus'); 3315 parent.classList.remove('super-no-match'); 3316 } else { 3317 parent.classList.remove('super-string-found'); 3318 parent.classList.add('super-no-match'); 3319 } 3320 }, 250); 3321 } 3322 } 3323 } 3324 3325 // Trigger Events 3326 app.triggerEvent = function (e, target, eventType) { 3327 // Get element actions, and check for multiple event methods 3328 var actions, _event, _function, _currentFunc, sfevents; 3329 try { 3330 sfevents = JSON.parse(target.attributes.sfevents.value); 3331 } catch (error) { 3332 // eslint-disable-next-line no-console 3333 console.log(error); 3334 alert(error); 3335 } 3336 Object.keys(sfevents).forEach(function (key) { 3337 // Check if contains comma, meaning it has multiple event methods for this function 3338 _event = key.split(','); 3339 if (_event.length > 1) { 3340 // Seems it contains multiple events, so let's split them up and create a new sfevents object 3341 Object.keys(_event).forEach(function (e_key) { 3342 sfevents[_event[e_key]] = sfevents[key]; 3343 }); 3344 delete sfevents[key]; 3345 } 3346 }); 3347 actions = sfevents[eventType]; 3348 if (actions) { 3349 if(typeof actions === 'string'){ 3350 _currentFunc = app; 3351 if(actions.split('.').length>1){ 3352 _function = actions.split('.'); 3353 for (var i = 0; i < _function.length; i++) {
3354 // Skip if function name is 'app' 3355 if (_function[i] == 'app') continue; 3356 if (_currentFunc[_function[i]]) { 3357 _currentFunc = _currentFunc[_function[i]]; 3358 } else { 3359 // eslint-disable-next-line no-console 3360 console.log('Function ' + actions + '() is undefined!'); 3361 break; 3362 } 3363 } 3364 _currentFunc(e, target, eventType, actions); 3365 }else{ 3366 if (_currentFunc[actions]) { 3367 _currentFunc = _currentFunc[actions]; 3368 _currentFunc(e, target, eventType, actions); 3369 } else { 3370 // eslint-disable-next-line no-console 3371 console.log('Function ' + actions + '() is undefined!'); 3372 } 3373 } 3374 }else{ 3375 Object.keys(actions).forEach(function (key) { // key = function name 3376 _currentFunc = app; 3377 _function = key.split('.'); 3378 for (var i = 0; i < _function.length; i++) { 3379 // Skip if function name is 'app' 3380 if (_function[i] == 'app') continue; 3381 if (_currentFunc[_function[i]]) { 3382 _currentFunc = _currentFunc[_function[i]]; 3383 } else { 3384 // eslint-disable-next-line no-console 3385 console.log('Function ' + key + '() is undefined!'); 3386 break; 3387 } 3388 } 3389 _currentFunc(e, target, eventType, actions[key]); 3390 }); 3391 } 3392 } 3393 }; 3394 // Equivalent for jQuery's .on() function 3395 app.delegate = function (element, event, elements, callback) { 3396 element.addEventListener(event, function (event) { 3397 var target = event.target; 3398 while (target && target !== this) { 3399 if (target.matches(elements)) { 3400 callback(event, target); 3401 return false; 3402 } 3403 target = target.parentNode; 3404 } 3405 }); 3406 }; 3407 // Iterate over all events, and listen to any event being triggered 3408 app.events = { 3409 click: [ 3410 'body', 3411 '.super-keyword-filter', 3412 '.super-keyword-tags .super-item', 3413 '.super-keyword-tag' 3414 ], 3415 mousedown: [ 3416 '.super-keyword-filter' 3417 ], 3418 onblur: [ 3419 '.super-keyword-filter' 3420 ], 3421 keyup: [ 3422 '.super-keyword-filter' 3423 ], 3424 keydown: [ 3425 '.super-keyword-filter' 3426 ] 3427 }; 3428 Object.keys(app.events).forEach(function (eventType) { 3429 var elements = app.events[eventType].join(", "); 3430 app.delegate(document, eventType, elements, function (e, target) { 3431 // Trigger event(s) 3432 if (typeof target.attributes.sfevents !== 'undefined') app.triggerEvent(e, target, eventType); 3433 }); 3434 }); 3435 })(jQuery); 3436})(jQuery);
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.