1////////////////////// 2// Global Functions // 3////////////////////// 4 5// Loader for Buttons 6$(window).bind('pageshow', function() { 7 if ($('.btn-loader').length) { 8 $('.btn-loader').on('click', function(e){ 9 if (e.ctrlKey || e.metaKey) { 10 // Don't Show Loader 11 } else { 12 // Show Loader 13 var loadingText = $(this).data('btn-loader-loading-text'); 14 $(this).addClass('loading').text(loadingText); 15 } 16 }); 17 // Reset Button Loader 18 function btnLoaderReset(btnLoader) { 19 var loaderText = btnLoader.data('btn-loader-text'); 20 btnLoader.removeClass('loading').text(loaderText); 21 } 22 $('.btn-loader').each(function(){ 23 btnLoaderReset($(this)); 24 }); 25 } 26}); 27 28// BE - Property Widget Silider Function 29function bePropWidgetSlider() { 30 $('.be-property-widget-img-area .swiper-container:not(.swiper-container-initialized)').each(function () { 31 const bePropertyWidgetSwiper = new Swiper(this, { 32 //loop: true, Commented out for performance gains 33 lazy: { 34 checkInView: true, 35 loadPrevNext: true 36 }, 37 pagination: { 38 el: '.swiper-pagination', 39 clickable: false, 40 dynamicBullets: true, 41 }, 42 navigation: { 43 nextEl: '.swiper-button-next', 44 prevEl: '.swiper-button-prev', 45 } 46 }); 47 }); 48} 49// BE - Initialize Property Widget Image Slider on Page Load 50bePropWidgetSlider(); 51 52// BE - Loading Div - Constant 53var beLoadingClass = 'be-loading'; 54var beLoading = `<div class="${beLoadingClass}"><div class="swiper-lazy-preloader"></div></div>`; 55 56// BE - Bootstrap Alert Div - Dynamic for JS usage 57function alertMessage(classes, text) { 58 return ` 59 <div class="alert ${classes}"> 60 ${text} 61 <button type="button" class="close" data-dismiss="alert" aria-label="Close"> 62 <span aria-hidden="true">×</span> 63 </button> 64 </div> 65 ` 66} 67 68// BE - Bootstrap Tool Tips 69function enableTooltips() { 70 // BE - Bootstrap Tooltips 71 $('[data-toggle="tooltip"]').tooltip(); 72} 73 74// BE - Pulse Effect - Box Shadow Around Element that Pulses once 75function pulse(element) { 76 $(element).removeClass('pulse', 1); 77 $(element).addClass('pulse', 1); 78} 79 80// BE - Favorites Dropdown Container 81var favoritesDropdownContainer = $('.i-header-favorites .i-header-action-dropdown-main-container'); 82 83// BE - Update Favorites List Function - saveFavorites 84function updateFavoritesList(thisElement, propDataHolder, action) { 85 // Get Property Data 86 var property = thisElement.closest(propDataHolder); 87 var propertyID = property.data('unitcode'); 88 var propWidget = $('[data-unitcode='+ propertyID +']'); 89 var propTitle = propWidget.data('unitshortname') || property.find('.i-header-dropdown-list-item-title').text(); 90 var propWidgetFavorite = propWidget.find('.be-property-widget-img-area-favorite'); 91 if (action == 'add') { 92 var favAction = 1; 93 } 94 if (action == 'remove') { 95 var favAction = 0; 96 // Remove from Favorites 97 propWidgetFavorite.removeClass('favorite'); 98 // Toast Notification 99 $.fn.beToast({ 100 icon: 'heart-regular', 101 iconColor: 'body-font-color', 102 title: 'Removed from Favorites', 103 body: propTitle 104 }); 105 } 106 // Save Favorites 107 $.ajax({ 108 type: 'GET', 109 url: siteFolder + 'ajax/saveFavorites' + siteURLEnding + '?propertyID='+propertyID+'&favAdded='+favAction, 110 success: function(data) { 111 // If Zero Favories are saved then hide the badge 112 if (data == -1) { 113 openModal('favorites-requires-login'); 114 } else if (data == 0) { 115 $('.i-header-favorites-toggle .badge').addClass('d-none'); 116 // Update the Compare Favorites Number on the Compare Favorites Page 117 if ($('#favTotal').length) { 118 $('#favTotal').html(0); 119 $('.compare-wrap .container') 120 .html('<h1 class="site-color-1">Compare Your Favorites</h1>') 121 .append(alertMessage('alert-warning','You do not have any Favorites now!')); 122 } 123 $('.be-header-bar-sub-send-and-print button').prop('disabled',true); 124 } else { 125 if (action == 'add') { 126 // Add to Favorites 127 propWidgetFavorite.addClass('favorite'); 128 // Toast Notification 129 $.fn.beToast({ 130 icon: 'heart-solid', 131 iconColor: 'true-red', 132 title: 'Added to Favorites', 133 body: propTitle 134 }); 135 } 136 // Update the number count on the fly in the header if more than 0 137 $('.i-header-favorites-toggle .badge').html(data).removeClass('d-none'); 138 // Update the Compare Favorites Number on the Compare Favorites Page 139 if ($('#favTotal').length) { 140 $('#favTotal').html(data); 141 } 142 } 143 // Now load the data into the top right view via ajax 144 $.ajax({ 145 type: 'GET', 146 url: siteFolder + 'ajax/favorites' + siteURLEnding, 147 cache: false, 148 success: function(data) { 149 // Load Returned Data 150 favoritesDropdownContainer.html(data); 151 console.log('favs data: ' + data); 152 } 153 }); 154 } 155 }); 156} 157
158//////////////////// 159// Document Ready // 160//////////////////// 161$(document).ready(function () { 162 163 // BE - On page load remove the .no-transition-on-load class for better loading appearance 164 $('html').removeClass('no-transition-on-load'); 165 166 // BE - Disable CSS Transitions on Orientation Change on Mobile 167 window.addEventListener('resize', function () { 168 $('html').addClass('no-transition-on-load'); 169 setTimeout(function () { 170 $('html').removeClass('no-transition-on-load'); 171 }, 100); 172 }, false); 173 174 // BE - Header Height - Measures the headers height, used by CSS for height calculations under the header 175 headerElement = $('.be-header')[0]; 176 let resizeObserver = new ResizeObserver(() => { 177 var headerHeight = $('.be-header').outerHeight(); 178 document.documentElement.style.setProperty('--headerHeight', headerHeight + 'px'); 179 }); 180 resizeObserver.observe(headerElement); 181 182 // BE - Let tooltips work on page load 183 enableTooltips(); 184 185 // BE - Main Navigation Toggle Mobile 186 $('.i-header-navigation-toggle').on('click', function () { 187 $('.i-header-navigation-container').toggleClass('open'); 188 $('html').addClass('i-header-navigation-container-open'); 189 if ($('.pdp-sidebar-footer').hasClass('show')) { 190 $('.pdp-sidebar-footer').removeClass('show'); 191 $('.pdp-sidebar-footer').addClass('navigation-show'); 192 } 193 }); 194 $('.i-header-navigation-close').on('click', function () { 195 $('.i-header-navigation-container').toggleClass('open'); 196 $('html').removeClass('i-header-navigation-container-open'); 197 if ($('.pdp-sidebar-footer').hasClass('navigation-show')) { 198 $('.pdp-sidebar-footer').addClass('show'); 199 $('.pdp-sidebar-footer').removeClass('navigation-show'); 200 } 201 }); 202 $('.i-header-navigation-sub-toggle').on('click', function () { 203 var subNav = $(this).next('.i-header-navigation-sub'); 204 var subHeight = subNav[0].scrollHeight; 205 var subParent = $(this).closest('.i-header-navigation-sub'); 206 if (!$(this).hasClass('toggled')) { 207 // Open Sub Nav 208 $(this).addClass('toggled'); 209 $(this).next('.i-header-navigation-sub').addClass('open'); 210 subNav.css({ 'max-height': subHeight + 'px' }); 211 if (subParent.length == 1) { 212 subParent.css({ 'max-height': 'none' }); 213 setTimeout(function () { 214 var subParentHeight = subParent[0].scrollHeight; 215 subParent.css({ 'max-height': subParentHeight + 'px' }); 216 }, 450); // 50 milliseconds after the 400ms (0.4s) CSS transition animation 217 } 218 } else { 219 // Close Sub Nav 220 $(this).removeClass('toggled'); 221 $(this).next('.i-header-navigation-sub').removeClass('open'); 222 subNav.css({ 'max-height': '0' }); 223 if (subParent.length == 1) { 224 var subParentHeight = subParent[0].scrollHeight; 225 subParent.css({ 'max-height': subParentHeight + 'px' }); 226 } 227 } 228 }); 229 230 // Add class to last child of Nav 231 $(window).on('resize',function(){ 232 if ($(window).outerWidth() >= 1025) { 233 $('.i-header-navigation-item:last-child:has(.i-header-navigation-sub)').addClass('i-header-navigation-item-end'); 234 } 235 }).resize(); 236 237 // BE - Header Action Toggles 238 $('.i-header-actions-toggle').on('click', function () { 239 $(this).tooltip('hide'); 240 if (!$(this).hasClass('active')) { 241 $('.i-header-actions-toggle').not(this).removeClass('active'); 242 $('.i-header-actions-toggled').not(this).removeClass('open'); 243 if ($(window).outerWidth() >= 1025 && $(this).hasClass('pdp-header-map-toggle')) { 244 // Desktop & Map - If on PDP Page 245 // Dont add class of active 246 } else { 247 $(this).addClass('active'); 248 } 249 $(this).parent().find('.i-header-actions-toggled').addClass('open'); 250 // If dates exist, hide when toggling action 251 $('.pdp-sidebar.session-dates .pdp-sidebar-footer').removeClass('show'); 252 } else { 253 if ($(window).outerWidth() >= 1025 && $(this).hasClass('pdp-header-map-toggle')) { 254 // Desktop & Map - If on PDP Page 255 // Dont remove class of active 256 } else { 257 $(this).removeClass('active'); 258 } 259 $(this).parent().find('.i-header-actions-toggled').removeClass('open'); 260 // If dates exist, show when toggling action 261 $('.pdp-sidebar.session-dates .pdp-sidebar-footer').addClass('show'); 262 } 263 // Map - If On SRP Page - Overflow management for desktop and mobile 264 if ($(this).hasClass('srp-header-map-toggle')) { 265 if ($('html').hasClass('srp-map-open')) { 266 $('html').removeClass('srp-map-open'); 267 } else { 268 $('html').addClass('srp-map-open'); 269 } 270 $('html').removeClass('recently-viewed-toggled'); 271 $('html').removeClass('favorites-toggled'); 272 $('.srp-map.be-header-actions-toggled').toggleClass('open'); 273 } 274 // Recently Viewed - Overflow management for desktop and mobile 275 if ($(this).hasClass('i-header-recently-viewed-toggle')) { 276 if ($('html').hasClass('recently-viewed-toggled')) { 277 $('html').removeClass('recently-viewed-toggled'); 278 } else { 279 $('html').addClass('recently-viewed-toggled'); 280 } 281 $('html').removeClass('srp-map-open'); 282 $('html').removeClass('favorites-toggled'); 283 } 284 // Favorites - Overflow management for desktop and mobile 285 if ($(this).hasClass('i-header-favorites-toggle')) { 286 if ($('html').hasClass('favorites-toggled')) { 287 $('html').removeClass('favorites-toggled'); 288 } else { 289 $('html').addClass('favorites-toggled'); 290 } 291 $('html').removeClass('srp-map-open'); 292 $('html').removeClass('recently-viewed-toggled'); 293 } 294 }); 295 296 // BE - Header Action Close 297 $('.i-header-action-dropdown-close').on('click', function () { 298 $('html').removeClass('favorites-toggled'); 299 $('html').removeClass('srp-map-open'); 300 $('html').removeClass('recently-viewed-toggled'); 301 $(this).closest('.i-header-actions-toggled').prev('.i-header-actions-toggle').removeClass('active'); 302 $(this).closest('.i-header-actions-toggled').toggleClass('open'); 303 }); 304 305 // BE - Main - Scroll to Class Name 306 $('[data-scroll-to]').click(function (e) { 307 e.preventDefault(); 308 var headerHeight = $('.be-header').outerHeight(); 309 var dataScrollTo = $(this).data('scroll-to'); 310 var dataScrollToAdjust = $(this).data('scroll-to-adjust') || 0; 311 var dataScrollToBlock = $('.' + dataScrollTo + '').offset().top - dataScrollToAdjust - headerHeight; 312 $('html, body').stop(); 313 $('html, body').animate({ 314 scrollTop: dataScrollToBlock 315 }, 800); 316 return false;
317 }); 318 319 // BE - Favorites Header Toggle - Click and load favorites if they aren't already shown 320 $('.i-header-favorites-toggle').on('click',function(){ 321 if ( !favoritesDropdownContainer.find('.i-header-dropdown-list').length ) { 322 $.ajax({ 323 type: 'GET', 324 url: siteFolder + 'ajax/favorites' + siteURLEnding, 325 cache: false, 326 success: function(data) { 327 favoritesDropdownContainer.html(data); 328 } 329 }); 330 } 331 }); 332 333 // BE - Property Widget - Favorites Heart Click - Shows a Toast and adds it to Favorites list 334 $(document).on('click', '.be-property-widget-img-area-favorite', function () { 335 if (!$(this).hasClass('favorite')) { 336 // Add to Favorites List 337 updateFavoritesList($(this), '.be-property-widget', 'add'); 338 } else { 339 // Remove from Favorites List 340 updateFavoritesList($(this), '.be-property-widget', 'remove'); 341 } 342 }); 343 344 // BE - Remove From Favorites List 345 $(document).on('click', '.i-header-dropdown-list-remove-from-favs', function(){ 346 // Remove from Favorites List 347 updateFavoritesList($(this), '.i-header-dropdown-list-item', 'remove'); 348 }); 349 350 // BE - Recently Viewed List Dropdown 351 $(document).on('click','.i-header-recently-viewed-toggle',function(){ 352 if ( !$('.i-header-recently-viewed .i-header-action-dropdown-main-container').find('.i-header-dropdown-list').length ) { 353 // Load the recently viewed data 354 $.ajax({ 355 type: 'GET', 356 url: siteFolder + 'ajax/recentlyViewed' + siteURLEnding, 357 cache: false, 358 success: function(data) { 359 $('.i-header-recently-viewed .i-header-action-dropdown-main-container').html(data); 360 } 361 }); 362 } 363 }); 364 365 // BE - Numbers and Dashes Only for Inputs 366 $(document).on('input', '.be-numbers-only', function() { 367 this.value = this.value.replace(/[^-+\d]/g,''); 368 }); 369 370 // BE - Read More / See more Button Toggle 371/* 372 if ($('.be-read-more-btn').length) { 373 setTimeout(function(){ 374 $('.be-read-more-btn').each(function () { 375 var readMoreContainer = $(this).prev('.be-read-more-wrap'); 376 var readMoreDefaultHeight = document.documentElement.style.getPropertyValue('--defaultHeight'); 377 var readMoreScrollHeight = readMoreContainer[0].scrollHeight; 378 var more = $(this).data('text-more'); 379 var less = $(this).data('text-less'); 380 // On Page Load or Resize - Whether or not to show the 'Read More' button based on content size 381 $(window).on('resize', function () { 382 if (readMoreScrollHeight < 150) { 383 readMoreContainer.addClass('short'); 384 readMoreContainer.next('.be-read-more-btn').addClass('d-none'); 385 } else { 386 readMoreContainer.removeClass('short'); 387 readMoreContainer.next('.be-read-more-btn').removeClass('d-none'); 388 } 389 }).resize(); 390 // On Button Click 391 $(this).on('click', function () { 392 if (!readMoreContainer.hasClass('open')) { 393 // Open 394 readMoreContainer.addClass('open'); 395 if (readMoreContainer.hasClass('srp-read-more-wrap')) { 396 readMoreInnerContainer = readMoreContainer.find('.srp-read-more-inner-wrap'); 397 readMoreInnerHeight = getComputedStyle(readMoreInnerContainer[0]).getPropertyValue('height'); 398 console.log('readMoreInnerHeight: ' + readMoreInnerHeight + ", readMoreScrollHeight: " + readMoreScrollHeight); 399 readMoreContainer.css({ 'max-height': readMoreInnerHeight }); 400 } else { 401 readMoreContainer.css({ 'max-height': readMoreScrollHeight + 'px' }); 402 } 403 $(this).text(less); 404 } else { 405 // Close 406 readMoreContainer.removeClass('open'); 407 readMoreContainer.css({ 'max-height': readMoreDefaultHeight }); 408 $(this).text(more); 409 } 410 }); 411 }); 412 }, 1500); 413 } 414*/ 415 416 if ($('.be-read-more-btn').length) { 417 setTimeout(function(){ 418 $('.be-read-more-btn').each(function () { 419 var readMoreContainer = $(this).prev('.be-read-more-wrap'); 420 var readMoreDefaultHeight = document.documentElement.style.getPropertyValue('--defaultHeight'); 421 var readMoreScrollHeight = readMoreContainer[0].scrollHeight; 422 var more = $(this).data('text-more'); 423 var less = $(this).data('text-less'); 424 // On Page Load or Resize - Whether or not to show the 'Read More' button based on content size 425 $(window).on('resize', function () { 426 if (readMoreScrollHeight < 150) { 427 readMoreContainer.addClass('short'); 428 readMoreContainer.next('.be-read-more-btn').addClass('d-none'); 429 } else { 430 readMoreContainer.removeClass('short'); 431 readMoreContainer.next('.be-read-more-btn').removeClass('d-none'); 432 } 433 }).resize(); 434 // On Button Click 435 $(this).on('click', function () { 436 if (!readMoreContainer.hasClass('open')) { 437 // Open 438 readMoreContainer.addClass('open'); 439 readMoreContainer.css({ 'max-height': readMoreScrollHeight + 'px' }); 440 $(this).text(less); 441 } else { 442 // Close 443 readMoreContainer.removeClass('open'); 444 readMoreContainer.css({ 'max-height': readMoreDefaultHeight }); 445 $(this).text(more); 446 447 // Scroll to top of section when closing 448 var headerHeight = $('.be-header').outerHeight(); 449 var dataScrollTo = $(this).closest('.pdp-section'); 450 var dataScrollToAdjust = $('.pdp-header-bar-sub-navigation-btn').data('scroll-to-adjust'); 451 var dataScrollToBlock = dataScrollTo.offset().top - dataScrollToAdjust - headerHeight; 452 $('html, body').stop(); 453 $('html, body').animate({ 454 scrollTop: dataScrollToBlock 455 }, 400); 456 return false;
457 } 458 }); 459 }); 460 }, 1500); 461 } 462 463 // BE - Datepicker - Default Class - Simple datepicker mostly for modals (returns valid after selecting date) 464 if ($('.be-datepicker').length) { 465 $('.be-datepicker').datepicker().change(function () { $(this).valid() }); 466 } 467 468 // BE - Datepicker - Fix for SEO Lighthouse Audit & ADA 469 setTimeout(function () { 470 $('.ui-datepicker-prev').attr('title', 'Prev Calendar').attr('href', '#'); 471 $('.ui-datepicker-next').attr('title', 'Next Calendar').attr('href', '#'); 472 $(document).on('click','.ui-datepicker-prev, .ui-datepicker-next', function(e) { 473 e.stopPropagation(); 474 return false; 475 }); 476 $('.dropdown-toggle').attr('role', ''); 477 }, 500); 478 479 // BE - Selectpicker - Validation - Remove Error Label when Selection is made 480 $('.selectpicker').on('change', function () { 481 $(this).next('.error').hide(); 482 }); 483 484 // BE - Scroll to top Arrow 485 var lastScrollTop = 0; 486 var delta = 200; 487 var timer; 488 var scrollArea = $(window); 489 function scrollToTopRemove() { 490 timer = setTimeout(function () { 491 $('.be-scroll-to-top').removeClass('in'); 492 }, 3000); 493 } 494 scrollArea.on('scroll', function () { 495 var deviceHeight = $(window).outerHeight(); 496 var scrollHeight = $(scrollArea).scrollTop(); 497 // Scroll intent difference 498 if (Math.abs(lastScrollTop - scrollHeight) >= delta) { 499 if (scrollHeight > lastScrollTop) { 500 // Scrolling Down 501 $('.be-scroll-to-top').removeClass('in'); 502 } else { 503 // Scrolling Up 504 // If you are far enough down to want to quickly scroll up 505 if (scrollHeight > deviceHeight) { 506 $('.be-scroll-to-top').addClass('in'); 507 clearTimeout(timer); 508 scrollToTopRemove(); 509 } else { 510 $('.be-scroll-to-top').removeClass('in'); 511 } 512 } 513 lastScrollTop = scrollHeight; 514 } 515 }); 516 $(document).on('click', '.be-scroll-to-top-btn', function () { 517 $('html, body').animate({ scrollTop: $('html').position().top }, 800); 518 }); 519 520 // Compare Favorites - Remove From Favorites List 521 if ($('.compare-favorites-row').length) { 522 $(document).on('click', '.compare-favorites-remove-favorite-btn', function(){ 523 // Remove from Favorites List 524 updateFavoritesList($(this), '.compare-favorites-row', 'remove'); 525 var thisRow = $(this).closest('.compare-favorites-row'); 526 var thisRowID = thisRow.data('unitcode'); 527 // Remove from Modal 528 $(`.compare-favorites-send-to-a-friend-modal .property-info[data-unitcode="${thisRowID}"]`).remove(); 529 // Remove Row 530 thisRow.remove(); 531 }); 532 } 533 534 // Compare Favorites - DataTables 535 if ($('#favoritePropertiesTable').length) { 536 $('#favoritePropertiesTable').DataTable({ 537 searching: false, 538 paging: false, 539 info: false 540 }); 541 } 542 543 // Compare Favorites - Send to a Friend Form 544 if ($('#sendToFriendCompare').length) { 545 $('form#sendToFriendCompare').validate({ 546 submitHandler: function(form){ 547 $.ajax({ 548 type: 'POST', 549 url: siteFolder + 'ajax/sendCompareFavorites' + siteURLEnding, 550 data: $('form#sendToFriendCompare').serialize(), 551 dataType: 'text', 552 success: function (response) { 553 response = $.trim(response); 554 if(response === 'success') { 555 closeModal(); 556 $.fn.beToast({ 557 icon: 'share-solid', 558 iconColor: 'site-color-1', 559 title: 'Send to a Friend', 560 body: 'Your email has been sent!', 561 delay: 7000 562 }); 563 $('form#sendToFriendCompare div.g-recaptcha-error').html(''); 564 } else { 565 $('form#sendToFriendCompare div.g-recaptcha-error').html(alertMessage('alert-danger','You must complete the reCAPTCHA')); 566 } 567 } 568 }); 569 return false; 570 } 571 }); 572 } 573 574});
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.