1( function ( $ ) { 2 "use strict"; 3 4 const $window = $( window ); 5 6 window.rheaIsRTL = function () { 7 let isRTL = false; 8 if ( document.querySelector( 'body' ).classList.contains( 'rtl' ) ) { 9 isRTL = true; 10 } 11 return isRTL; 12 } 13 14 $( document ).ready( function () { 15 /*-----------------------------------------------------------------------------------*/ 16 /* Home page properties pagination 17 /*-----------------------------------------------------------------------------------*/ 18 const $body = $( 'body' ); 19 $body.on( 'click', '.rhea_pagination_wrapper a', function ( e ) { 20 e.preventDefault(); 21 22 var thisParent = $( this ).parents( '.rhea_ele_property_ajax_target' ); 23 var id = $( thisParent ).attr( 'id' ); 24 var thisLoader = $( thisParent ).find( '.rhea_svg_loader' ); 25 var thisInner = $( thisParent ).find( '.home-properties-section-inner-target' ); 26 var pageNav = $( thisParent ).find( '.rhea_pagination_wrapper a' ); 27 var thisLink = $( this ); 28 29 if ( ! ( thisLink ).hasClass( 'current' ) ) { 30 var link = $( this ).attr( 'href' ); 31 thisInner.fadeTo( 'slow', 0.5 ); 32 33 thisLoader.slideDown( 'fast' ); 34 // thisContent.fadeOut('fast', function(){ 35 thisParent.load( link + ' #' + id + ' .home-properties-section-inner-target', function ( response, status, xhr ) { 36 if ( status == 'success' ) { 37 thisInner.fadeTo( 'fast', 1 ); 38 pageNav.removeClass( 'current' ); 39 thisLink.addClass( 'current' ); 40 thisLoader.slideUp( 'fast' ); 41 if ( typeof EREloadNewsSlider != 'undefined' && $.isFunction( EREloadNewsSlider ) ) { 42 EREloadNewsSlider(); 43 } 44 if ( typeof setVideoHeightElementor != 'undefined' && $.isFunction( setVideoHeightElementor ) ) { 45 setVideoHeightElementor(); 46 } 47 $( 'html, body' ).animate( { 48 scrollTop : $( '#' + id ).offset().top - 32 49 }, 1000 ); 50 51 } else { 52 thisInner.fadeTo( 'fast', 1 ); 53 thisLoader.slideUp( 'fast' ); 54 } 55 } ); 56 } 57 } ); 58 59 $body.on( "click", ".rhea-ultra-properties-ajax-pagination a", function ( event ) { 60 const $this = $( this ), 61 currentPageNum = parseInt( $this.data( 'page' ) ), 62 propertiesContainer = $this.closest( ".rhea-ultra-properties-container" ), 63 propertiesInner = propertiesContainer.find( '.rhea-ultra-properties-inner-container' ), 64 propertiesStatsWrapper = propertiesContainer.find( '.rhea-ultra-properties-top-bar-stats-wrapper' ), 65 paginationContainer = propertiesContainer.find( ".rhea-ultra-properties-ajax-pagination" ), 66 paginationItems = propertiesContainer.find( ".pagination a" ), 67 loader = propertiesContainer.find( ".rhea_svg_loader" ); 68 69 if ( $this.hasClass( "current" ) ) { 70 return false; 71 } 72 73 loader.slideDown(); 74 75 if ( typeof propertiesMapNewData !== "undefined" ) { 76 $.ajax( { 77 url : ajaxurl, 78 type : 'post', 79 data : { 80 action : 'rhea_map_properties_data', 81 paged : currentPageNum, 82 properties_args : JSON.parse( propertiesMapNewData.rheaPropertiesArgs ) 83 }, 84 success : function ( response ) { 85 if ( response.data ) { 86 const rheaUpdateMapData = $.Event( 'rheaUpdateMapData', { 87 mapProperties : JSON.stringify( response.data ) 88 } ); 89 $( document ).trigger( rheaUpdateMapData ); 90 } 91 } 92 } ); 93 } 94 95 $.ajax( { 96 url : $this.attr( 'href' ), 97 method : 'GET', 98 success : function ( response ) { 99 let $response = $( response ); 100 propertiesStatsWrapper.html( $response.find( ".rhea-ultra-properties-top-bar-stats-wrapper > .rhea-ultra-properties-stats" ) ); 101 paginationContainer.html( $response.find( ".rhea-ultra-properties-ajax-pagination > .pagination" ) ); 102 propertiesInner.html( $response.find( ".rhea-ultra-properties-inner-container > div" ) ); 103 104 paginationItems.removeClass( 'current' ); 105 $this.addClass( 'current' ); 106 107 loader.slideUp(); 108 109 // Scroll to the top of the properties 110 $( 'html, body' ).animate( { 111 scrollTop : propertiesContainer.find( '.rhea-ultra-properties-inner-container' ) 112 .offset().top - 100 113 }, 1000 ); 114 } 115 } ); 116 117 event.preventDefault(); 118 } ); 119 120 // Add class if div is empty 121 let rheaStatusBox = $( '.rhea-ultra-property-card-three-wrapper .rhea-ultra-status-box' ); 122 if ( 0 < rheaStatusBox.length ) { 123 rheaStatusBox.each( function () { 124 if ( ! $.trim( $( this ).html() ).length ) { 125 $( this ).addClass( 'rhea-empty-wrapper' ); 126 } 127 } ); 128 } 129 130 // show lightbox info on button click 131 $( 'body' ).on( 'click', '.rhea-ultra-property-card-five-popup', function () { 132 133 let thisPopUp = $( this ).data( 'src' ); 134 let galleryItems = $( thisPopUp ).find( '.rhea-gallery-item' ); 135 galleryItems.each( function () { 136 let thisUlr = $( this ).data( 'bg-image' ); 137 $( this ).css( 'background-image', 'url("' + thisUlr + '")' ); 138 } ); 139 } ); 140 141 rheaEqualWidthButtons( '.rhea-equal-width-btn-1', '.rhea-equal-width-btn-2' ); 142 143 let triggerAnimate = $('.rhea-trigger-animate'); 144 if ( triggerAnimate.length ) { 145 146 $('body').on('mouseenter', '.rhea-trigger-animate', function () { 147 $(this).find('.rhea-animate-item').removeClass("animate-out").addClass("animate-in"); 148 }); 149 $('body').on('mouseleave', '.rhea-trigger-animate',function () { 150 $(this).find('.rhea-animate-item').removeClass("animate-in").addClass("animate-out"); 151 }); 152 153 function animateBottomOnDevices() { 154 let bodyDevice = $body.attr( 'data-elementor-device-mode' ); 155 let bottomOnDevices = $( '.bottom-on-devices' ); 156 157 if ( bodyDevice !== 'desktop' && bodyDevice !== 'widescreen' ) { 158 bottomOnDevices.removeClass( 'left span-wide' ).addClass( 'bottom' ); 159 } else { 160 bottomOnDevices.removeClass( 'bottom' ).addClass( 'left span-wide' ); 161 } 162 } 163 164 animateBottomOnDevices(); 165 $( window ).on( 'resize', function () { 166 animateBottomOnDevices(); 167 } ); 168 169 } 170 171 } ); 172 173 174 /*-----------------------------------------------------------------------------------*/ 175 /* Equal Width Buttons 176 /*-----------------------------------------------------------------------------------*/ 177 window.rheaEqualWidthButtons = function ( btn1, btn2 ) { 178 const rheaW1 = $( btn1 ).innerWidth(); 179 const rheaW2 = $( btn2 ).innerWidth(); 180 if ( rheaW1 > rheaW2 ) { 181 $( btn2 ).css( 'width', rheaW1 + "px" ); 182 } else { 183 $( btn1 ).css( 'width', rheaW2 + "px" ); 184 } 185 } 186 187 /*-----------------------------------------------------------------------------------*/ 188 /* Nav Menu Responsive Layout Management 189 /*-----------------------------------------------------------------------------------*/ 190 window.rheaMenuDisplayScreen = function ( size, widgetID ) { 191 const lgMenu = $( ".rhea-lg-menu-" + widgetID ); 192 const responsiveMenu = $( ".rhea-responsive-men-" + widgetID ); 193 if ( innerWidth < size ) { 194 lgMenu.hide(); 195 responsiveMenu.show(); 196 197 } else { 198 lgMenu.show(); 199 responsiveMenu.hide(); 200 } 201 } 202 203 /*-----------------------------------------------------------------------------------*/ 204 /* SelectPicker Drop Down Initiation 205 /*-----------------------------------------------------------------------------------*/ 206 window.rheaSelectPicker = function ( id ) { 207 if ( $().selectpicker ) { 208 $( id ).selectpicker( { 209 iconBase : 'fas', 210 dropupAuto : 'true', 211 width : "100%", 212 tickIcon : 'fa-check', 213 selectAllText : '<span class="rhea_select_bs_buttons rhea_bs_select"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><polygon points="22.1 9 20.4 7.3 14.1 13.9 15.8 15.6 "/><polygon points="27.3 7.3 16 19.3 9.6 12.8 7.9 14.5 16 22.7 29 9 "/><polygon points="1 14.5 9.2 22.7 10.9 21 2.7 12.8 "/></svg></span>', 214 deselectAllText : '<span class="rhea_select_bs_buttons rhea_bs_deselect"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30"><style type="text/css"> \n' + 215 '\t.rh-st0{fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:10;}\n' + 216 '</style><path class="rhea_des rh-st0" d="M3.4 10.5H20c3.8 0 7 3.1 7 7v0c0 3.8-3.1 7-7 7h-6"/><polyline class="rhea_des rh-st0" points="8.4 15.5 3.4 10.5 8.4 5.5 "/></svg></span>' 217 218 } ); 219 } 220 }; 221 222 /*-----------------------------------------------------------------------------------*/ 223 /* Search Form Widget 224 /*-----------------------------------------------------------------------------------*/ 225 window.rheaSearchFields = function ( id, fieldCount, topFields, collapsedFields ) { 226 227 var divList = $( id ).find( '.rhea_prop_search__option' ); 228 divList.sort( function ( a, b ) { 229 return $( a ).data( "key-position" ) - $( b ).data( "key-position" ) 230 } ); 231 232 $( topFields ).html( divList ).promise().done( function () { 233 234 235 var getDataTopBar = fieldCount; 236 237 238 var advanceSearch = $( topFields ).find( '.rhea_prop_search__option' ); 239 240 var prePendTo = $( collapsedFields ); 241 242 var i = 0; 243 244 var j = 0; 245 246 advanceSearch.each( function () { 247 if ( i < getDataTopBar + 1 ) { 248 if ( $( this ).hasClass( 'hide-fields' ) ) { 249 j = 2; 250 } 251 if ( $( this ).hasClass( 'rvr-hide-fields' ) ) { 252 j++; 253 } 254 } 255 i++; 256 } ); 257 var advanceElements = getDataTopBar + j + 1; 258 259 if ( advanceElements > 0 ) { 260 var advanceFieldsSmart = $( topFields ) 261 .find( '.rhea_prop_search__option:nth-of-type(n+' + advanceElements + ')' ); 262 263 advanceFieldsSmart.detach().prependTo( prePendTo ); 264 265 } 266 267 } ); 268 269 270 }; 271 272 window.rheaOpenSearchPopup = function ( trigger, popup ) { 273 $( trigger ).on( 'click', function () { 274 $( popup ).addClass( 'active' ); 275 $( popup ).fadeIn( 'fast' ); 276 } ); 277 $( '.rhea-popup-close' ).on( 'click', function () { 278 $( popup ).removeClass( 'active' ); 279 $( popup ).fadeOut( 'fast' ); 280 $( trigger ).removeClass( 'rhea_advance_open' ); 281 } ) 282 } 283 284 window.rheaPropertySlider = function ( id, min, max, pos = 'before', separator = ',', currency = '$', min_searched = '', max_searched = '', step = 100 ) { 285
286 function thousandSeparator( n ) { 287 if ( typeof n === 'number' ) { 288 n += ''; 289 var x = n.split( '.' ); 290 var x1 = x[0]; 291 var x2 = x.length > 1 ? '.' + x[1] : ''; 292 var rgx = /(\d+)(\d{3})/; 293 while ( rgx.test( x1 ) ) { 294 x1 = x1.replace( rgx, '$1' + separator + '$2' ); 295 } 296 return x1 + x2; 297 } else { 298 return n; 299 } 300 } 301 302 var getPosition = pos; 303 304 var PosBefore = ''; 305 var PosAfter = ''; 306 if ( getPosition === 'before' ) { 307 PosBefore = currency; 308 } else { 309 PosAfter = currency; 310 } 311 312 var minVal = min; 313 var maxVal = max; 314 if ( min_searched !== '' ) { 315 minVal = min_searched 316 } 317 if ( max_searched !== '' ) { 318 maxVal = max_searched 319 } 320 321 $( id ).slider( { 322 range : true, 323 min : min, 324 max : max, 325 step : step, 326 values : [minVal, maxVal], 327 slide : function ( event, ui ) { 328 // Set interval difference between min and max price slider values 329 if ( ui.values[0] >= ui.values[1] - Math.round( ui.values[1] / 10 ) ) { 330 return false; 331 } 332 333 for ( var i = 0; i < ui.values.length; ++i ) { 334 $( "input.rhea_slider_value[data-index=" + i + "]" ).val( ui.values[i] ); 335 $( "span.rhea_price_display[data-index=" + i + "]" ) 336 .text( PosBefore + thousandSeparator( ui.values[i] ) + PosAfter ); 337 338 } 339 } 340 } ); 341 }; 342 343 window.rheaSearchAdvanceState = function ( buttonID, wrapperID ) { 344 $( buttonID ).on( 'click', function () { 345 $( buttonID ).toggleClass( 'rhea_advance_open' ); 346 if ( $( buttonID ).hasClass( 'rhea_advance_open' ) ) { 347 $( wrapperID ).slideDown( 'normal' ); 348 } else { 349 $( wrapperID ).slideUp( 'normal' ); 350 } 351 } ); 352 353 354 }; 355 356 window.rheaFeaturesState = function ( buttonID, wrapperID ) { 357 $( buttonID ).on( 'click', function () { 358 $( buttonID ).toggleClass( 'rhea_features_open' ); 359 if ( $( buttonID ).hasClass( 'rhea_features_open' ) ) { 360 $( wrapperID ).slideDown( 'normal' ); 361 } else { 362 $( wrapperID ).slideUp( 'normal' ); 363 } 364 } ); 365 366 367 }; 368 369 /*-----------------------------------------------------------------------------------*/ 370 /* Search Form price change on status change 371 /*-----------------------------------------------------------------------------------*/ 372 window.rheaSearchStatusChange = function ( priceOther, PriceRent, statusID, rent_status = 'for-rent' ) { 373 374 if ( '' !== rent_status ) { 375 376 var rhea_property_status_changed = function ( new_status ) { 377 var price_for_others = $( priceOther ); 378 var price_for_rent = $( PriceRent ); 379 380 if ( price_for_others.length > 0 && price_for_rent.length > 0 ) { 381 382 if ( new_status === rent_status ) { 383 price_for_others.addClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', true ); 384 price_for_rent.removeClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', false ); 385 386 387 } else { 388 price_for_rent.addClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', true ); 389 price_for_others.removeClass( 'hide-fields' ).find( 'select' ).prop( 'disabled', false ); 390 } 391 } 392 }; 393 $( statusID ).change( function ( e ) { 394 var selected_status = $( this ).val(); 395 rhea_property_status_changed( selected_status ); 396 $( '.rhea_multi_select_picker' ).selectpicker( 'refresh' ); 397 } ); 398 399 /* On page load ( as on search page ) */ 400 var selected_status = $( statusID ).val(); 401 if ( selected_status === rent_status ) { 402 rhea_property_status_changed( selected_status ); 403 } 404 } 405 }; 406 407 window.minMaxPriceValidation = function ( minID, maxID ) { 408 409 /** 410 * Max and Min Price 411 * Shows red outline if min price is bigger than max price 412 */ 413 414 /* for normal prices */ 415 $( minID ).add( maxID ).on( 'change', function () { 416 var min_text_val = $( minID ).val();
417 var min_int_val = ( isNaN( min_text_val ) ) ? 0 : parseInt( min_text_val ); 418 419 var max_text_val = $( maxID ).val(); 420 var max_int_val = ( isNaN( max_text_val ) ) ? 0 : parseInt( max_text_val ); 421 422 if ( ( min_int_val >= max_int_val ) && ( min_int_val != 0 ) && ( max_int_val != 0 ) ) { 423 $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).addClass( 'rhea-error' ); 424 } else { 425 $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).removeClass( 'rhea-error' ); 426 } 427 } ); 428 }; 429 window.minMaxRentPriceValidation = function ( minID, maxID ) { 430 431 /* for rent prices */ 432 $( minID ).add( maxID ).on( 'change', function () { 433 434 var min_text_val = $( minID ).val(); 435 436 var min_int_val = ( isNaN( min_text_val ) ) ? 0 : parseInt( min_text_val ); 437 438 var max_text_val = $( maxID ).val(); 439 var max_int_val = ( isNaN( max_text_val ) ) ? 0 : parseInt( max_text_val ); 440 441 if ( ( min_int_val >= max_int_val ) && ( min_int_val != 0 ) && ( max_int_val != 0 ) ) { 442 $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).addClass( 'rhea-error' ); 443 } else { 444 $( minID ).add( maxID ).siblings( '.dropdown-toggle' ).removeClass( 'rhea-error' ); 445 } 446 } ); 447 }; 448 449 window.minMaxAreaValidation = function ( minID, maxID ) { 450 /** 451 * Max and Min Area 452 * To show red outline if min is bigger than max 453 */ 454 $( minID ).add( maxID ).on( 'change', function ( obj, e ) { 455 var min_text_val = $( minID ).val();
456 var min_int_val = ( isNaN( min_text_val ) ) ? 0 : parseInt( min_text_val ); 457 458 var max_text_val = $( maxID ).val(); 459 var max_int_val = ( isNaN( max_text_val ) ) ? 0 : parseInt( max_text_val ); 460 461 if ( ( min_int_val >= max_int_val ) && ( min_int_val != 0 ) && ( max_int_val != 0 ) ) { 462 $( minID ).add( maxID ).addClass( 'rhea-error' ); 463 } else { 464 $( minID ).add( maxID ).removeClass( 'rhea-error' ); 465 } 466 } ); 467 }; 468 469 470 /** 471 * MapBox map widget map generation 472 * 473 * @since 0.9.10 474 * 475 * */ 476 window.rheaLoadMapBoxMap = function ( id, settingObj ) { 477 478 let ThisMapID = id, 479 mapBoxContainer = document.getElementById( id ); 480 481 mapBoxContainer.className = mapBoxContainer.className + ' mapbox-dl-map-wrap rhea-mapbox-wrap'; 482 483 if ( typeof settingObj !== "undefined" ) { 484 485 if ( 0 < settingObj.properties.length && typeof settingObj.settings.api_key !== 'undefined' ) { 486 487 const eleMapBoxAPI = settingObj.settings.api_key, 488 mapBoxPropertiesData = settingObj.properties, 489 widgetSettings = settingObj.settings, 490 mapBoxStyle = widgetSettings.style, 491 mapBoxMarkerType = 'pin'; //widgetSettings.marker_type; 492 493 // TODO find out the proper way to implement it 494 let tileLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 495 attribution : '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>' 496 } ); 497 498 // get map bounds 499 let mapBounds = []; 500 for ( let i = 0; i < mapBoxPropertiesData.length; i++ ) { 501 if ( mapBoxPropertiesData[i].lat && mapBoxPropertiesData[i].lng ) { 502 mapBounds.push( [mapBoxPropertiesData[i].lat, mapBoxPropertiesData[i].lng] ); 503 } 504 } 505 506 // Basic map 507 let mapBoxCenter = L.latLng( 27.664827, -81.515755 ); // given coordinates not going to matter 99.9% of the time but still added just in case. 508 if ( 1 === mapBounds.length ) { 509 mapBoxCenter = L.latLng( mapBounds[0] ); // this is also not going to effect 99% of the time but just in case of one property. 510 } 511 512 L.mapbox.accessToken = eleMapBoxAPI; 513 const mapBoxProperties = L.mapbox.map( mapBoxContainer ) 514 .setView( mapBoxCenter, 12 ) 515 .addLayer( L.mapbox.styleLayer( mapBoxStyle ) ); 516 517 if ( 1 < mapBounds.length ) { 518 mapBoxProperties.fitBounds( mapBounds ); // fit bounds should work only for more than one properties 519 } 520 521 let markers = new L.MarkerClusterGroup(); 522 523 for ( let i = 0; i < mapBoxPropertiesData.length; i++ ) { 524 if ( mapBoxPropertiesData[i].lat && mapBoxPropertiesData[i].lng ) { 525 let propertyMapData = mapBoxPropertiesData[i], 526 markerLatLng = L.latLng( propertyMapData.lat, propertyMapData.lng ), 527 propertyMarker, 528 markerOptions = { 529 id : propertyMapData.id, 530 riseOnHover : true 531 }; 532 533 // Marker icon 534 if ( propertyMapData.title ) { 535 markerOptions.title = propertyMapData.title; 536 } 537 538 // Map marker. 539 if ( 'pin' === mapBoxMarkerType ) { 540 let iconOptions = { 541 iconUrl : propertyMapData.icon, 542 iconSize : [42, 57], 543 iconAnchor : [20, 57], 544 popupAnchor : [1, -54] 545 }; 546 if ( propertyMapData.retinaIcon ) { 547 iconOptions.iconRetinaUrl = propertyMapData.retinaIcon; 548 } 549 markerOptions.icon = L.icon( iconOptions ); 550 propertyMarker = L.marker( markerLatLng, markerOptions ); 551 } else { 552 propertyMarker = new L.CircleMarker( markerLatLng, { 553 fillColor : '#1cb2ff', //widgetSettings.marker_color, 554 color : '#1cb2ff', //widgetSettings.marker_color, 555 weight : 2, 556 fillOpacity : 0.6, 557 opacity : 0.6, 558 radius : 25 559 }
559 ).addTo( mapBoxProperties ); 560 } 561 562 // Marker popup 563 let popupContentWrapper = document.createElement( "div" ); 564 popupContentWrapper.className = 'mapboxgl-popup-content'; 565 let popupContent = ""; 566 567 if ( propertyMapData.thumb ) { 568 popupContent += '<a class="mapbox-popup-thumb-link" href="' + propertyMapData.url + '"><img class="mapbox-popup-thumb" src="' + propertyMapData.thumb + '" alt="' + propertyMapData.title + '"/></a>'; 569 } 570 571 if ( propertyMapData.title ) { 572 popupContent += '<h5 class="mapbox-popup-title"><a class="mapbox-popup-link" href="' + propertyMapData.url + '">' + propertyMapData.title + '</a></h5>'; 573 } 574 575 if ( propertyMapData.price ) { 576 popupContent += '<p><span class="mapbox-popup-price">' + propertyMapData.price + '</span></p>'; 577 } 578 579 popupContentWrapper.innerHTML = popupContent; 580 581 propertyMarker.popupContents = popupContentWrapper; 582 propertyMarker.id = propertyMapData.id; 583 propertyMarker.className = 'mapboxgl-wrapper'; 584 propertyMarker.bindPopup( popupContentWrapper ); 585 586 markers.addLayer( propertyMarker ); 587 588 } 589 } 590 mapBoxProperties.addLayer( markers ); 591 mapBoxProperties.scrollWheelZoom.disable(); 592 593 /* 594 * Panning the marker to center of the visible map on "popupopen" event 595 */ 596 mapBoxProperties.on( 'popupopen', function ( e ) { 597 // find the pixel location on the map where the popup anchor is 598 var px = mapBoxProperties.project( e.target._popup._latlng ); 599 // find the height of the popup container, divide by 2, subtract from the Y axis of marker location 600 px.y -= e.target._popup._container.clientHeight / 2; 601 // pan to new center 602 mapBoxProperties.panTo( mapBoxProperties.unproject( px ), { animate : true } ); 603 604 } ); 605 606 /** 607 * Function to find the marker in a cluster 608 * @param {int} marker 609 * @param {int} cluster 610 * @returns 611 */ 612 function is_marker_in_cluster( marker, cluster ) { 613 614 let length = cluster.length; 615 616 for ( let i = 0; i < length; i++ ) { 617 618 if ( cluster[i].id == marker ) { 619 620 return true; 621 622 } 623 624 } 625 626 return false; 627 628 } 629 630 /** 631 * Open Popup function 632 * @param {int} markerid 633 */ 634 function mapbox_open_popup( markerid ) { 635 636 mapBoxProperties.eachLayer( function ( layer ) { 637 638 // Checking if this layer is a cluster 639 if ( typeof layer._childCount !== "undefined" ) { 640 641 // Getting all markers in this cluster 642 let markersincluster = layer.getAllChildMarkers(); 643 644 if ( is_marker_in_cluster( markerid, markersincluster ) ) { 645 646 layer.spiderfy(); 647 648 markersincluster.forEach( 649 function ( property_marker ) { 650 if ( property_marker.id === parseInt( markerid ) ) { 651 652 property_marker.openPopup(); 653 654 } 655 } ); 656 657 } 658 659 } else { 660 661 if ( layer.id === parseInt( markerid ) ) { 662 663 layer.openPopup(); 664 665 } 666 667 } 668 669 } ); 670 671 } 672 673 /** 674 * Close Popup function 675 * @param {int} markerid 676 */ 677 function mapbox_close_popup( markerid ) { 678 679 mapBoxProperties.eachLayer( function ( layer ) { 680 681 // Checking if this layer is a cluster 682 if ( typeof layer._childCount !== "undefined" ) { 683 684 // Getting all markers in this cluster 685 var markersincluster = layer.getAllChildMarkers(); 686 687 if ( is_marker_in_cluster( markerid, markersincluster ) ) { 688 689 layer.unspiderfy(); 690 691 markersincluster.forEach( 692 function ( property_marker ) { 693 694 if ( property_marker.id == parseInt( markerid ) ) { 695 696 layer.closePopup(); 697 698 } 699 700 } ); 701 } 702 703 } else { 704 705 if ( layer.id == parseInt( markerid ) ) { 706 707 layer.closePopup(); 708 709 mapBoxProperties.closePopup(); 710 711 } 712 713 } 714 715 } ); 716 717 } 718 719 let realhomesInfoboxPopupTrigger = function () { 720 721 $( '.rh_popup_info_map' ).each( function ( i ) { 722 723 // Getting the Property ID for mouse events 724 let property_ID = $( this ).attr( 'data-rh-id' ).replace( /[^\d.]/g, '' ); 725 726 $( this ) 727 .on( 'mouseenter', function () { 728 mapbox_open_popup( property_ID ); 729 } ) 730 .on( 'mouseleave', function () { 731 mapbox_close_popup( property_ID ); 732 } ); 733 734 } ); 735 736 return false;
737 }; 738 739 let RHisMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test( navigator.userAgent ) ? true : false; 740 741 if ( ! RHisMobile ) { 742 realhomesInfoboxPopupTrigger(); 743 } 744 745 } else { 746 747 // Fallback Map 748 var fallbackLayer = L.tileLayer( 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 749 attribution : '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' 750 } ); 751 752 // todo: provide an option for fallback map coordinates 753 var fallbackMapOptions = { 754 center : [27.664827, -81.515755], 755 zoom : 12 756 }; 757 758 var fallbackMap = L.map( ThisMapID, fallbackMapOptions ); 759 fallbackMap.addLayer( fallbackLayer ); 760 761 } 762 763 } 764 765 }; 766 767 768 window.rheaLocationsHandler = function ( hierarchicalLocations, 769 locationPlaceholders, 770 selectBoxesIDs, 771 slugsInQueryParams, 772 selectBoxesCount, 773 anyValue, 774 multiSelect ) { 775 776 /** 777 * Following function automatically runs to initialize locations boxes 778 */ 779 ( function () { 780 /* prepare select boxes */ 781 prepareSelectBoxes(); 782 783 let parentLocations = []; 784 for ( let selectIndex = 0; selectIndex < selectBoxesCount; selectIndex++ ) { 785 const currentSelect = $( '#' + selectBoxesIDs[selectIndex] ); /* loop's current select box */ 786 const currentIsLast = ( selectBoxesCount === ( selectIndex + 1 ) ); /* check if current select box is last */ 787 788 if ( selectIndex === 0 ) { /* First iteration */ 789 parentLocations = addParentLocations( currentSelect, currentIsLast ); 790 } else { /* later iterations */ 791 /* If parents locations array is not empty then there could be children to add in current select box */ 792 if ( parentLocations.length > 0 ) { 793 let currentLocations = []; 794 const previousSelect = $( '#' + selectBoxesIDs[selectIndex - 1] ); 795 796 /* loop through all if value is "any" */ 797 if ( previousSelect.val() === anyValue ) { 798 for ( let i = 0; i < parentLocations.length; i++ ) { 799 let tempLocations = addChildrenLocations( currentSelect, parentLocations[i].children, '', currentIsLast ); 800 if ( tempLocations.length > 0 ) { 801 currentLocations = $.merge( currentLocations, tempLocations ); 802 } 803 } 804 } else { 805 /* Otherwise add only children of previous selected location, It there are any. */ 806 let previousLocation = searchLocation( previousSelect.val(), hierarchicalLocations ); 807 if ( previousLocation && previousLocation.children.length > 0 ) { 808 currentLocations = addChildrenLocations( currentSelect, previousLocation.children, '', currentIsLast ); 809 } 810 } 811 812 /* hook up updateChildSelect function with previous select change event */ 813 previousSelect.change( updateChildSelect ); 814 /* currentLocations variable is passed to parentLocations for code below and for next iteration */ 815 parentLocations = currentLocations; 816 } 817 } 818 819 /* If parentLocations is empty */ 820 if ( parentLocations.length === 0 ) { 821 /* disable current select and children selects if any */ 822 disableSelect( currentSelect ); 823 /* No need for further iterations */ 824 break; 825 } else { 826 /* Select the right option within current select based on query parameters */ 827 selectParamOption( currentSelect ); 828 } 829 } /* end of loop */ 830 } )(); /* Run the function immediately after declaration */ 831 832 /** 833 * Adds top level locations to given select box, If addAllChildren is true then it adds all children locations as well 834 * @param targetSelect 835 * @param addAllChildren 836 * @returns {*[]} 837 */ 838 function addParentLocations( targetSelect, addAllChildren ) { 839 let addedLocations = []; 840 let insertionCounter = 0; 841 842 /* loop through top level locations */ 843 hierarchicalLocations.forEach( function ( currentLocation, index, locationsArray ) { 844 targetSelect.append( '<option value="' + currentLocation.slug + '">' + currentLocation.name + '</option>' ); 845 addedLocations[insertionCounter++] = currentLocation; 846 if ( addAllChildren && currentLocation.children.length ) { 847 addChildrenLocations( targetSelect, currentLocation.children, '- ', addAllChildren ); 848 } 849 } ); 850 851 return addedLocations; 852 } 853 854 /** 855 * Adds top level locations form given childrenLocations array to targetSelect box, If addAllChildren is true then it adds all children locations as well 856 * @param targetSelect 857 * @param childrenLocations 858 * @param prefix 859 * @param addAllChildren 860 * @returns {*[]} 861 */ 862 function addChildrenLocations( targetSelect, childrenLocations, prefix, addAllChildren ) { 863 let addedChildrenLocations = []; 864 let insertionCounter = 0; 865 866 /* loop through all children locations */ 867 childrenLocations.forEach( function ( currentLocation, index, locationsArray ) { 868 targetSelect.append( '<option value="' + currentLocation.slug + '">' + prefix + currentLocation.name + '</option>' ); 869 addedChildrenLocations[insertionCounter++] = currentLocation; 870 /* If a current location has children then add those as well */ 871 if ( addAllChildren && currentLocation.children.length ) { 872 let tempLocations = addChildrenLocations( targetSelect, currentLocation.children, prefix + '- ', addAllChildren ); 873 if ( tempLocations.length > 0 ) { 874 /* merge newly added children locations with existing children locations array */ 875 addedChildrenLocations = $.merge( addedChildrenLocations, tempLocations ); 876 } 877 } 878 } ); 879 880 return addedChildrenLocations; 881 } 882 883 /** 884 * Search a location from given locations array for given slug 885 * @param slug 886 * @param locations 887 * @returns {boolean} location OR false if no location is found 888 */ 889 function searchLocation( slug, locations ) {
890 let targetLocation = false; 891 892 for ( let index = 0; index < locations.length; index++ ) { 893 let currentLocation = locations[index]; 894 if ( currentLocation.slug === slug ) { 895 targetLocation = currentLocation; 896 break; 897 } 898 if ( currentLocation.children.length > 0 ) { 899 targetLocation = searchLocation( slug, currentLocation.children ); 900 if ( targetLocation ) { 901 break; 902 } 903 } 904 } 905 906 return targetLocation; 907 } 908 909 /** 910 * Update child select box based on change in selected value of parent select box 911 * @param event 912 */ 913 function updateChildSelect( event ) { 914 let selectedSlug = $( this ).val(); 915 let currentSelectIndex = selectBoxesIDs.indexOf( $( this ).attr( 'id' ) ); 916 917 /* When "any" is selected, Also no need to run this on last select box */ 918 if ( selectedSlug === anyValue && ( currentSelectIndex > -1 ) && ( currentSelectIndex < ( selectBoxesCount - 1 ) ) ) { 919 for ( let s = currentSelectIndex; s < ( selectBoxesCount - 1 ); s++ ) { 920 /* check if child select is Last */ 921 let childSelectIsLast = ( selectBoxesCount === ( s + 2 ) ); 922 923 /* find child select box, empty it and add any options to it */ 924 let childSelect = $( '#' + selectBoxesIDs[s + 1] ); 925 childSelect.empty(); 926 addAnyOption( childSelect ); 927 928 /* loop through select options to find and add children locations into next select */ 929 let anyChildLocations = []; 930 $( '#' + selectBoxesIDs[s] + ' > option' ).each( function () { 931 if ( this.value !== anyValue ) { 932 let relatedLocation = searchLocation( this.value, hierarchicalLocations ); 933 if ( relatedLocation && relatedLocation.children.length > 0 ) { 934 let tempChildrenLocations = addChildrenLocations( childSelect, relatedLocation.children, '', childSelectIsLast ); 935 if ( tempChildrenLocations.length > 0 ) { 936 anyChildLocations = $.merge( anyChildLocations, tempChildrenLocations ); 937 } 938 } 939 } 940 } ); 941 942 /* enable next select if options are added otherwise disable it */ 943 if ( anyChildLocations.length > 0 ) { 944 enableSelect( childSelect ); 945 } else { 946 disableSelect( childSelect ); 947 break; 948 } 949 950 } /* end of for loop */ 951 952 } else { 953 /* In case of valid location selection */ 954 let selectedParentLocation = searchLocation( selectedSlug, hierarchicalLocations ); 955 if ( selectedParentLocation ) { 956 let childLocations = []; 957 for ( let childSelectIndex = currentSelectIndex + 1; childSelectIndex < selectBoxesCount; childSelectIndex++ ) { 958 /* check if child select is Last */ 959 let childSelectIsLast = ( selectBoxesCount === ( childSelectIndex + 1 ) ); 960 961 /* find and empty child select box */ 962 let childSelect = $( '#' + selectBoxesIDs[childSelectIndex] ); 963 childSelect.empty(); 964 965 /* First iteration */ 966 if ( childLocations.length === 0 ) { 967 if ( selectedParentLocation.children.length > 0 ) { 968 addAnyOption( childSelect ); 969 let tempLocations = addChildrenLocations( childSelect, selectedParentLocation.children, '', childSelectIsLast ); 970 if ( tempLocations.length > 0 ) { 971 childLocations = tempLocations; 972 } 973 } 974 } else if ( childLocations.length > 0 ) { /* 2nd and later iterations */ 975 let currentLocations = []; 976 for ( let i = 0; i < childLocations.length; i++ ) { 977 let tempChildLocation = childLocations[i]; 978 if ( tempChildLocation.children.length > 0 ) { 979 addAnyOption( childSelect ); 980 let tempLocations = addChildrenLocations( childSelect, tempChildLocation.children, '', childSelectIsLast ); 981 if ( tempLocations.length > 0 ) { 982 currentLocations = $.merge( currentLocations, tempLocations ); 983 } 984 } 985 } 986 /* If there are current locations OR none, assign current locations array to child locations*/ 987 childLocations = currentLocations; 988 } 989 990 if ( childLocations.length > 0 ) { 991 enableSelect( childSelect ); 992 } else { 993 disableSelect( childSelect ); 994 break; 995 } 996 } /* end of for loop */ 997 } 998 } 999 } 1000 1001 /** 1002 * Adds Any value and select index based place holder text to given select box. 1003 * @param targetSelect 1004 */ 1005 function addAnyOption( targetSelect ) { 1006 if ( targetSelect.has( 'option' ).length > 0 ) { 1007 return; 1008 } 1009 1010 /* current select box index */ 1011 let targetSelectIndex = selectBoxesIDs.indexOf( targetSelect.attr( 'id' ) ); 1012 1013 /* For location fields in search form */ 1014 if ( targetSelect.parents( '.rhea_prop_search__select' ) 1015 .hasClass( 'rhea_location_prop_search_' + targetSelectIndex ) ) { 1016 targetSelect.append( '<option value="' + anyValue + '" selected="selected">' + locationPlaceholders[targetSelectIndex] + '</option>' ); 1017 } 1018 } 1019 1020 /** 1021 * Disable a select box and next select boxes if exists 1022 * @param targetSelect 1023 */ 1024 function disableSelect( targetSelect ) { 1025 let targetSelectID = targetSelect.attr( 'id' ); 1026 targetSelect.empty(); 1027 1028 targetSelect.closest( '.option-bar' ).addClass( 'disabled' ); 1029 if ( targetSelect.is( ':enabled' ) ) { 1030 targetSelect.prop( 'disabled', true ); 1031 targetSelect.parents( '.rhea_prop_search__select' ).addClass( 'rhea_disable_parent' ); 1032 } 1033 1034 let targetSelectIndex = selectBoxesIDs.indexOf( targetSelectID ); // target select box index 1035 let nextSelectBoxesCount = selectBoxesCount - ( targetSelectIndex + 1 ); 1036 1037 /* Disable next select box as well */ 1038 if ( nextSelectBoxesCount > 0 ) { 1039 let nextSelect = $( '#' + selectBoxesIDs[targetSelectIndex + 1] ); 1040 disableSelect( nextSelect ); 1041 } 1042 } 1043 1044 /** 1045 * Enable a select box 1046 * @param targetSelect 1047 */ 1048 function enableSelect( targetSelect ) { 1049 let targetSelectID = targetSelect.attr( 'id' ); 1050
1051 if ( targetSelect.is( ':disabled' ) ) { 1052 targetSelect.prop( 'disabled', false ); 1053 } 1054 1055 // remove class from parents 1056 targetSelect.parents( '.rhea_prop_search__select' ).map( function () { 1057 if ( $( this ).hasClass( 'rhea_disable_parent' ) ) { 1058 $( this ).removeClass( 'rhea_disable_parent' ); 1059 } 1060 } ); 1061 1062 /* Remove .option-bar's disabled class */ 1063 let optionWrapper = targetSelect.closest( '.option-bar' ); 1064 if ( optionWrapper.hasClass( 'disabled' ) ) { 1065 optionWrapper.removeClass( 'disabled' ); 1066 } 1067 } 1068 1069 /** 1070 * Mark the current value in query params as selected in related select box 1071 * @param currentSelect 1072 */ 1073 function selectParamOption( currentSelect ) { 1074 if ( Object.keys( slugsInQueryParams ).length > 0 ) { 1075 let selectName = currentSelect.attr( 'name' ); 1076 if ( typeof selectName !== "undefined" ) { 1077 selectName = selectName.replace( /[\[\]]+/g, '' ); /* remove box brackets as for multi select location brackets comes with name */ 1078 } 1079 if ( typeof slugsInQueryParams[selectName] !== 'undefined' ) { 1080 let tempValue = slugsInQueryParams[selectName]; 1081 if ( Array.isArray( tempValue ) ) { 1082 for ( let i = 0; i < tempValue.length; i++ ) { 1083 currentSelect.find( 'option[value="' + tempValue[i] + '"]' ).prop( 'selected', true ); 1084 } 1085 } else { 1086 currentSelect.find( 'option[value="' + tempValue + '"]' ).prop( 'selected', true ); 1087 } 1088 } 1089 } 1090 } 1091 1092 /** 1093 * Append options with Any value or None value depending on conditions 1094 */ 1095 function prepareSelectBoxes() { 1096 /* Loop through select boxes and prepare them with basic option */ 1097 for ( let selectIndex = 0; selectIndex < selectBoxesCount; selectIndex++ ) { 1098 let currentSelectId = selectBoxesIDs[selectIndex]; 1099 let currentSelect = $( '#' + currentSelectId ); 1100 1101 /* For location fields in search form */ 1102 if ( ( multiSelect !== 'multiple' ) && 1103 ( currentSelect.has( 'option' ).length === 0 ) && 1104 ( currentSelect.parents( '.rhea_prop_search__select' ) 1105 .hasClass( 'rhea_location_prop_search_' + selectIndex ) ) ) { 1106 addAnyOption( currentSelect ); 1107 } 1108 } 1109 } 1110 }; 1111 1112 var rheaLocationSuccessList = function ( data, thisParent, refreshList = false ) { 1113 1114 if ( true === refreshList ) { 1115 thisParent.find( 'option' ).not( ':selected, .none' ).remove().end(); 1116 } 1117 var getSelected = $( thisParent ).val(); 1118 1119 1120 jQuery.each( data, function ( index, text ) { 1121 1122 if ( getSelected ) { 1123 if ( getSelected.indexOf( text[0] ) < 0 ) { 1124 thisParent.append( 1125 $( '<option value="' + text[0] + '">' + text[1] + '</option>' ) 1126 ); 1127 } 1128 } else { 1129 thisParent.append( 1130 $( '<option value="' + text[0] + '">' + text[1] + '</option>' ) 1131 ); 1132 } 1133 } ); 1134 thisParent.selectpicker( 'refresh' ); 1135 $( parent ).find( 'ul.dropdown-menu li:first-of-type a' ).focus(); 1136 1137 $( parent ).find( 'input' ).focus(); 1138 1139 }; 1140 1141 var rheaLoaderFadeIn = function ( parent ) { 1142 $( parent ).find( '.rhea-location-ajax-loader' ).fadeIn( 'fast' ); 1143 }; 1144 1145 var rheaLoaderFadeOut = function ( parent ) { 1146 $( parent ).find( '.rhea-location-ajax-loader' ).fadeOut( 'fast' ); 1147 }; 1148 1149 var rheaTriggerAjaxOnLoad = function ( parent, thisParent, ajaxurl, hideEmpty, SortAlpha, fieldValue = '' ) { 1150 1151 $.ajax( { 1152 url : ajaxurl, 1153 dataType : 'json', 1154 delay : 250, // delay in ms while typing when to perform a AJAX search 1155 data : { 1156 action : 'rhea_get_location_options', // AJAX action for admin-ajax.php 1157 query : fieldValue, 1158 hideemptyfields : hideEmpty, 1159 sortplpha : SortAlpha 1160 1161 }, 1162 beforeSend : rheaLoaderFadeIn( parent ), 1163 success : function ( data ) { 1164 rheaLoaderFadeOut( parent ); 1165 rheaLocationSuccessList( data, thisParent, true ); 1166 } 1167 } ); 1168 1169 }; 1170 1171 var rheaTriggerAjaxOnScroll = function ( parent, thisParent, farmControl, ajaxurl, hideEmpty, SortAlpha, fieldValue = '' ) { 1172 1173 var paged = 2; 1174 1175 farmControl.on( 'keyup', function ( e ) { 1176 paged = 2; 1177 1178 fieldValue = $( this ).val(); 1179 } ); 1180 1181 var targetInner = $( parent ).find( 'div.inner' ); 1182 1183 targetInner.on( 'scroll', function () { 1184 var thisInner = $( this ); 1185
1186 var thisInnerHeight = thisInner.innerHeight(); 1187 var getScrollIndex = thisInner.scrollTop() + thisInnerHeight; 1188 if ( getScrollIndex >= $( this )[0].scrollHeight ) { 1189 1190 1191 $.ajax( { 1192 url : ajaxurl, 1193 dataType : 'json', 1194 delay : 250, // delay in ms while typing when to perform a AJAX search 1195 data : { 1196 action : 'rhea_get_location_options', // AJAX action for admin-ajax.php 1197 query : fieldValue, 1198 page : paged, 1199 hideemptyfields : hideEmpty, 1200 sortplpha : SortAlpha 1201 }, 1202 // beforeSend: loaderFadeIn(), 1203 beforeSend : rheaLoaderFadeIn( parent ), 1204 success : function ( data ) { 1205 rheaLoaderFadeOut( parent ); 1206 paged++; 1207 rheaLocationSuccessList( data, thisParent, false ); 1208 1209 if ( ! $.trim( data ) ) { 1210 $( parent ).find( '.rhea-location-ajax-loader' ).fadeTo( "fast", 0 ); 1211 } 1212 } 1213 } ); 1214 } 1215 } ); 1216 }; 1217 1218 window.rheaAjaxSelect = function ( parent, id, ajaxurl, hideEmpty, SortAlpha ) { 1219 var farmControl = $( parent ).find( '.form-control' ); 1220 var thisParent = $( id ); 1221 rheaTriggerAjaxOnScroll( parent, thisParent, farmControl, ajaxurl, hideEmpty, SortAlpha ); 1222 rheaTriggerAjaxOnLoad( parent, thisParent, ajaxurl, hideEmpty, SortAlpha ); 1223 farmControl.on( 'keyup', function ( e ) { 1224 var fieldValue = $( this ).val(); 1225 fieldValue = fieldValue.trim(); 1226 var wordcounts = jQuery.trim( fieldValue ).length; 1227 $( parent ).find( '.rhea-location-ajax-loader' ).fadeTo( "fast", 1 ); 1228 if ( wordcounts > 0 ) { 1229 $.ajax( { 1230 url : ajaxurl, 1231 dataType : 'json', 1232 delay : 250, // delay in ms while typing when to perform a AJAX search 1233 data : { 1234 action : 'rhea_get_location_options', // AJAX action for admin-ajax.php 1235 query : fieldValue, 1236 hideemptyfields : hideEmpty, 1237 sortplpha : SortAlpha 1238 }, 1239 beforeSend : rheaLoaderFadeIn( parent ), 1240 success : function ( data ) { 1241 rheaLoaderFadeOut( parent ); 1242 thisParent.find( 'option' ).not( ':selected' ).remove().end(); 1243 // var options = []; 1244 if ( fieldValue && data ) { 1245 rheaLocationSuccessList( data, thisParent ); 1246 } else { 1247 thisParent.find( 'option' ).not( ':selected' ).remove().end(); 1248 thisParent.selectpicker( 'refresh' ); 1249 $( parent ).find( 'ul.dropdown-menu li:first-of-type a' ).focus(); 1250 $( parent ).find( 'input' ).focus(); 1251 } 1252 } 1253 } ); 1254 } else { 1255 rheaTriggerAjaxOnLoad( parent, thisParent, ajaxurl, hideEmpty, SortAlpha ) 1256 } 1257 } ); 1258 }; 1259 1260 window.searchFormAjaxKeywords = function ( id, url ) { 1261 var inputField = $( id ).find( 'input' ); 1262 inputField.keyup( function () { 1263 var charCount = inputField.val().length; 1264 if ( charCount > 1 ) { 1265 $( id ).find( '.rhea-properties-data-list' ).slideDown(); 1266 $( id ).find( '.rhea_sfoi_ajax_loader' ).show(); 1267 $( id ).find( '.rhea-field-icon-wrapper' ).addClass( 'rhea-search-fade' ) 1268 $.ajax( { 1269 url : url, 1270 type : 'POST', 1271 data : { 1272 action : 'rh_sfoi_data_fetch', 1273 keyword : $( this ).val() 1274 }, 1275 success : function ( data ) { 1276 $( id ).find( '.rhea-properties-data-list' ).html( data ); 1277 $( id ).find( '.rhea_sfoi_ajax_loader' ).hide(); 1278 $( id ).find( '.rhea-field-icon-wrapper' ).removeClass( 'rhea-search-fade' ) 1279 1280 } 1281 } ); 1282 } else { 1283 $( id ).find( '.rhea-properties-data-list' ).slide
1283Up(); 1284 } 1285 } ); 1286 } 1287 1288 window.rheaTestimonialsTwoCarousel = function ( id, itemsFluid = 4, items = 3, itemsTab = 2, itemsMob = 1, gap = 30, dots = true, rtl = false ) { 1289 if ( $().owlCarousel ) { 1290 $( id ).owlCarousel( { 1291 loop : false, 1292 dots : dots, 1293 nav : false, 1294 margin : gap, 1295 rtl : rtl, 1296 responsive : { 1297 0 : { 1298 items : itemsMob 1299 }, 1300 767 : { 1301 items : itemsTab 1302 }, 1303 1024 : { 1304 items : items 1305 }, 1306 1440 : { 1307 items : itemsFluid 1308 } 1309 } 1310 1311 } ); 1312 } 1313 }; 1314 1315 window.rheaTestimonialsThreeCarousel = function ( slide1, slide2, navSelectors, animationspeed = '600', slideshowspeed = '5000', slideShow1 = true, direction1 = 'horizontal', animation1 = 'fade', reverse1 = false, animation2 = 'fade', reverse2 = false ) { 1316 if ( $().flexslider ) { 1317 $( slide1 ).flexslider( { 1318 controlNav : false, 1319 directionNav : false, 1320 animationLoop : true, 1321 slideshow : slideShow1, 1322 direction : direction1, 1323 animation : animation1, 1324 reverse : reverse1, 1325 animationSpeed : animationspeed, 1326 slideshowSpeed : slideshowspeed 1327 } ); 1328 1329 $( slide2 ).flexslider( { 1330 controlNav : false, 1331 animation : animation2, 1332 animationLoop : true, 1333 slideshow : slideShow1, 1334 reverse : reverse2, 1335 customDirectionNav : $( navSelectors ), 1336 sync : $( slide1 ), 1337 animationSpeed : animationspeed, 1338 slideshowSpeed : slideshowspeed 1339 } ); 1340 } 1341 }; 1342 1343 window.rheaTestimonialsFourCarousel = function ( slider, navSelectors, animation = 'fade', animationSpeed = '600', reverse = false, slideshow = false, slideshowSpeed = '5000' ) { 1344 if ( $().flexslider ) { 1345 $( slider ).flexslider( { 1346 controlNav : false, 1347 directionNav : false, 1348 animation : animation, 1349 animationSpeed : animationSpeed, 1350 reverse : reverse, 1351 slideshow : slideshow, 1352 slideshowSpeed : slideshowSpeed 1353 } ); 1354 1355 $( navSelectors ).on( 'click', function ( event ) { 1356 $( slider ).flexslider( $( this ).attr( 'href' ) ); 1357 event.preventDefault(); 1358 } ); 1359 } 1360 }; 1361 1362 window.EREloadNewsSlider = function () { 1363 if ( $().flexslider ) { 1364 $( '.rhea-listing-news-slider' ).each( function () { 1365 $( this ).flexslider( { 1366 animation : "slide", 1367 slideshow : false, 1368 controlNav : false, 1369 1370 customDirectionNav : $( this ).next( '.rhea-news-directional-nav' ).find( 'a' ) 1371 } ); 1372 } ); 1373 } 1374 } 1375 1376 window.ultraFeaturedSlider = function ( s1, s2 ) { 1377 var s1 = $( s1 ); 1378 var s2 = $( s2 ); 1379 var maxItems = 3; 1380 1381 var $sliderItemTotal = $( ".rhea-slider-item-total" ); 1382 1383 s2.flexslider( { 1384 move : 1, 1385 directionNav : false, 1386 animation : "slide", 1387 controlNav : false, 1388 animationLoop : false, 1389 slideshow : false, 1390 itemWidth : 10, 1391 itemMargin : 12, 1392 asNavFor : s1, 1393 maxItems : maxItems, 1394 minItems : 1, 1395 start : function ( item ) { 1396 slideCounter( item ); 1397 }, 1398 after : function ( item ) { 1399 slideCounter( item ); 1400 } 1401 } ); 1402 1403 function slideCounter( item ) { 1404 $sliderItemTotal.text( item.count - maxItems - item.currentSlide ); 1405 } 1406 1407 s1.flexslider( { 1408 smoothHeight : true, 1409 animation : "fade", 1410 controlNav : false, 1411 animationLoop : false, 1412 slideshow : false, 1413 sync : s2 1414 } ); 1415 1416 1417 } 1418 1419 window.rheaSubmitContactForm = function ( formID, btnSelector ) {
1420 if ( jQuery().validate && jQuery().ajaxSubmit ) { 1421 1422 var submitButton = $( btnSelector ), 1423 ajaxLoader = $( formID ).find( '.rhea-ajax-loader' ), 1424 messageContainer = $( formID ).find( '.rhea-message-container' ), 1425 errorContainer = $( formID ).find( ".rhea-error-container" ); 1426 1427 var formOptions = { 1428 beforeSubmit : function () { 1429 submitButton.attr( 'disabled', 'disabled' ); 1430 ajaxLoader.fadeIn( 'fast' ); 1431 messageContainer.fadeOut( 'fast' ); 1432 errorContainer.fadeOut( 'fast' ); 1433 }, 1434 success : function ( ajax_response, statusText, xhr, $form ) { 1435 var response = $.parseJSON( ajax_response ); 1436 ajaxLoader.fadeOut( 'fast' ); 1437 submitButton.removeAttr( 'disabled' ); 1438 if ( response.success ) { 1439 $form.resetForm(); 1440 messageContainer.html( response.message ).fadeIn( 'fast' ); 1441 1442 setTimeout( function () { 1443 messageContainer.fadeOut( 'slow' ) 1444 }, 5000 ); 1445 1446 // call reset function if it exists 1447 if ( typeof inspiryResetReCAPTCHA == 'function' ) { 1448 inspiryResetReCAPTCHA(); 1449 } 1450 1451 if ( typeof CFOSData !== 'undefined' ) { 1452 setTimeout( function () { 1453 window.location.replace( CFOSData.redirectPageUrl ); 1454 }, 1000 ); 1455 } 1456 1457 if ( typeof contactFromData !== 'undefined' ) { 1458 setTimeout( function () { 1459 window.location.replace( contactFromData.redirectPageUrl ); 1460 }, 1000 ); 1461 } 1462 } else { 1463 errorContainer.html( response.message ).fadeIn( 'fast' ); 1464 } 1465 } 1466 }; 1467 1468 1469 // Agent single page form 1470 $( formID ).validate( { 1471 errorLabelContainer : errorContainer, 1472 submitHandler : function ( form ) { 1473 $( form ).ajaxSubmit( formOptions ); 1474 } 1475 } ); 1476 } 1477 }; 1478 1479 window.rheaAgentToggleV4 = function ( ID ) { 1480 let agentCard = $( ID ).find( '.rhea-v4-agent-slide' ); 1481 agentCard.each( function () { 1482 let agentWrapper = $( this ).find( '.rhea_agent_expand_trigger' ); 1483 let agentExpander = $( this ).find( '.agent-detail-expander' ); 1484 agentWrapper.on( 'click', function ( e ) { 1485 e.preventDefault(); 1486 agentExpander.slideToggle(); 1487 } ); 1488 } ); 1489 } 1490 1491 function isInViewport( node ) { 1492 var rect = node.getBoundingClientRect(); 1493 return ( 1494 ( rect.height > 0 || rect.width > 0 ) && 1495 rect.bottom >= 0 && 1496 rect.right >= 0 && 1497 rect.top <= ( window.innerHeight || document.documentElement.clientHeight ) && 1498 rect.left <= ( window.innerWidth || document.documentElement.clientWidth ) 1499 ) 1500 } 1501 1502 function scrollParallax( selector ) { 1503 var scrolled = jQuery( window ).scrollTop(); 1504 jQuery( selector ).each( function ( index, element ) { 1505 var initY = jQuery( this ).offset().top; 1506 var height = jQuery( this ).height(); 1507 var endY = initY + jQuery( this ).height(); 1508 1509 // Check if the element is in the viewport. 1510 var visible = isInViewport( this ); 1511 if ( visible ) { 1512 var diff = scrolled - initY; 1513 var ratio = Math.round( ( diff / height ) * 100 ); 1514 jQuery( this ).css( 'background-position', 'center ' + parseInt( ( ratio * 1 ) ) + 'px' ) 1515 } 1516 1517 } ) 1518 } 1519 1520 jQuery( '.ere_cta_parallax' ).each( function () { 1521 scrollParallax( this ); 1522 } ); 1523 1524 jQuery( window ).scroll( function () { 1525 jQuery( '.ere_cta_parallax' ).each( function () { 1526 scrollParallax( this ); 1527 } ); 1528 1529 } ); 1530 1531 // Testimonials Five Carousel
1532 window.rheaTestimonialsFiveCarousel = function ( settings ) { 1533 if ( $().owlCarousel ) { 1534 1535 let carouselOptions = { 1536 items : 1, 1537 margin : 0, 1538 nav : false, 1539 autoHeight : true, 1540 loop : settings.loop, 1541 autoplay : settings.autoplay, 1542 autoplayTimeout : settings.autoplaySpeed, 1543 autoplayHoverPause : true, 1544 smartSpeed : settings.animationSpeed, 1545 dotsContainer : settings.dots, 1546 rtl : $( 'body' ).hasClass( 'rtl' ) 1547 }; 1548 1549 if ( 'fade' === settings.slideAnimation ) { 1550 carouselOptions.animateOut = 'fadeOut'; 1551 carouselOptions.animateIn = 'fadeIn'; 1552 } 1553 1554 $( settings.id ).owlCarousel( carouselOptions ); 1555 } 1556 }; 1557 1558 // Image Carousel Widget Script. 1559 window.rheaImageCarousel = function ( settings ) { 1560 if ( $().slick ) { 1561 const imageCarouselWrap = $( settings.wrapper ), 1562 imageCarousel = $( settings.id ); 1563 1564 imageCarousel.on( 'init', function ( event, slick, direction ) { 1565 $( event.currentTarget ).show(); 1566 } ); 1567 1568 imageCarousel.slick( { 1569 fade : settings.fade, 1570 speed : settings.speed, 1571 infinite : settings.infinite, 1572 autoplay : settings.autoplay, 1573 autoplaySpeed : settings.autoplaySpeed, 1574 pauseOnHover : settings.pauseOnHover, 1575 pauseOnInteraction : settings.pauseOnInteraction, 1576 slidesToShow : settings.slidesToShow, 1577 slidesToScroll : settings.slidesToScroll, 1578 rows : 1, 1579 slidesPerRow : 1, 1580 dots : settings.dots, 1581 arrows : settings.arrows, 1582 prevArrow : imageCarouselWrap.find( '.rhea-image-carousel-button-prev' ), 1583 nextArrow : imageCarouselWrap.find( '.rhea-image-carousel-button-next' ), 1584 vertical : false, 1585 mobileFirst : true, 1586 adaptiveHeight : false, 1587 rtl : $( 'body' ).hasClass( 'rtl' ), 1588 responsive : [ 1589 { 1590 breakpoint : 1025, 1591 settings : { 1592 slidesToShow : settings.slidesToShow, 1593 slidesToScroll : settings.slidesToScroll 1594 } 1595 }, 1596 { 1597 breakpoint : 768, 1598 settings : { 1599 slidesToShow : settings.slidesToShowTablet, 1600 slidesToScroll : settings.slidesToScrollTablet 1601 } 1602 }, 1603 { 1604 breakpoint : 380, 1605 settings : { 1606 slidesToShow : settings.slidesToShowMobile, 1607 slidesToScroll : settings.slidesToScrollMobile 1608 } 1609 }, 1610 { 1611 breakpoint : 0, 1612 settings : { 1613 slidesToShow : 1, 1614 slidesToScroll : 1 1615 } 1616 } 1617 ] 1618 } ); 1619 } 1620 }; 1621 1622 // Accordion Widget Script. 1623 window.rheaAccordion = function ( id ) { 1624 $( '#' + id + ' > .rhea-accordion-title' ).on( 'click', function ( event ) { 1625 var $this = $( this ); 1626 1627 if ( $this.hasClass( 'rhea-accordion-active' ) ) { 1628 $this.next( '.rhea-accordion-content' ).slideUp( 500, function () { 1629 $this.removeClass( 'rhea-accordion-active' ) 1630 } ); 1631 } else { 1632 $this.siblings( '.rhea-accordion-title' ).removeClass( 'rhea-accordion-active' ); 1633 $this.addClass( 'rhea-accordion-active' ) 1634 .next( '.rhea-accordion-content' ) 1635 .slideDown( 500 ) 1636 .siblings( '.rhea-accordion-content' ) 1637 .slideUp( 500 ); 1638 } 1639 } ); 1640 }; 1641 1642 // Tabs Widget Script. 1643 window.rheaTabs = function ( id ) { 1644 const tabsContainer = $( '#' + id ); 1645 const tabsList = tabsContainer.find( '.rhea-tabs-list li' ); 1646 const tabsContentWrapper = tabsContainer.find( '.rhea-tabs-content-wrapper' ); 1647 const tabsContent = tabsContainer.find( '.rhea-tabs-content-wrapper .rhea-tabs-content' ); 1648 1649 if ( tabsContent.length ) { 1650 let minHeight = 0; 1651 let contentHeights = []; 1652 1653 tabsContent.each( function ( index ) { 1654 // Gather all content wrapper heights. 1655 contentHeights.push( $( this ).outerHeight() ); 1656 } ); 1657 1658 if ( contentHeights ) { 1659 // Find max value in the array and add with wrapper's space. 1660 minHeight = Math.max.apply( Math, contentHeights ) + ( tabsContentWrapper.outerHeight() - tabsContentWrapper.height() ); 1661 1662 // Set container minimum height 1663 tabsContainer.css( 'min-height', minHeight ); 1664 } 1665 } 1666 1667 tabsList.on( 'click', function ( event ) { 1668 const $this = $( this ); 1669 1670 tabsList.removeClass( 'rhea-tabs-active' ); 1671 $this.addClass( 'rhea-tabs-active' ); 1672 1673 // Hide all content and show current one. 1674 tabsContent.hide().removeClass( 'rhea-tabs-active' ); 1675 tabsContent.eq( $this.index() ).show().addClass( 'rhea-tabs-active' ); 1676 } ); 1677 }; 1678 1679 // Image Gallery Widget Script. 1680 window.rheaImageGallery = function ( settings ) { 1681 if ( jQuery().isotope ) { 1682 const container = $( settings.containerId ), 1683 filterLinks = $( settings.filters ), 1684 galleryOptions = { 1685 filter : "*", 1686 animationEngine : 'best-available', 1687 itemSelector : settings.itemSelector 1688 }; 1689 1690 if ( 'grid' === settings.layout ) { 1691 galleryOptions.layoutMode = 'fitRows'; 1692 } 1693 1694 const gallery = container.isotope( galleryOptions ); 1695 1696 // Re-layout 1697 gallery.isotope( 'layout' ); 1698 1699 filterLinks.on( 'click', function ( event ) { 1700 filterLinks.removeClass( 'current' ); 1701 $( this ).addClass( 'current' ); 1702 1703 gallery.isotope( { filter : '.' + $( this ).attr( 'data-filter' ) } ); 1704 event.preventDefault(); 1705 } ); 1706 } 1707 }; 1708 1709 // Get width and height and set the width/position of Featured Properties slider nav 1710 window.rheaFeaturedNavPosition = function ( id1, id2 ) { 1711 var sliderWidth = $( id1 ).outerWidth(); 1712 var slideHeight = $( id1 ).outerHeight(); 1713 1714 $( id2 ).width( sliderWidth );
1715 $( id2 ).css( 'top', slideHeight ); 1716 } 1717 1718 // Schedule Tour Form Widget Script. 1719 window.rheaScheduleTourForm = function ( id ) { 1720 if ( jQuery().validate && jQuery().ajaxSubmit ) { 1721 1722 const formId = $( id ), 1723 submitButton = formId.find( '.rhea-stf-submit' ), 1724 ajaxLoader = formId.find( '.rhea-stf-ajax-loader' ), 1725 messageContainer = formId.find( '.rhea-stf-message-container' ), 1726 errorContainer = formId.find( ".rhea-stf-error-container" ); 1727 1728 const formOptions = { 1729 beforeSubmit : function () { 1730 submitButton.attr( 'disabled', 'disabled' ); 1731 ajaxLoader.fadeIn( 'fast' ); 1732 messageContainer.fadeOut( 'fast' ); 1733 errorContainer.fadeOut( 'fast' ); 1734 }, 1735 success : function ( ajax_response, statusText, xhr, $form ) { 1736 var response = $.parseJSON( ajax_response ); 1737 ajaxLoader.fadeOut( 'fast' ); 1738 submitButton.removeAttr( 'disabled' ); 1739 if ( response.success ) { 1740 $form.resetForm(); 1741 messageContainer.html( response.message ).fadeIn( 'fast' ); 1742 1743 setTimeout( function () { 1744 messageContainer.fadeOut( 'slow' ) 1745 }, 5000 ); 1746 1747 // Call reset function if it exists. 1748 // if (typeof inspiryResetReCAPTCHA == 'function') { 1749 // inspiryResetReCAPTCHA(); 1750 // } 1751 } else { 1752 errorContainer.html( response.message ).fadeIn( 'fast' ); 1753 } 1754 } 1755 }; 1756 1757 $( id ).validate( { 1758 errorLabelContainer : errorContainer, 1759 submitHandler : function ( form ) { 1760 $( form ).ajaxSubmit( formOptions ); 1761 } 1762 } ); 1763 } 1764 }; 1765 1766 if ( jQuery().isotope ) { 1767 $( '.rhea_properties_cities_wrapper.masonry' ).isotope( { 1768 itemSelector : '.rhea_property_city', 1769 //percentPosition: true, 1770 masonry : { 1771 //columnWidth: 300, 1772 horizontalOrder : true 1773 } 1774 } ) 1775 } 1776 1777 /** 1778 * Enable empty values dropdown fields again on clicking the browser back button 1779 */ 1780 window.onload = function ( event ) { 1781 setTimeout( function () { 1782 $( '.rhea_multi_select_picker' ).selectpicker( 'refresh' ); 1783 $( '.rhea_multi_select_picker_location ' ).selectpicker( 'refresh' ); 1784 }, 500 ); 1785 1786 } 1787 1788 1789 /** 1790 * Hotel Services Slider 1791 */ 1792 1793 window.rheaServicesSlider = function ( id ) { 1794 1795 const carousel = $( id ).find( '.rhea-service-carousel-tabs' ); 1796 const slider = $( id ).find( '.rhea-service-carousel-images' ); 1797 const navPrev = $( id ).find( '.rhea-prev-service' ); 1798 const navNext = $( id ).find( '.rhea-next-service' ); 1799 1800 carousel.slick( { 1801 slidesToShow : 4, 1802 slidesToScroll : 1, 1803 asNavFor : slider, 1804 dots : false, 1805 centerMode : false, 1806 focusOnSelect : true, 1807 prevArrow : navPrev, 1808 nextArrow : navNext, 1809 responsive : [ 1810 { 1811 breakpoint : 1200, 1812 settings : { 1813 slidesToShow : 3 1814 } 1815 }, 1816 { 1817 breakpoint : 800, 1818 settings : { 1819 slidesToShow : 2 1820 } 1821 } 1822 ] 1823 } ); 1824 1825 slider.slick( { 1826 slidesToShow : 1, 1827 slidesToScroll : 1, 1828 arrows : false, 1829 fade : true, 1830 draggable : false 1831 } ); 1832 1833 } 1834 1835 /** 1836 * RVR guests fields counter 1837 */ 1838 window.rvrGuestsFieldsCounter = function ( field, wrapper ) { 1839 const guestNumberField = $( wrapper ).find( '.rhea-guests-number' ); 1840 guestNumberField.each( function () { 1841 1842 let decrement = $( this ).find( '.minus' ); 1843 let increment = $( this ).find( '.plus' ); 1844 let $input = $( this ).find( 'input' ); 1845 let currentCounter = ''; 1846 let adultsRequired = false;
1847 if ( $( this ).hasClass( 'adults-field' ) ) { 1848 currentCounter = $( this ).closest( '.rhea-guests-field-dropdown-box' ).find( '.adults i' ); 1849 adultsRequired = true; 1850 } 1851 if ( $( this ).hasClass( 'children-field' ) ) { 1852 currentCounter = $( this ).closest( '.rhea-guests-field-dropdown-box' ).find( '.children i' ); 1853 } 1854 if ( $( this ).hasClass( 'infants-field' ) ) { 1855 currentCounter = $( this ).closest( '.rhea-guests-field-dropdown-box' ).find( '.infants i' ); 1856 } 1857 1858 decrement.on( 'click', function () { 1859 1860 let count = parseInt( $input.val() ) - 1; 1861 if ( true === adultsRequired ) { 1862 count = count < 1 ? 1 : count; 1863 } else { 1864 count = count < 0 ? 0 : count; 1865 } 1866 $input.val( count ); 1867 $input.change(); 1868 currentCounter.html( count ); 1869 return false; 1870 } ); 1871 1872 increment.on( 'click', function () { 1873 let count = parseInt( $input.val() ) + 1; 1874 $input.val( count ); 1875 $input.change(); 1876 currentCounter.html( count ); 1877 return false; 1878 } ); 1879 1880 } ); 1881 1882 $( field ).on( 'click', function () { 1883 if ( ! $( wrapper ).hasClass( 'active' ) ) { 1884 $( wrapper ).addClass( 'active' ); 1885 } else { 1886 $( wrapper ).removeClass( 'active' ); 1887 } 1888 } ); 1889 1890 //Close guests field dropdown if click outside the wrapper 1891 $( 'body' ).on( "click", function ( e ) { 1892 const target = $( '.rhea-guests-field-dropdown-box, .rhea-guests-field-dropdown-box *' ); 1893 const targetDrop = $( '.rhea-rvr-guests-fields-wrapper' ); 1894 if ( targetDrop.hasClass( 'active' ) ) { 1895 if ( $( e.target ).is( target ) === false && $( e.target ).is( targetDrop ) === false ) { 1896 targetDrop.removeClass( "active" ); 1897 } 1898 } 1899 } ); 1900 1901 } 1902 1903} )( 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.