1/** 2 * Global variables 3 */ 4"use strict"; 5 6var userAgent = navigator.userAgent.toLowerCase(), 7 initialDate = new Date(), 8 9 $document = $( document ), 10 $window = $(window), 11 $html = $( "html" ), 12 13 isDesktop = $html.hasClass( "desktop" ), 14 isIE = userAgent.indexOf( "msie" ) != -1 ? parseInt( userAgent.split( "msie" )[ 1 ] ) : userAgent.indexOf( "trident" ) != -1 ? 11 : userAgent.indexOf( "edge" ) != -1 ? 12 : false, 15 isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ), 16 isNoviBuilder, 17 18 plugins = { 19 responsiveTabs: $( ".responsive-tabs" ), 20 rdInputLabel: $( ".form-label" ), 21 rdNavbar: $( ".rd-navbar" ), 22 regula: $( "[data-constraints]" ), 23 photoSwipeGallery: $( "[data-photo-swipe-item]" ), 24 isotope: $( ".isotope" ), 25 customToggle: $( "[data-custom-toggle]" ), 26 search: $( ".rd-search" ), 27 searchResults: $( '.rd-search-results' ), 28 rdMailForm: $( ".rd-mailform" ), 29 copyrightYear: $( "#copyright-year" ), 30 materialParallax: $( ".parallax-container" ), 31 maps: $( ".google-map-container" ), 32 lightGallery: $( "[data-lightgallery='group']" ), 33 lightGalleryItem: $( "[data-lightgallery='item']" ), 34 lightDynamicGalleryItem: $( "[data-lightgallery='dynamic']" ) 35 }; 36 37 38/** 39 * @desc Check the element was been scrolled into the view 40 * @param {object} elem - jQuery object 41 * @return {boolean} 42 */ 43function isScrolledIntoView ( elem ) { 44 if ( isNoviBuilder ) return true; 45 return elem.offset().top + elem.outerHeight() >= $window.scrollTop() && elem.offset().top <= $window.scrollTop() + $window.height(); 46} 47 48/** 49 * @desc Calls a function when element has been scrolled into the view 50 * @param {object} element - jQuery object 51 * @param {function} func - init function 52 */ 53function lazyInit( element, func ) { 54 var scrollHandler = function () { 55 if ( ( !element.hasClass( 'lazy-loaded' ) && ( isScrolledIntoView( element ) ) ) ) { 56 func.call(); 57 element.addClass( 'lazy-loaded' ); 58 } 59 }; 60 61 scrollHandler(); 62 $window.on( 'scroll', scrollHandler ); 63} 64/** 65 * Initialize All Scripts 66 */ 67$document.ready( function () { 68 isNoviBuilder = window.xMode; 69 70 71 72 /** 73 * Google map function for getting latitude and longitude 74 */ 75 function getLatLngObject(str, marker, map, callback) { 76 var coordinates = {}; 77 try { 78 coordinates = JSON.parse(str); 79 callback(new google.maps.LatLng( 80 coordinates.lat, 81 coordinates.lng 82 ), marker, map) 83 } catch (e) { 84 map.geocoder.geocode({'address': str}, function (results, status) { 85 if (status === google.maps.GeocoderStatus.OK) { 86 var latitude = results[0].geometry.location.lat(); 87 var longitude = results[0].geometry.location.lng(); 88 89 callback(new google.maps.LatLng( 90 parseFloat(latitude), 91 parseFloat(longitude) 92 ), marker, map) 93 } 94 }) 95 } 96 } 97 98 function initMaps() { 99 var key; 100 101 for ( var i = 0; i < plugins.maps.length; i++ ) { 102 if ( plugins.maps[i].hasAttribute( "data-key" ) ) { 103 key = plugins.maps[i].getAttribute( "data-key" ); 104 break; 105 } 106 } 107 108 $.getScript('//maps.google.com/maps/api/js?'+ ( key ? 'key='+ key + '&' : '' ) +'sensor=false&libraries=geometry,places&v=quarterly', function () { 109 var head = document.getElementsByTagName('head')[0], 110 insertBefore = head.insertBefore; 111 112 head.insertBefore = function (newElement, referenceElement) { 113 if (newElement.href && newElement.href.indexOf('//fonts.googleapis.com/css?family=Roboto') !== -1 || newElement.innerHTML.indexOf('gm-style') !== -1) { 114 return; 115 } 116 insertBefore.call(head, newElement, referenceElement); 117 }; 118 var geocoder = new google.maps.Geocoder; 119 for (var i = 0; i < plugins.maps.length; i++) { 120 var zoom = parseInt(plugins.maps[i].getAttribute("data-zoom"), 10) || 11; 121 var styles = plugins.maps[i].hasAttribute('data-styles') ? JSON.parse(plugins.maps[i].getAttribute("data-styles")) : []; 122 var center = plugins.maps[i].getAttribute("data-center") || "New York"; 123 124 // Initialize map 125 var map = new google.maps.Map(plugins.maps[i].querySelectorAll(".google-map")[0], { 126 zoom: zoom, 127 styles: styles, 128 scrollwheel: false, 129 center: {lat: 0, lng: 0} 130 }); 131 132 // Add map object to map node 133 plugins.maps[i].map = map; 134 plugins.maps[i].geocoder = geocoder; 135 plugins.maps[i].keySupported = true; 136 plugins.maps[i].google = google; 137 138 // Get Center coordinates from attribute
139 getLatLngObject(center, null, plugins.maps[i], function (location, markerElement, mapElement) { 140 mapElement.map.setCenter(location); 141 }); 142 143 // Add markers from google-map-markers array 144 var markerItems = plugins.maps[i].querySelectorAll(".google-map-markers li"); 145 146 if (markerItems.length){ 147 var markers = []; 148 for (var j = 0; j < markerItems.length; j++){ 149 var markerElement = markerItems[j]; 150 getLatLngObject(markerElement.getAttribute("data-location"), markerElement, plugins.maps[i], function(location, markerElement, mapElement){ 151 var icon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon"); 152 var activeIcon = markerElement.getAttribute("data-icon-active") || mapElement.getAttribute("data-icon-active"); 153 var info = markerElement.getAttribute("data-description") || ""; 154 var infoWindow = new google.maps.InfoWindow({ 155 content: info 156 }); 157 markerElement.infoWindow = infoWindow; 158 var markerData = { 159 position: location, 160 map: mapElement.map 161 } 162 if (icon){ 163 markerData.icon = icon; 164 } 165 var marker = new google.maps.Marker(markerData); 166 markerElement.gmarker = marker; 167 markers.push({markerElement: markerElement, infoWindow: infoWindow}); 168 marker.isActive = false; 169 // Handle infoWindow close click 170 google.maps.event.addListener(infoWindow,'closeclick',(function(markerElement, mapElement){ 171 var markerIcon = null; 172 markerElement.gmarker.isActive = false; 173 markerIcon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon"); 174 markerElement.gmarker.setIcon(markerIcon); 175 }).bind(this, markerElement, mapElement)); 176 177 178 // Set marker active on Click and open infoWindow 179 google.maps.event.addListener(marker, 'click', (function(markerElement, mapElement) { 180 if (markerElement.infoWindow.getContent().length === 0) return; 181 var gMarker, currentMarker = markerElement.gmarker, currentInfoWindow; 182 for (var k =0; k < markers.length; k++){ 183 var markerIcon; 184 if (markers[k].markerElement === markerElement){ 185 currentInfoWindow = markers[k].infoWindow; 186 } 187 gMarker = markers[k].markerElement.gmarker; 188 if (gMarker.isActive && markers[k].markerElement !== markerElement){ 189 gMarker.isActive = false; 190 markerIcon = markers[k].markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon") 191 gMarker.setIcon(markerIcon); 192 markers[k].infoWindow.close(); 193 } 194 } 195 196 currentMarker.isActive = !currentMarker.isActive; 197 if (currentMarker.isActive) { 198 if (markerIcon = markerElement.getAttribute("data-icon-active") || mapElement.getAttribute("data-icon-active")){ 199 currentMarker.setIcon(markerIcon); 200 } 201 202 currentInfoWindow.open(map, marker); 203 }else{ 204 if (markerIcon = markerElement.getAttribute("data-icon") || mapElement.getAttribute("data-icon")){ 205 currentMarker.setIcon(markerIcon); 206 } 207 currentInfoWindow.close(); 208 } 209 }).bind(this, markerElement, mapElement)) 210 }) 211 } 212 } 213 } 214 }); 215 } 216 217 218 // Google maps 219 if( plugins.maps.length ) { 220 lazyInit( plugins.maps, initMaps ); 221 } 222 /** 223 * Live Search 224 * @description create live search results 225 */ 226 function liveSearch ( options ) { 227 $( '#' + options.live ).removeClass( 'cleared' ).html(); 228 options.current++; 229 options.spin.addClass( 'loading' ); 230 $.get( handler, { 231 s: decodeURI( options.term ), 232 liveSearch: options.live, 233 dataType: "html", 234 liveCount: options.liveCount, 235 filter: options.filter, 236 template: options.template 237 }, function ( data ) { 238 options.processed++; 239 var live = $( '#' + options.live ); 240 if ( options.processed == options.current && !live.hasClass( 'cleared' ) ) { 241 live.find( '> #search-results' ).removeClass( 'active' ); 242 live.html( data ); 243 setTimeout( function () { 244 live.find( '> #search-results' ).addClass( 'active' ); 245 }, 50 ); 246 } 247 options.spin.parents( '.rd-search' ).find( '.input-group-addon' ).removeClass( 'loading' ); 248 } ) 249 } 250
251 /** 252 * attachFormValidator 253 * @description attach form validation to elements 254 */ 255 function attachFormValidator ( elements ) { 256 for ( var i = 0; i < elements.length; i++ ) { 257 var o = $( elements[ i ] ), v; 258 o.addClass( "form-control-has-validation" ).after( "<span class='form-validation'></span>" ); 259 v = o.parent().find( ".form-validation" ); 260 if ( v.is( ":last-child" ) ) { 261 o.addClass( "form-control-last-child" ); 262 } 263 } 264 265 elements 266 .on( 'input change propertychange blur', function ( e ) { 267 var $this = $( this ), results; 268 269 if ( e.type !== "blur" ) { 270 if ( !$this.parent().hasClass( "has-error" ) ) { 271 return; 272 } 273 } 274 275 if ( $this.parents( '.rd-mailform' ).hasClass( 'success' ) ) { 276 return; 277 } 278 279 if ( (results = $this.regula( 'validate' )).length ) { 280 for ( i = 0; i < results.length; i++ ) { 281 $this.siblings( ".form-validation" ).text( results[ i ].message ).parent().addClass( "has-error" ) 282 } 283 } else { 284 $this.siblings( ".form-validation" ).text( "" ).parent().removeClass( "has-error" ) 285 } 286 } ) 287 .regula( 'bind' ); 288 289 var regularConstraintsMessages = [ 290 { 291 type: regula.Constraint.Required, 292 newMessage: "The text field is required." 293 }, 294 { 295 type: regula.Constraint.Email, 296 newMessage: "The email is not a valid email." 297 }, 298 { 299 type: regula.Constraint.Numeric, 300 newMessage: "Only numbers are required" 301 }, 302 { 303 type: regula.Constraint.Selected, 304 newMessage: "Please choose an option." 305 } 306 ]; 307 308 for ( var i = 0; i < regularConstraintsMessages.length; i++ ) { 309 var regularConstraint = regularConstraintsMessages[ i ]; 310 311 regula.override( { 312 constraintType: regularConstraint.type, 313 defaultMessage: regularConstraint.newMessage 314 } ); 315 } 316 } 317 318 /** 319 * isValidated 320 * @description check if all elemnts pass validation 321 */ 322 function isValidated ( elements, captcha ) { 323 var results, errors = 0; 324 325 if ( elements.length ) { 326 for ( j = 0; j < elements.length; j++ ) { 327 328 var $input = $( elements[ j ] ); 329 if ( (results = $input.regula( 'validate' )).length ) { 330 for ( k = 0; k < results.length; k++ ) { 331 errors++; 332 $input.siblings( ".form-validation" ).text( results[ k ].message ).parent().addClass( "has-error" ); 333 } 334 } else { 335 $input.siblings( ".form-validation" ).text( "" ).parent().removeClass( "has-error" ) 336 } 337 } 338 339 if ( captcha ) { 340 if ( captcha.length ) { 341 return validateReCaptcha( captcha ) && errors == 0 342 } 343 } 344 345 return errors == 0; 346 } 347 return true; 348 } 349 350 /** 351 * validateReCaptcha 352 * @description validate google reCaptcha 353 */ 354 function validateReCaptcha ( captcha ) { 355 var captchaToken = captcha.find( '.g-recaptcha-response' ).val(); 356 357 if ( captchaToken.length === 0 ) { 358 captcha 359 .siblings( '.form-validation' ) 360 .html( 'Please, prove that you are not robot.' ) 361 .addClass( 'active' ); 362 captcha 363 .closest( '.form-group' ) 364 .addClass( 'has-error' ); 365 366 captcha.on( 'propertychange', function () { 367 var $this = $( this ), 368 captchaToken = $this.find( '.g-recaptcha-response' ).val(); 369 370 if ( captchaToken.length > 0 ) { 371 $this 372 .closest( '.form-group' ) 373 .removeClass( 'has-error' ); 374 $this 375 .siblings( '.form-validation' ) 376 .removeClass( 'active' ) 377 .html( '' ); 378 $this.off( 'propertychange' ); 379 } 380 } ); 381 382 return false; 383 } 384 385 return true; 386 } 387 388 /** 389 * onloadCaptchaCallback 390 * @description init google reCaptcha 391 */ 392 window.onloadCaptchaCallback = function () { 393 for ( i = 0; i < plugins.captcha.length; i++ ) { 394 var $capthcaItem = $( plugins.captcha[ i ] ); 395 396 grecaptcha.render( 397 $capthcaItem.attr( 'id' ), 398 { 399 sitekey: $capthcaItem.attr( 'data-sitekey' ), 400 size: $capthcaItem.attr( 'data-size' ) ? $capthcaItem.attr( 'data-size' ) : 'normal', 401 theme: $capthcaItem.attr( 'data-theme' ) ? $capthcaItem.attr( 'data-theme' ) : 'light', 402 callback: function ( e ) { 403 $( '.recaptcha' ).trigger( 'propertychange' ); 404 } 405 } 406 ); 407 $capthcaItem.after( "<span class='form-validation'></span>" ); 408 } 409 }; 410 411 // IE Classes 412 if ( isIE ) { 413 if ( isIE < 10 ) $html.addClass( "lt-ie-10" ); 414 if ( isIE < 11 ) $html.addClass( "ie-10" ); 415 if ( isIE === 11 ) $( "html" ).addClass( "ie-11" ); 416 if ( isIE >= 12 ) $( "html" ).addClass( "ie-edge" ); 417 } 418 419 // Copyright Year 420 if ( plugins.copyrightYear.length ) { 421 plugins.copyrightYear.text( initialDate.getFullYear() ); 422 } 423 424 // Responsive Tabs 425 if ( plugins.responsiveTabs.length ) { 426 var i = 0; 427 for ( i = 0; i < plugins.responsiveTabs.length; i++ ) { 428 var $this = $( plugins.responsiveTabs[ i ] ); 429 $this.easyResponsiveTabs( { 430 type: $this.attr( "data-type" ), 431 tabidentify: $this.find( ".resp-tabs-list" ).attr( "data-group" ) || "tab" 432 } ); 433 } 434 } 435 436 // RD Input Label 437 if ( plugins.rdInputLabel.length ) { 438 plugins.rdInputLabel.RDInputLabel(); 439 } 440 441 // Regula 442 if ( plugins.regula.length ) { 443 attachFormValidator( plugins.regula ); 444 } 445 446 // WOW 447 if ( !isNoviBuilder && $html.hasClass( 'desktop' ) && $html.hasClass( "wow-animation" ) && $( ".wow" ).length ) { 448 new WOW().init(); 449 } 450 451 // Isotope 452 if ( plugins.isotope.length ) { 453 var i, isogroup = []; 454 for ( i = 0; i < plugins.isotope.length; i++ ) { 455 var 456 isotopeItem = plugins.isotope[ i ], 457 iso = new Isotope( isotopeItem, { 458 itemSelector: '.isotope-item', 459 layoutMode: isotopeItem.getAttribute( 'data-isotope-layout' ) ? isotopeItem.getAttribute( 'data-isotope-layout' ) : 'masonry', 460 filter: '*' 461 } ); 462 463 isogroup.push( iso ); 464 } 465 466 setTimeout( function () { 467 for ( var i = 0; i < isogroup.length; i++ ) { 468 var isotope = isogroup[ i ]; 469 isotope.element.className += " isotope--loaded"; 470 isotope.layout(); 471 window.addEventListener( 'resize', (function () { 472 this.layout(); 473 }).bind( isotope ) ); 474 } 475 }, 600 ); 476 477 $( "[data-isotope-filter]" ).on( "click", function ( e ) { 478 e.preventDefault(); 479 var filter = $( this ); 480 filter.parents( ".isotope-filters" ).find( '.active' ).removeClass( "active" ); 481 filter.addClass( "active" ); 482 var iso = $( '.isotope[data-isotope-group="' + this.getAttribute( "data-isotope-group" ) + '"]' ); 483 iso.isotope( { 484 itemSelector: '.isotope-item', 485 layoutMode: iso.attr( 'data-isotope-layout' ) ? iso.attr( 'data-isotope-layout' ) : 'masonry', 486 filter: this.getAttribute( "data-isotope-filter" ) == '*' ? '*' : '[data-filter*="' + this.getAttribute( "data-isotope-filter" ) + '"]' 487 } ); 488 } ).eq( 0 ).trigger( "click" ); 489 490 491 } 492 493 // RD Navbar 494 if ( plugins.rdNavbar.length ) { 495 var navbar = plugins.rdNavbar, 496 aliases = { '0': '-', '480': '-xs-', '768': '-sm-', '992': '-md-', '1200': '-lg-' }, 497 responsiveNavbar = {}; 498 499 for ( var alias in aliases ) { 500 responsiveNavbar[ alias ] = {};
501 if ( navbar.attr( 'data' + aliases[ alias ] + 'layout' ) ) responsiveNavbar[ alias ].layout = navbar.attr( 'data' + aliases[ alias ] + 'layout' ); 502 else responsiveNavbar[ alias ].layout = 'rd-navbar-fixed'; 503 if ( navbar.attr( 'data' + aliases[ alias ] + 'device-layout' ) ) responsiveNavbar[ alias ].deviceLayout = navbar.attr( 'data' + aliases[ alias ] + 'device-layout' ); 504 else responsiveNavbar[ alias ].deviceLayout = 'rd-navbar-fixed'; 505 if ( navbar.attr( 'data' + aliases[ alias ] + 'hover-on' ) ) responsiveNavbar[ alias ].focusOnHover = navbar.attr( 'data' + aliases[ alias ] + 'hover-on' ) === 'true'; 506 if ( navbar.attr( 'data' + aliases[ alias ] + 'auto-height' ) ) responsiveNavbar[ alias ].autoHeight = navbar.attr( 'data' + aliases[ alias ] + 'auto-height' ) === 'true'; 507 if ( navbar.attr( 'data' + aliases[ alias ] + 'stick-up-offset' ) ) responsiveNavbar[ alias ].stickUpOffset = navbar.attr( 'data' + aliases[ alias ] + 'stick-up-offset' ); 508 if ( navbar.attr( 'data' + aliases[ alias ] + 'stick-up' ) && !isNoviBuilder ) responsiveNavbar[ alias ].stickUp = navbar.attr( 'data' + aliases[ alias ] + 'stick-up' ) === 'true'; 509 else responsiveNavbar[ alias ].stickUp = false; 510 511 if ( $.isEmptyObject( responsiveNavbar[ alias ] ) ) delete responsiveNavbar[ alias ]; 512 } 513 514 navbar.RDNavbar( { 515 stickUpClone: ( !isNoviBuilder && navbar.attr( "data-stick-up-clone" ) ) ? navbar.attr( "data-stick-up-clone" ) === 'true' : false, 516 stickUpOffset: ( navbar.attr( "data-stick-up-offset" ) ) ? navbar.attr( "data-stick-up-offset" ) : 1, 517 anchorNavOffset: -78, 518 anchorNav: !isNoviBuilder, 519 anchorNavEasing: 'linear', 520 focusOnHover: !isNoviBuilder, 521 responsive: responsiveNavbar, 522 onDropdownOver: function () { 523 return !isNoviBuilder; 524 } 525 } ); 526 527 if ( navbar.attr( "data-body-class" ) ) { 528 document.body.className += ' ' + navbar.attr( "data-body-class" ); 529 } 530 } 531 532 // RD Search 533 if ( plugins.search.length || plugins.searchResults ) { 534 var handler = "bat/rd-search.php"; 535 var defaultTemplate = '<h5 class="search_title"><a target="_top" href="#{href}" class="search_link">#{title}</a></h5>' + 536 '<p>...#{token}...</p>' + 537 '<p class="match"><em>Terms matched: #{count} - URL: #{href}</em></p>'; 538 var defaultFilter = '*.html'; 539 540 if ( plugins.search.length ) { 541 542 for ( i = 0; i < plugins.search.length; i++ ) { 543 var searchItem = $( plugins.search[ i ] ), 544 options = { 545 element: searchItem, 546 filter: (searchItem.attr( 'data-search-filter' )) ? searchItem.attr( 'data-search-filter' ) : defaultFilter, 547 template: (searchItem.attr( 'data-search-template' )) ? searchItem.attr( 'data-search-template' ) : defaultTemplate, 548 live: (searchItem.attr( 'data-search-live' )) ? searchItem.attr( 'data-search-live' ) : false, 549 liveCount: (searchItem.attr( 'data-search-live-count' )) ? parseInt( searchItem.attr( 'data-search-live' ) ) : 4, 550 current: 0, processed: 0, timer: {} 551 }; 552 553 if ( $( '.rd-navbar-search-toggle' ).length ) { 554 var toggle = $( '.rd-navbar-search-toggle' ); 555 toggle.on( 'click', function () { 556 if ( !($( this ).hasClass( 'active' )) ) { 557 searchItem.find( 'input' ).val( '' ).trigger( 'propertychange' ); 558 } 559 } ); 560 } 561 562 if ( options.live ) { 563 searchItem.find( 'input' ).on( "keyup input propertychange", $.proxy( function () { 564 this.term = this.element.find( 'input' ).val().trim(); 565 this.spin = this.element.find( '.input-group-addon' ); 566 clearTimeout( this.timer ); 567 568 if ( this.term.length > 2 ) { 569 this.timer = setTimeout( liveSearch( this ), 200 ); 570 } else if ( this.term.length == 0 ) { 571 $( '#' + this.live ).addClass( 'cleared' ).html( '' ); 572 } 573 }, options, this ) ); 574 } 575 576 searchItem.submit( $.proxy( function () { 577 $( '<input />' ).attr( 'type', 'hidden' ) 578 .attr( 'name', "filter" ) 579 .attr( 'value', this.filter ) 580 .appendTo( this.element ); 581 return true; 582 }, options, this ) ) 583 } 584 } 585 586 if ( plugins.searchResults.length ) { 587 var regExp = /\?.*s=([^&]+)\&filter=([^&]+)/g; 588 var match = regExp.exec( location.search ); 589 590 if ( match != null ) { 591 $.get( handler, {
592 s: decodeURI( match[ 1 ] ), 593 dataType: "html", 594 filter: match[ 2 ], 595 template: defaultTemplate, 596 live: '' 597 }, function ( data ) { 598 plugins.searchResults.html( data ); 599 } ) 600 } 601 } 602 } 603 604 // UI To Top 605 if ( !isNoviBuilder && isDesktop ) { 606 $().UItoTop( { 607 easingType: 'easeOutQuart', 608 containerClass: 'ui-to-top icon icon-xs icon-circle icon-darker-filled mdi mdi-chevron-up' 609 } ); 610 } 611 612 // RD Mailform 613 if ( plugins.rdMailForm.length ) { 614 var i, j, k, 615 msg = { 616 'MF000': 'Successfully sent!', 617 'MF001': 'Recipients are not set!', 618 'MF002': 'Form will not work locally!', 619 'MF003': 'Please, define email field in your form!', 620 'MF004': 'Please, define type of your form!', 621 'MF254': 'Something went wrong with PHPMailer!', 622 'MF255': 'Aw, snap! Something went wrong.' 623 }; 624 625 for ( i = 0; i < plugins.rdMailForm.length; i++ ) { 626 var $form = $( plugins.rdMailForm[ i ] ), 627 formHasCaptcha = false; 628 629 $form.attr( 'novalidate', 'novalidate' ).ajaxForm( { 630 data: { 631 "form-type": $form.attr( "data-form-type" ) || "contact", 632 "counter": i 633 }, 634 beforeSubmit: function ( arr, $form, options ) { 635 636 var form = $( plugins.rdMailForm[ this.extraData.counter ] ), 637 inputs = form.find( "[data-constraints]" ), 638 output = $( "#" + form.attr( "data-form-output" ) ), 639 captcha = form.find( '.recaptcha' ), 640 captchaFlag = true; 641 642 output.removeClass( "active error success" ); 643 644 if ( isValidated( inputs, captcha ) ) { 645 646 // veify reCaptcha 647 if ( captcha.length ) { 648 var captchaToken = captcha.find( '.g-recaptcha-response' ).val(), 649 captchaMsg = { 650 'CPT001': 'Please, setup you "site key" and "secret key" of reCaptcha', 651 'CPT002': 'Something wrong with google reCaptcha' 652 }; 653 654 formHasCaptcha = true; 655 656 $.ajax( { 657 method: "POST", 658 url: "bat/reCaptcha.php", 659 data: { 'g-recaptcha-response': captchaToken }, 660 async: false 661 } ) 662 .done( function ( responceCode ) { 663 if ( responceCode !== 'CPT000' ) { 664 if ( output.hasClass( "snackbars" ) ) { 665 output.html( '<p><span class="icon text-middle mdi mdi-check icon-xxs"></span><span>' + captchaMsg[ responceCode ] + '</span></p>' ) 666 667 setTimeout( function () { 668 output.removeClass( "active" ); 669 }, 3500 ); 670 671 captchaFlag = false; 672 } else { 673 output.html( captchaMsg[ responceCode ] ); 674 } 675 676 output.addClass( "active" ); 677 } 678 } ); 679 } 680 681 if ( !captchaFlag ) { 682 return false; 683 } 684 685 form.addClass( 'form-in-process' ); 686 687 if ( output.hasClass( "snackbars" ) ) { 688 output.html( '<p><span class="icon text-middle fa fa-circle-o-notch fa-spin icon-xxs"></span><span>Sending</span></p>' ); 689 output.addClass( "active" ); 690 } 691 } else { 692 return false; 693 } 694 }, 695 error: function ( result ) { 696 697 var output = $( "#" + $( plugins.rdMailForm[ this.extraData.counter ] ).attr( "data-form-output" ) ), 698 form = $( plugins.rdMailForm[ this.extraData.counter ] ); 699 700 output.text( msg[ result ] ); 701 form.removeClass( 'form-in-process' ); 702 703 if ( formHasCaptcha ) { 704 grecaptcha.reset(); 705 } 706 }, 707 success: function ( result ) { 708 709 var form = $( plugins.rdMailForm[ this.extraData.counter ] ), 710 output = $( "#" + form.attr( "data-form-output" ) ), 711 select = form.find( 'select' ); 712 713 form 714 .addClass( 'success' ) 715 .removeClass( 'form-in-process' ); 716 717 if ( formHasCaptcha ) { 718 grecaptcha.reset(); 719 } 720 721 result = result.length === 5 ? result : 'MF255'; 722 output.text( msg[ result ] ); 723 724 if ( result === "MF000" ) { 725 if ( output.hasClass( "snackbars" ) ) { 726 output.html( '<p><span class="icon text-middle mdi mdi-check icon-xxs"></span><span>' + msg[ result ] + '</span></p>' ); 727 } else { 728 output.addClass( "active success" ); 729 } 730 } else { 731 if ( output.hasClass( "snackbars" ) ) { 732 output.html( ' <p class="snackbars-left"><span class="icon icon-xxs mdi mdi-alert-outline text-middle"></span><span>' + msg[ result ] + '</span></p>' ); 733 } else { 734 output.addClass( "active error" ); 735 } 736 } 737 738 form.clearForm(); 739 740 if ( select.length ) { 741 select.select2( "val", "" ); 742 } 743
744 form.find( 'input, textarea' ).trigger( 'blur' ); 745 746 setTimeout( function () { 747 output.removeClass( "active error success" ); 748 form.removeClass( 'success' ); 749 }, 3500 ); 750 } 751 } ); 752 } 753 } 754 755 // Custom Toggles 756 if ( plugins.customToggle.length ) { 757 var i; 758 for ( i = 0; i < plugins.customToggle.length; i++ ) { 759 var $this = $( plugins.customToggle[ i ] ); 760 $this.on( 'click', function ( e ) { 761 e.preventDefault(); 762 $( "#" + $( this ).attr( 'data-custom-toggle' ) ).add( this ).toggleClass( 'active' ); 763 } ); 764 765 if ( $this.attr( "data-custom-toggle-disable-on-blur" ) === "true" ) { 766 $( "body" ).on( "click", $this, function ( e ) { 767 if ( e.target !== e.data[ 0 ] && $( "#" + e.data.attr( 'data-custom-toggle' ) ).find( $( e.target ) ).length == 0 && e.data.find( $( e.target ) ).length == 0 ) { 768 $( "#" + e.data.attr( 'data-custom-toggle' ) ).add( e.data[ 0 ] ).removeClass( 'active' ); 769 } 770 } ) 771 } 772 } 773 } 774 775 // Material Parallax 776 if ( plugins.materialParallax.length ) { 777 if ( !isNoviBuilder && !isIE && !isMobile ) { 778 plugins.materialParallax.parallax(); 779 } else { 780 for ( var i = 0; i < plugins.materialParallax.length; i++ ) { 781 var $parallax = $( plugins.materialParallax[ i ] ); 782 783 $parallax.addClass( 'parallax-disabled' ); 784 $parallax.css( { "background-image": 'url(' + $parallax.data( "parallax-img" ) + ')' } ); 785 } 786 } 787 } 788 789 790 791 // lightGallery 792 function initLightGallery ( itemsToInit, addClass ) { 793 $( itemsToInit ).lightGallery( { 794 thumbnail: $( itemsToInit ).attr( "data-lg-thumbnail" ) !== "false", 795 selector: "[data-lightgallery='item']", 796 autoplay: $( itemsToInit ).attr( "data-lg-autoplay" ) === "true", 797 pause: parseInt( $( itemsToInit ).attr( "data-lg-autoplay-delay" ) ) || 5000, 798 addClass: addClass, 799 mode: $( itemsToInit ).attr( "data-lg-animation" ) || "lg-slide", 800 loop: $( itemsToInit ).attr( "data-lg-loop" ) !== "false" 801 } ); 802 } 803 804 function initDynamicLightGallery ( itemsToInit, addClass ) { 805 $( itemsToInit ).on( "click", function () { 806 $( itemsToInit ).lightGallery( { 807 thumbnail: $( itemsToInit ).attr( "data-lg-thumbnail" ) !== "false", 808 selector: "[data-lightgallery='item']", 809 autoplay: $( itemsToInit ).attr( "data-lg-autoplay" ) === "true", 810 pause: parseInt( $( itemsToInit ).attr( "data-lg-autoplay-delay" ) ) || 5000, 811 addClass: addClass, 812 mode: $( itemsToInit ).attr( "data-lg-animation" ) || "lg-slide", 813 loop: $( itemsToInit ).attr( "data-lg-loop" ) !== "false", 814 dynamic: true, 815 dynamicEl: 816 JSON.parse( $( itemsToInit ).attr( "data-lg-dynamic-elements" ) ) || [] 817 } ); 818 } ); 819 } 820 821 function initLightGalleryItem ( itemToInit, addClass ) { 822 $( itemToInit ).lightGallery( { 823 selector: "this", 824 addClass: addClass, 825 counter: false, 826 youtubePlayerParams: { 827 modestbranding: 1, 828 showinfo: 0, 829 rel: 0, 830 controls: 0 831 }, 832 vimeoPlayerParams: { 833 byline: 0, 834 portrait: 0 835 } 836 } ); 837 } 838 839 if ( !isNoviBuilder && plugins.lightGallery.length ) { 840 for ( var i = 0; i < plugins.lightGallery.length; i++ ) initLightGallery( plugins.lightGallery[ i ] ); 841 } 842 843 if ( !isNoviBuilder && plugins.lightGalleryItem.length ) { 844 for ( var i = 0; i < plugins.lightGalleryItem.length; i++ ) initLightGalleryItem( plugins.lightGalleryItem[ i ] ); 845 } 846 847 if ( !isNoviBuilder && plugins.lightDynamicGalleryItem.length ) { 848 for ( var i = 0; i < plugins.lightDynamicGalleryItem.length; i++ ) initDynamicLightGallery( plugins.lightDynamicGalleryItem[ i ] ); 849 } 850} );
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.