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