1/* global wpforms_settings,grecaptcha,wpforms_validate,wpforms_timepicker */ 2 3;(function($) { 4 5 'use strict'; 6 7 var WPForms = { 8 9 /** 10 * Start the engine. 11 * 12 * @since 1.2.3 13 */ 14 init: function() { 15 16 // Document ready 17 $(document).ready(WPForms.ready); 18 19 // Page load 20 $(window).on('load', WPForms.load); 21 22 WPForms.bindUIActions(); 23 }, 24 25 /** 26 * Document ready. 27 * 28 * @since 1.2.3 29 */ 30 ready: function() { 31 32 // Set user identifier 33 WPForms.setUserIndentifier(); 34 35 WPForms.loadValidation(); 36 WPForms.loadDatePicker(); 37 WPForms.loadTimePicker(); 38 WPForms.loadInputMask(); 39 WPForms.loadPayments(); 40 41 // Randomize elements. 42 $( '.wpforms-randomize' ).each( function() { 43 $( this ).randomize(); 44 }); 45 46 $(document).trigger('wpformsReady'); 47 }, 48 49 /** 50 * Page load. 51 * 52 * @since 1.2.3 53 */ 54 load: function() { 55 56 }, 57 58 //--------------------------------------------------------------------// 59 // Initializing 60 //--------------------------------------------------------------------// 61 62 /** 63 * Load jQuery Validation. 64 * 65 * @since 1.2.3 66 */ 67 loadValidation: function() { 68 69 // Only load if jQuery validation library exists 70 if (typeof $.fn.validate !== 'undefined') { 71 72 // jQuery Validation library will not correctly validate 73 // fields that do not have a name attribute, so we use the 74 // `wpforms-input-temp-name` class to add a temporary name 75 // attribute before validation is initialized, then remove it 76 // before the form submits. 77 $( '.wpforms-input-temp-name' ).each(function( index, el ) { 78 var random = Math.floor( Math.random() * 9999 ) + 1; 79 $( this ).attr( 'name', 'wpf-temp-' + random ); 80 }); 81 82 $.validator.messages.required = wpforms_settings.val_required; 83 $.validator.messages.url = wpforms_settings.val_url; 84 $.validator.messages.email = wpforms_settings.val_email; 85 $.validator.messages.number = wpforms_settings.val_number; 86 87 // Payments: Validate method for Credit Card Number 88 if(typeof $.fn.payment !== 'undefined') { 89 $.validator.addMethod( "creditcard", function(value, element) { 90 //var type = $.payment.cardType(value); 91 var valid = $.payment.validateCardNumber(value); 92 return this.optional(element) || valid; 93 }, wpforms_settings.val_creditcard); 94 // @todo validate CVC and expiration 95 } 96 97 // Validate method for file extensions 98 $.validator.addMethod( "extension", function(value, element, param) { 99 param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif"; 100 return this.optional(element) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) ); 101 }, wpforms_settings.val_fileextension ); 102 103 // Validate method for file size 104 $.validator.addMethod("maxsize", function(value, element, param) { 105 var maxSize = param, 106 optionalValue = this.optional(element), 107 i, len, file; 108 if (optionalValue) { 109 return optionalValue; 110 } 111 if (element.files && element.files.length) { 112 i = 0; 113 len = element.files.length; 114 for (; i < len; i++) { 115 file = element.files[i]; 116 if (file.size > maxSize) { 117 return false; 118 } 119 } 120 } 121 return true; 122 }, wpforms_settings.val_filesize); 123 124 // Validate email addresses 125 $.validator.methods.email = function( value, element ) { 126 return this.optional( element ) || /^[a-z0-9.!#$%&'*+\/=?^_`{|}~-]+@((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/i.test( value ); 127 }; 128 129 // Validate confirmations 130 $.validator.addMethod("confirm", function(value, element, param) { 131 return $.validator.methods.equalTo.call(this, value, element, param); 132 }, wpforms_settings.val_confirm); 133 134 // Validate required payments 135 $.validator.addMethod( "required-payment", function( value, element ) { 136 return WPForms.amountSanitize( value ) > 0; 137 }, wpforms_settings.val_requiredpayment ); 138 139 // Validate 12-hour time 140 $.validator.addMethod( "time12h", function( value, element ) { 141 return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value ); 142 }, wpforms_settings.val_time12h ); 143 144 // Validate 24-hour time 145 $.validator.addMethod( "time24h", function( value, element ) { 146 return this.optional(element) || /^(([0-1]?[0-9])|([2][0-3])):([0-5]?[0-9])(\ ?[AP]M)?$/i.test(value); 147 }, wpforms_settings.val_time24h ); 148 149 // Finally load jQuery Validation library for our forms 150 $('.wpforms-validate').each(function() { 151 var form = $(this), 152 formID = form.data('formid'), 153 properties; 154 155 // TODO: cleanup this BC with wpforms_validate. 156 if (typeof window['wpforms_'+formID] !== 'undefined' && window['wpforms_'+formID].hasOwnProperty('val
156idate')) { 157 properties = window['wpforms_'+formID].validate; 158 } else if ( typeof wpforms_validate !== 'undefined') { 159 properties = wpforms_validate; 160 } else { 161 properties = { 162 errorClass: 'wpforms-error', 163 validClass: 'wpforms-valid', 164 errorPlacement: function( error, element ) { 165 if ( element.attr( 'type' ) === 'radio' || element.attr( 'type' ) === 'checkbox' ) { 166 if ( element.hasClass( 'wpforms-likert-scale-option' ) ) { 167 if ( element.closest( 'table' ).hasClass( 'single-row' ) ) { 168 element.closest( 'table' ).after( error ); 169 } else { 170 element.closest( 'tr' ).find( 'th' ).append( error ); 171 } 172 } else { 173 element.parent().parent().parent().append( error ); 174 } 175 } else if ( element.is( 'select' ) && element.attr( 'class' ).match( /date-month|date-day|date-year/ ) ) { 176 if ( element.parent().find( 'label.wpforms-error:visible' ).length === 0 ) { 177 element.parent().find( 'select:last' ).after( error ); 178 } 179 } else { 180 error.insertAfter(element); 181 } 182 }, 183 highlight: function( element, errorClass, validClass ) { 184 var $element = $( element ), 185 $field = $element.closest( '.wpforms-field' ), 186 inputName = $element.attr( 'name' ); 187 if ( $element.attr( 'type' ) === 'radio' || $element.attr( 'type' ) === 'checkbox' ) { 188 $field.find( 'input[name=\''+inputName+'\']' ).addClass( errorClass ).removeClass( validClass ); 189 } else { 190 $element.addClass( errorClass ).removeClass( validClass ); 191 } 192 $field.addClass( 'wpforms-has-error' ); 193 }, 194 unhighlight: function( element, errorClass, validClass ) { 195 var $element = $( element ), 196 $field = $element.closest( '.wpforms-field' ), 197 inputName = $element.attr( 'name' ); 198 if ( $element.attr( 'type' ) === 'radio' || $element.attr( 'type' ) === 'checkbox' ) { 199 $field.find( 'input[name=\''+inputName+'\']' ).addClass( validClass ).removeClass( errorClass ); 200 } else { 201 $element.addClass( validClass ).removeClass( errorClass ); 202 } 203 $field.removeClass( 'wpforms-has-error' ); 204 }, 205 submitHandler: function(form) { 206 207 var $form = $(form), 208 $submit = $form.find('.wpforms-submit'), 209 altText = $submit.data('alt-text'); 210 211 if ( WPForms.empty( $submit.get(0).recaptchaID ) && $submit.get(0).recaptchaID !== 0 ) { 212 // Normal form. 213 if (altText) { 214 $submit.text(altText).prop('disabled', true); 215 } 216 217 // Remove name attributes if needed. 218 $( '.wpforms-input-temp-name' ).removeAttr('name'); 219 220 form.submit(); 221 222 } else { 223 // Form contains invisible reCAPTCHA. 224 grecaptcha.execute( $submit.get(0).recaptchaID ); 225 } 226 } 227 } 228 } 229 form.validate( properties ); 230 }); 231 } 232 }, 233 234 /** 235 * Load jQuery Date Picker. 236 * 237 * @since 1.2.3 238 */ 239 loadDatePicker: function() { 240 241 // Only load if jQuery datepicker library exists 242 if (typeof $.fn.flatpickr !== 'undefined') { 243 $('.wpforms-datepicker').each(function() { 244 var element = $(this), 245 form = element.closest('.wpforms-form'), 246 formID = form.data('formid'), 247 fieldID = element.closest('.wpforms-field').data('field-id'), 248 properties; 249 250 if (typeof window['wpforms_'+formID+'_'+fieldID] !== 'undefined' && window['wpforms_'+formID+'_'+fieldID].hasOwnProperty('datepicker')) { 251 properties = window['wpforms_'+formID+'_'+fieldID].datepicker; 252 } else if (typeof window['wpforms_'+formID] !== 'undefined' && window['wpforms_'+formID].hasOwnProperty('datepicker')) { 253 properties = window['wpforms_'+formID].datepicker; 254 } else if (typeof wpforms_datepicker !== 'undefined') { 255 properties = wpforms_datepicker; 256 } else { 257 properties = { 258 disableMobile: true 259 } 260 } 261 element.flatpickr(properties) 262 }); 263 } 264 }, 265 266 /** 267 * Load jQuery Time Picker. 268 * 269 * @since 1.2.3 270 */ 271 loadTimePicker: function() { 272 273 // Only load if jQuery timepicker library exists 274 if (typeof $.fn.timepicker !== 'undefined') { 275 $('.wpforms-timepicker').each(function() { 276 var element = $(this), 277 form = element.closest('.wpforms-form'), 278 formID = form.data('formid'), 279 fieldID = element.closest('.wpforms-field').data('field-id'), 280 properties; 281 282 if ( 283 typeof window['wpforms_'+formID+'_'+fieldID] !== 'undefined' && 284 window['wpforms_'+formID+'_'+fieldID].hasOwnProperty('timepicker') 285 ) { 286 properties = window['wpforms_'+formID+'_'+fieldID].timepicker; 287 } else if ( 288 typeof window['wpforms_'+formID] !== 'undefined' && 289 window['wpforms_'+formID].hasOwnProperty('timepicker') 290 ) { 291 properties = window['wpforms_'+formID].timepicker; 292 } else if ( typeof wpforms_timepicker !== 'undefined') { 293 properties = wpforms_timepicker; 294 } else { 295 properties = { 296 scrollDefault: 'now', 297 forceRoundTime: true 298 }; 299 } 300 301 element.timepicker(properties); 302 }); 303 } 304 }, 305 306 /** 307 * Load jQuery input masks. 308 * 309 * @since 1.2.3 310 */ 311 loadInputMask: function() { 312 313 // Only load if jQuery input mask library exists 314 if (typeof $.fn.inputmask !== 'undefined') { 315 $('.wpforms-masked-input').inputmask(); 316 } 317 }, 318 319 /** 320 * Payments: Do various payment-related tasks on load. 321 * 322 * @since 1.2.6 323 */ 324 loadPayments: function() { 325 326 // Update Total field(s) with latest calculation 327 $('.wpforms-payment-total').each(function(index, el) { 328 WPForms.amountTotal(this); 329 }); 330 331 // Credit card validation 332 if(typeof $.fn.payment !== 'undefined') { 333 $('.wpforms-field-credit-card-cardnumber').payment('formatCardNumber'); 334 $('.wpforms-field-credit-card-cardcvc').payment('formatCardCVC'); 335 } 336 }, 337 338 //--------------------------------------------------------------------// 339 // Binds 340 //--------------------------------------------------------------------// 341 342 /** 343 * Element bindings. 344 * 345 * @since 1.2.3 346 */ 347 bindUIActions: function() { 348 349 // Pagebreak navigation 350 $(document).on('click', '.wpforms-page-button', function(event) { 351 event.preventDefault(); 352 WPForms.pagebreakNav($(this)); 353 }); 354 355 // Payments: Update Total field(s) when latest calculation. 356 $(document).on('change input', '.wpforms-payment-price', function() { 357 WPForms.amountTotal(this, true); 358 }); 359 360 // Payments: Restrict user input payment fields 361 $(document).on('input', '.wpforms-payment-user-input', function() { 362 var $this = $(this), 363 amount = $this.val(); 364 $this.val(amount.replace(/[^0-9.,]/g, '')); 365 }); 366 367 // Payments: Sanitize/format user input amounts 368 $(document).on('focusout', '.wpforms-payment-user-input', function() { 369 var $this = $(this), 370 amount = $this.val(), 371 sanitized = WPForms.amountSanitize(amount), 372 formatted = WPForms.amountFormat(sanitized); 373 $this.val(formatted); 374 }); 375 376 // Rating field: hover effect. 377 $( '.wpforms-field-rating-item' ).hover( 378 function() { 379 $( this ).parent().find( '.wpforms-field-rating-item' ).removeClass( 'selected hover' ); 380 $( this ).prevAll().andSelf().addClass( 'hover' ); 381 }, 382 function() { 383 $( this ).parent().find( '.wpforms-field-rating-item' ).removeClass( 'selected hover' ); 384 $( this ).parent().find( 'input:checked' ).parent().prevAll().andSelf().addClass( 'selected' ); 385 } 386 ); 387 388 // Rating field: toggle selected state. 389 $( document ).on( 'change', '.wpforms-field-rating-item input', function() { 390 391 var $this = $( this ), 392 $wrap = $this.closest( '.wpforms-field-rating-items' ), 393 $items = $wrap.find( '.wpforms-field-rating-item' ); 394 395 $items.removeClass( 'hover selected' ); 396 $this.parent().prevAll().andSelf().addClass( 'selected' ); 397 }); 398 399 // Checkbox/Radio/Payment checkbox: toggle selected state class. 400 $( document ).on( 'change', '.wpforms-field-checkbox input, .wpforms-field-radio input, .wpforms-field-payment-multiple input', function() { 401 402 var $this = $( this ); 403 404 if ( 'radio' === $this.attr( 'type' ) ) { 405 $( this ).closest( 'ul' ).find( 'li' ).removeClass( 'wpforms-selected' ); 406 $( this ).closest( 'li' ).addClass( 'wpforms-selected' ); 407 } else { 408 $( this ).closest( 'li' ).toggleClass( 'wpforms-selected' ); 409 } 410 }) 411 412 // OptinMonster: initialize again after OM is finished. 413 // This is to accommodate moving the form in the DOM. 414 $(document).on('OptinMonsterAfterInject', function() { 415 WPForms.ready(); 416 }); 417 }, 418 419 /** 420 * Update Pagebreak navigation. 421 * 422 * @since 1.2.2 423 */ 424 pagebreakNav: function(el) { 425 426 var $this = $(el), 427 valid = true, 428 action = $this.data('action'), 429 page = $this.data('page'), 430 page2 = page, 431 next = page+1, 432 prev = page-1, 433 formID = $this.data('formid'), 434 $form = $this.closest('.wpforms-form'), 435 $page = $form.find('.wpforms-page-'+page), 436 $submit = $form.find('.wpforms-submit-container'), 437 $indicator = $form.find('.wpforms-page-indicator'), 438 $reCAPTCHA = $form.find('.wpforms-recaptcha-container'), 439 pageScroll = false;
440 441 // Page scroll 442 // TODO: cleanup this BC with wpform_pageScroll. 443 if ( window.wpforms_pageScroll === false ) { 444 pageScroll = false; 445 } else if ( !WPForms.empty( window.wpform_pageScroll ) ) { 446 pageScroll = window.wpform_pageScroll; 447 } else { 448 pageScroll = 75; 449 } 450 451 // Toggling between pages 452 if ( action === 'next' ){ 453 // Validate 454 if (typeof $.fn.validate !== 'undefined') { 455 $page.find('input.wpforms-field-required, select.wpforms-field-required, textarea.wpforms-field-required, .wpforms-field-required input').each(function(index, el) { 456 var field = $(el); 457 if ( field.valid() ) { 458 } else { 459 valid = false; 460 } 461 }); 462 // Scroll to first/top error on page 463 var $topError = $page.find('.wpforms-error').first(); 464 if ($topError.length) { 465 $('html, body').animate({ 466 scrollTop: $topError.offset().top-75 467 }, 750, function() { 468 $topError.focus(); 469 }); 470 } 471 } 472 // Move to next page 473 if (valid) { 474 page2 = next; 475 $page.hide(); 476 var $nextPage = $form.find('.wpforms-page-'+next); 477 $nextPage.show(); 478 if ( $nextPage.hasClass('last') ) { 479 $reCAPTCHA.show(); 480 $submit.show(); 481 } 482 if ( pageScroll ) { 483 // Scroll to top of the form 484 $('html, body').animate({ 485 scrollTop: $form.offset().top-pageScroll 486 }, 1000); 487 } 488 $this.trigger('wpformsPageChange', [ page2, $form ] ); 489 } 490 } else if ( action === 'prev' ) { 491 // Move to prev page 492 page2 = prev; 493 $page.hide(); 494 $form.find('.wpforms-page-'+prev).show(); 495 $reCAPTCHA.hide(); 496 $submit.hide(); 497 if ( pageScroll ) { 498 // Scroll to top of the form 499 $('html, body').animate({ 500 scrollTop: $form.offset().top-pageScroll 501 }, 1000); 502 } 503 $this.trigger('wpformsPageChange', [ page2, $form ] ); 504 } 505 506 if ( $indicator ) { 507 var theme = $indicator.data('indicator'), 508 color = $indicator.data('indicator-color'); 509 if ('connector' === theme || 'circles' === theme) { 510 $indicator.find('.wpforms-page-indicator-page').removeClass('active'); 511 $indicator.find('.wpforms-page-indicator-page-'+page2).addClass('active'); 512 $indicator.find('.wpforms-page-indicator-page-number').removeAttr('style'); 513 $indicator.find('.active .wpforms-page-indicator-page-number').css('background-color', color); 514 if ( 'connector' === theme) { 515 $indicator.find('.wpforms-page-indicator-page-triangle').removeAttr('style'); 516 $indicator.find('.active .wpforms-page-indicator-page-triangle').css('border-top-color', color); 517 } 518 } else if ('progress' === theme) { 519 var $pageTitle = $indicator.find('.wpforms-page-indicator-page-title'), 520 $pageSep = $indicator.find('.wpforms-page-indicator-page-title-sep'), 521 totalPages = $form.find('.wpforms-page').length, 522 width = (page2/totalPages)*100; 523 $indicator.find('.wpforms-page-indicator-page-progress').css('width', width+'%'); 524 $indicator.find('.wpforms-page-indicator-steps-current').text(page2); 525 if ($pageTitle.data('page-'+page2+'-title')) { 526 $pageTitle.css('display','inline').text($pageTitle.data('page-'+page2+'-title')); 527 $pageSep.css('display','inline'); 528 } else { 529 $pageTitle.css('display','none'); 530 $pageSep.css('display','none'); 531 } 532 } 533 } 534 }, 535 536 //--------------------------------------------------------------------// 537 // Other functions 538 //--------------------------------------------------------------------// 539 540 /** 541 * Payments: Calculate total. 542 * 543 * @since 1.2.3 544 */ 545 amountTotal: function(el, validate) { 546 547 var validate = validate || false, 548 $form = $(el).closest('.wpforms-form'), 549 total = 0, 550 totalFormatted = 0, 551 totalFormattedSymbol = 0, 552 currency = WPForms.getCurrency(); 553 554 $('.wpforms-payment-price', $form).each(function(index, el) { 555 556 var amount = 0, 557 $this = $(this); 558 559 if ($this.attr('type') === 'text' || $this.attr('type') === 'hidden' ) { 560 amount = $this.val(); 561 } else if ($this.attr('type') === 'radio' && $this.is(':checked')) { 562 amount = $this.data('amount'); 563 } else if ($this.is('select') && $this.find('option:selected').length > 0) { 564 amount = $this.find('option:selected').data('amount'); 565 } 566 if (!WPForms.empty(amount)) { 567 amount = WPForms.amountSanitize(amount); 568 total = Number(total)+Number(amount); 569 } 570 }); 571 572 totalFormatted = WPForms.amountFormat(total); 573 574 if ( 'left' === currency.symbol_pos) { 575 totalFormattedSymbol = currency.symbol+' '+totalFormatted; 576 } else { 577 totalFormattedSymbol = totalFormatted+' '+currency.symbol; 578 } 579 580 $form.find('.wpforms-payment-total').each(function(index, el) { 581 if ( 'hidden' === $(this).attr('type') || 'text' === $(this).attr('type') ) { 582 $(this).val(totalFormattedSymbol); 583 if ( 'text' === $(this).attr('type') && validate ) {
584 $(this).valid(); 585 } 586 } else { 587 $(this).text(totalFormattedSymbol); 588 } 589 }); 590 }, 591 592 /** 593 * Sanitize amount and convert to standard format for calculations. 594 * 595 * @since 1.2.6 596 */ 597 amountSanitize: function(amount) { 598 599 var currency = WPForms.getCurrency(); 600 601 amount = amount.toString().replace(/[^0-9.,]/g,''); 602 603 if ( currency.decimal_sep === ',' && ( amount.indexOf(currency.decimal_sep) !== -1 ) ) { 604 if ( currency.thousands_sep === '.' && amount.indexOf(currency.thousands_sep) !== -1 ) { 605 amount = amount.replace(currency.thousands_sep,''); 606 } else if( currency.thousands_sep === '' && amount.indexOf('.') !== -1 ) { 607 amount = amount.replace('.',''); 608 } 609 amount = amount.replace(currency.decimal_sep,'.'); 610 } else if ( currency.thousands_sep === ',' && ( amount.indexOf(currency.thousands_sep) !== -1 ) ) { 611 amount = amount.replace(currency.thousands_sep,''); 612 } 613 614 return WPForms.numberFormat( amount, 2, '.', '' ); 615 }, 616 617 /** 618 * Format amount. 619 * 620 * @since 1.2.6 621 */ 622 amountFormat: function(amount) { 623 624 var currency = WPForms.getCurrency(); 625 626 amount = String(amount); 627 628 // Format the amount 629 if ( currency.decimal_sep === ',' && ( amount.indexOf(currency.decimal_sep) !== -1 ) ) { 630 var sepFound = amount.indexOf(currency.decimal_sep), 631 whole = amount.substr(0, sepFound), 632 part = amount.substr(sepFound+1, amount.strlen-1); 633 amount = whole + '.' + part; 634 } 635 636 // Strip , from the amount (if set as the thousands separator) 637 if ( currency.thousands_sep === ',' && ( amount.indexOf(currency.thousands_sep) !== -1 ) ) { 638 amount = amount.replace(',',''); 639 } 640 641 if ( WPForms.empty( amount ) ) { 642 amount = 0; 643 } 644 645 return WPForms.numberFormat( amount, 2, currency.decimal_sep, currency.thousands_sep ); 646 }, 647 648 /** 649 * Get site currency settings. 650 * 651 * @since 1.2.6 652 */ 653 getCurrency: function() { 654 655 var currency = { 656 code: 'USD', 657 thousands_sep: ',', 658 decimal_sep: '.', 659 symbol: '$', 660 symbol_pos: 'left' 661 }; 662 663 // Backwards compatibility. 664 if ( typeof wpforms_settings.currency_code !== 'undefined' ) { 665 currency.code = wpforms_settings.currency_code; 666 } 667 if ( typeof wpforms_settings.currency_thousands !== 'undefined' ) { 668 currency.thousands_sep = wpforms_settings.currency_thousands; 669 } 670 if ( typeof wpforms_settings.currency_decimal !== 'undefined' ) { 671 currency.decimal_sep = wpforms_settings.currency_decimal; 672 } 673 if ( typeof wpforms_settings.currency_symbol !== 'undefined' ) { 674 currency.symbol = wpforms_settings.currency_symbol; 675 } 676 if ( typeof wpforms_settings.currency_symbol_pos !== 'undefined' ) { 677 currency.symbol_pos = wpforms_settings.currency_symbol_pos; 678 } 679 680 return currency; 681 }, 682 683 /** 684 * Format number. 685 * 686 * @link http://locutus.io/php/number_format/ 687 * @since 1.2.6 688 */ 689 numberFormat: function (number, decimals, decimalSep, thousandsSep) { 690 691 number = (number + '').replace(/[^0-9+\-Ee.]/g, ''); 692 var n = !isFinite(+number) ? 0 : +number; 693 var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals); 694 var sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep; 695 var dec = (typeof decimalSep === 'undefined') ? '.' : decimalSep; 696 var s; 697 698 var toFixedFix = function (n, prec) { 699 var k = Math.pow(10, prec); 700 return '' + (Math.round(n * k) / k).toFixed(prec) 701 }; 702 703 // @todo: for IE parseFloat(0.55).toFixed(0) = 0; 704 s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.'); 705 if (s[0].length > 3) { 706 s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep) 707 } 708 if ((s[1] || '').length < prec) { 709 s[1] = s[1] || ''; 710 s[1] += new Array(prec - s[1].length + 1).join('0') 711 } 712 713 return s.join(dec) 714 }, 715 716 /** 717 * Empty check similar to PHP. 718 * 719 * @link http://locutus.io/php/empty/ 720 * @since 1.2.6 721 */ 722 empty: function(mixedVar) { 723 724 var undef; 725 var key; 726 var i; 727 var len; 728 var emptyValues = [undef, null, false, 0, '', '0']; 729 730 for (i = 0, len = emptyValues.length; i < len; i++) { 731 if (mixedVar === emptyValues[i]) { 732 return true 733 } 734 } 735 736 if (typeof mixedVar === 'object') { 737 for (key in mixedVar) { 738 if (mixedVar.hasOwnProperty(key)) { 739 return false;
740 } 741 } 742 return true; 743 } 744 745 return false; 746 }, 747 748 /** 749 * Set cookie container user UUID. 750 * 751 * @since 1.3.3 752 */ 753 setUserIndentifier: function() { 754 755 if ( wpforms_settings.uuid_cookie && ! WPForms.getCookie('_wpfuuid') ) { 756 757 // Generate UUID - http://stackoverflow.com/a/873856/1489528 758 var s = new Array(36), 759 hexDigits = '0123456789abcdef', 760 uuid; 761 762 for (var i = 0; i < 36; i++) { 763 s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); 764 } 765 s[14] = "4"; 766 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); 767 s[8] = s[13] = s[18] = s[23] = '-'; 768 769 uuid = s.join(""); 770 771 WPForms.createCookie('_wpfuuid', uuid, 3999); 772 } 773 }, 774 775 /** 776 * Create cookie. 777 * 778 * @since 1.3.3 779 */ 780 createCookie: function(name, value, days) { 781 782 var expires = ''; 783 784 // If we have a days value, set it in the expiry of the cookie. 785 if ( days ) { 786 // If -1 is our value, set a session based cookie instead of a persistent cookie. 787 if ( '-1' === days ) { 788 expires = ''; 789 } else { 790 var date = new Date(); 791 date.setTime(date.getTime() + (days*24*60*60*1000)); 792 expires = '; expires=' + date.toGMTString(); 793 } 794 } else { 795 expires = '; expires=Thu, 01 Jan 1970 00:00:01 GMT'; 796 } 797 798 // Write the cookie. 799 document.cookie = name + '=' + value + expires + '; path=/'; 800 }, 801 802 /** 803 * Retrieve cookie. 804 * 805 * @since 1.3.3 806 */ 807 getCookie: function(name) { 808 809 var nameEQ = name + '=', 810 ca = document.cookie.split(';'); 811 812 for ( var i = 0; i < ca.length; i++ ) { 813 var c = ca[i]; 814 while ( c.charAt(0) === ' ' ) { 815 c = c.substring(1, c.length); 816 } 817 if ( c.indexOf(nameEQ) == 0 ) { 818 return c.substring(nameEQ.length, c.length); 819 } 820 } 821 822 return null; 823 }, 824 825 /** 826 * Delete cookie. 827 */ 828 removeCookie: function(name) { 829 830 WPForms.createCookie(name, '',-1); 831 } 832 }; 833 834 // Initialize. 835 WPForms.init(); 836 837 // Add to global scope. 838 window.wpforms = WPForms; 839 840 //--------------------------------------------------------------------// 841 // jQuery Functions. 842 //--------------------------------------------------------------------// 843 844 /** 845 * Randomize selectors. 846 * 847 * @since 1.4.4 848 */ 849 $.fn.randomize = function( selector ){ 850 851 var $elems = selector ? $( this ).find( selector ) : $( this ).children(); 852 853 for ( var i = $elems.length; i >= 0; i-- ) { 854 $( this ).append( $elems[ Math.random() * i | 0 ] ); 855 } 856 857 return this; 858 } 859})(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.