/*jshint esversion: 6*/
if(window.performance.mark) {
window.performance.mark('startJSLoad');
}
//FUNCTION TO CONVERT POST DATA OBJECTS
function postData(data) {
return Object.keys(data).map( function(k){
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
}).join('&');
}
//SETUP MEDIA QUERIES IN JS
var xsDown = window.matchMedia("(max-width:575px)");
//DO OUR INITAL CHECK FOR LAZY LOADING
if(window.performance.mark) {
window.performance.mark('startLazyLoad');
}
//SETUP INTERSECTION OBSERVER CONFIG
const config = {
root: null,
rootMargin: '300px 100% 300px 100%', //300px above & below | 100% left & right
threshold: 0
};
//SETUP INTERSECTION OBSERVER FUNCTION
let observer = new IntersectionObserver(function(entries, self) {
entries.forEach(entry => {
//GET THE ACTUAL ELEMENT AND ITS TAG
let elem = entry.target;
let type = elem.tagName;
//LOAD NO MATTER WHERE THEY ARE
if(elem.classList.contains("modal")) {
let {Modal} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.classList.contains("toast")){
(async () => {
let {Toast} = await import('/js/bootstrap/bootstrapesm.js');
let toastTrigger = document.getElementById('liveToastBtn');
let toastLiveExample = document.getElementById('liveToast');
if (toastTrigger) {
toastTrigger.addEventListener('click', function () {
var toast = new Toast(toastLiveExample);
toast.show();
});
}
})();
}
//LAZY LOAD ONLY IF COMING INTO VIEW
if (entry.isIntersecting) {
if(type == "IMG" && (elem.classList.contains("defer-img") || elem.classList.contains("defer_img"))) {
loadIMGTAG(elem);
} else if(type == "PICTURE" && (elem.classList.contains("defer-img") || elem.classList.contains("defer_img"))) {
loadPICTAG(elem);
} else if(elem.classList.contains("defer-img") || elem.classList.contains("defer_img")) {
loadIMGCSS(elem);
} else if(type == "IFRAME" && (elem.classList.contains("defer-iframe") || elem.classList.contains("defer_iframe"))) {
loadIFRAME(elem);
} else if(type == "VIDEO" && (elem.classList.contains("defer-video") || elem.classList.contains("defer_video"))) {
loadVIDEO(elem);
} else if(elem.dataset.bsDismiss && elem.dataset.bsDismiss == "alert"){
let {Alert} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.dataset.bsToggle && (elem.dataset.bsToggle == "button" || elem.dataset.bsToggle == "buttons")){
let {Button} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.classList.contains("carousel")) {
let {Carousel} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.dataset.bsToggle && elem.dataset.bsToggle == "collapse"){
let {Collapse} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.dataset.bsToggle && elem.dataset.bsToggle == "dropdown"){
let {Dropdown} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.dataset.bsToggle && elem.dataset.bsToggle == "popover"){
(async () => {
let {Popover} = await import('/js/bootstrap/bootstrapesm.js');
new Popover(elem);
})();
} else if(elem.dataset.bsSpy && elem.dataset.bsSpy == "scroll"){
(async () => {
let {ScrollSpy} = await import('/js/bootstrap/bootstrapesm.js');
ScrollSpy.getOrCreateInstance(elem);
})();
} else if(elem.dataset.bsToggle && elem.dataset.bsToggle == "tab"){
let {Tab} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.dataset.bsToggle && elem.dataset.bsToggle == "offcanvas"){
let {Offcanvas} = import('/js/bootstrap/bootstrapesm.js');
} else if(elem.dataset.bsToggle && elem.dataset.bsToggle == "tooltip"){
(async () => {
let {Tooltip} = await import('/js/bootstrap/bootstrapesm.js');
new Tooltip(elem);
})();
} else if (elem.id == "payment-form") {
let promise1 = loadScript('StripeJS',('https://js.stripe.com/v3/'));
let promise2 = loadScript('FormValidation',(jsMin === true ? '/js/min/formValidationmin.'+jsFingerprint+'.js':'/js/formValidation.'+jsFingerprint+'.js'));
Promise.all([promise1,promise2]).then(function(){
loadScript('FormValidationBS5',(jsMin === true ? '/js/min/Bootstrap5min.'+jsFingerprint+'.js':'/js/Bootstrap5.'+jsFingerprint+'.js')).then(() => {
getPaymentForm(elem);
});
});
} else if(elem.classList.contains("secureForm") || elem.classList.contains("validateForm")) {
if(elem.classList.contains("validateForm")) {
loadScript('FormValidation',(jsMin === true ? '/js/min/formValidationmin.'+jsFingerprint+'.js':'/js/formValidation.'+jsFingerprint+'.js')).then(function(){
loadScript('FormValidationBS5',(jsMin === true ? '/js/min/Bootstrap5min.'+jsFingerprint+'.js':'/js/Bootstrap5.'+jsFingerprint+'.js')).then(() => {
FormValidation.formValidation(
elem,
{
plugins: {
trigger: new FormValidation.plugins.Trigger(),
submitButton: new FormValidation.plugins.SubmitButton(),
defaultSubmit: new FormValidation.plugins.DefaultSubmit(),
bootstrap5: new FormValidation.plugins.Bootstrap5({
rowSelector: '.mb-3',
}),
declarative: new FormValidation.plugins.Declarative()
},
}
);
});
});
}
if(elem.classList.contains("secureForm")) {
let spamStopper = document.createElement('input');
spamStopper.type = 'hidden';
spamStopper.name = 'ts';
spamStopper.value = token;
elem.appendChild(spamStopper);
}
} else if(elem.classList.contains("import_static_map")) {
swapStaticMap(elem);
} else if(elem.classList.contains("before_after_container")){
loadScript('InfoStarBA',(jsMin === true ? '/js/min/infostar_before_aftermin.'+jsFingerprint+'.js':'/js/infostar_before_after.'+jsFingerprint+'.js'));
} else if(elem.classList.contains("datepicker")) {
loadScript('Datepicker',(jsMin === true ? '/js/min/flatpickrmin.'+jsFingerprint+'.js':'/js/flatpickr.'+jsFingerprint+'.js')).then(function(){
flatpickr(elem, {
dateFormat: 'm/d/Y',
allowInput: true,
onOpen: function() {
loadCss('SiteCSS',(jsMin === true ? '/css/sitemin.'+cssFingerprint+'.css':'/css/site.'+cssFingerprint+'.css'));
}
});
});
}
self.unobserve(elem);
}
});
}, config);
//GET EVERYTHING WE NEED TO LAZY LOAD
const elems = document.querySelectorAll(".defer-img, .defer_img, .defer-iframe, .defer_iframe, .defer-video, .defer_video, #payment-form, .import_static_map, .secureForm, .validateForm, .carousel, .modal, .before_after_container, .datepicker, .sticky, [data-bs-dismiss='alert'], [data-bs-toggle='button'], [data-bs-toggle='buttons'], [data-bs-toggle='collapse'], [data-bs-toggle='dropdown'], [data-bs-toggle='offcanvas'], [data-bs-toggle='popover'], [data-bs-spy='scroll'], [data-bs-toggle='tab'], .toast, [data-bs-toggle='tooltip']");
//PASS EVERYTHING TO THE INTERSECTION OBSERVER
elems.forEach(elem => {
observer.observe(elem);
});
if(window.performance.mark) {
window.performance.mark('endLazyLoad');
window.performance.measure('lazyLoadMeasure', 'startLazyLoad', 'endLazyLoad');
var importLazyLoadMeasure = window.performance.getEntriesByName('lazyLoadMeasure');
console.log("LazyLoad: "+importLazyLoadMeasure[0].duration+"ms");
}
//LAZY LOAD AN IMAGE TAG
function loadIMGTAG(elem) {
if (xsDown.matches) {
if (elem.classList.contains("no-mobile")) {
elem.parentNode.removeChild(elem);
} else {
let src = elem.getAttribute('data-src');
let srcset = elem.getAttribute('data-srcset');
let sizes = elem.getAttribute('data-sizes');
if(src !== null) {
elem.src = src;
}
if(srcset !== null) {
elem.srcset = srcset;
}
if(sizes !== null) {
elem.sizes = sizes;
}
}
} else {
let src = elem.getAttribute('data-src');
let srcset = elem.getAttribute('data-srcset');
let sizes = elem.getAttribute('data-sizes');
if(src !== null) {
elem.src = src;
}
if(srcset !== null) {
elem.srcset = srcset;
}
if(sizes !== null) {
elem.sizes = sizes;
}
}
}
//LAZY LOAD A PICTURE TAG
function loadPICTAG(elem) {
if (xsDown.matches) {
if (elem.classList.contains("no-mobile")) {
elem.parentNode.removeChild(elem);
} else {
let sources = elem.querySelectorAll("source");
sources.forEach(source => {
let src = source.getAttribute('data-src');
let srcset = source.getAttribute('data-srcset');
let sizes = source.getAttribute('data-sizes');
if(src !== null) {
source.src = src;
}
if(srcset !== null) {
source.srcset = srcset;
}
if(sizes !== null) {
source.sizes = sizes;
}
});
let img = elem.querySelector("img");
let src = img.getAttribute('data-src');
let srcset = img.getAttribute('data-srcset');
let sizes = img.getAttribute('data-sizes');
if(src !== null) {
img.src = src;
}
if(srcset !== null) {
img.srcset = srcset;
}
if(sizes !== null) {
img.sizes = sizes;
}
}
} else {
let sources = elem.querySelectorAll("source");
sources.forEach(source => {
let src = source.getAttribute('data-src');
let srcset = source.getAttribute('data-srcset');
let sizes = source.getAttribute('data-sizes');
if(src !== null) {
source.src = src;
}
if(srcset !== null) {
source.srcset = srcset;
}
if(sizes !== null) {
source.sizes = sizes;
}
});
let img = elem.querySelector("img");
let src = img.getAttribute('data-src');
let srcset = img.getAttribute('data-srcset');
let sizes = img.getAttribute('data-sizes');
if(src !== null) {
img.src = src;
}
if(srcset !== null) {
img.srcset = srcset;
}
if(sizes !== null) {
img.sizes = sizes;
}
}
}
//LAZY LOAD CSS BACKGROUND IMAGE
function loadIMGCSS(elem) {
if (xsDown.matches) {
if (elem.classList.contains("no-mobile")) {
//DO NOTHING
} else {
elem.classList.remove('defer-img');
}
} else {
elem.classList.remove('defer-img');
}
}
//LAZY LOAD IFRAME
function loadIFRAME(elem) {
if (xsDown.matches) {
if (elem.classList.contains("no-mobile")) {
elem.parentNode.removeChild(elem);
} else {
let src = elem.getAttribute('data-src');
elem.src = src;
}
} else {
let src = elem.getAttribute('data-src');
elem.src = src;
}
}
//LAZY LOAD HTML5 VIDEO
function loadVIDEO(elem) {
//HTML5 VIDEO
if(xsDown.matches){
if(elem.classList.contains("no_mobile")){
//DO NOTHING
} else {
let source = elem.querySelector('source');
let src = source.getAttribute('data-src');
source.src = src;
elem.get(0).load();
}
}
else{
let source = elem.querySelector('source');
let src = source.getAttribute('data-src');
source.src = src;
elem.load();
}
}
//STATIC MAP CLICK EVENT
function swapStaticMap(elem){
elem.addEventListener("click",function(event){
let e = event.target;
if(e.classList.contains("static_map_swap")) {
let embed = e.dataset.embed;
elem.innerHTML = '';
}
});
}
//PAYMENT FORM
//STRIPE SPECIFIC FUNCTIONS
function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}
function createToken(stripe,card) {
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server
stripeTokenHandler(result.token);
}
});
}
//SETUP THE PAYMENT FORM
function getPaymentForm(elem){
let stripeKey = document.getElementById("payment-form-stripe").value;
if(stripeKey == "" || stripeKey == null){
alert("Stripe Keys Not SetPlease Set Up Your Stripe Keys.","warning");
return false;
}
//LOAD SPAM STOPPER
let spamStopper = document.createElement('input');
spamStopper.type = 'hidden';
spamStopper.name = 'ts';
spamStopper.value = token;
elem.appendChild(spamStopper);
FormValidation.formValidation(
elem,
{
plugins: {
trigger: new FormValidation.plugins.Trigger(),
submitButton: new FormValidation.plugins.SubmitButton(),
bootstrap5: new FormValidation.plugins.Bootstrap5({
rowSelector: '.mb-3',
}),
declarative: new FormValidation.plugins.Declarative()
},
}
).on('core.form.valid',function(){
createToken(stripe,card);
});
//STRIPE API
var stripe = Stripe(stripeKey);
var elements = stripe.elements();
var card = elements.create('card');
card.mount('#card-element');
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
document.getElementById('payment-submit').disabled = true;
document.getElementById('payment-submit').classList.add('disabled');
} else {
displayError.textContent = '';
document.getElementById('payment-submit').disabled = false;
document.getElementById('payment-submit').classList.remove('disabled');
}
});
}
//SET UP SEARCH BOX AUTOCOMPLETE
let searchBars = document.querySelectorAll('.search_term');
function getAutoComplete() {
let data = postData({action:"get_autocomplete"});
let request = new XMLHttpRequest();
request.open('POST','/common/javascript_variables.php',true);
request.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8');
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
let data = JSON.parse(request.responseText);
new autoComplete({
selector: '.search_term',
minChars: 1,
source: function(term,suggest) {
term = term.toLowerCase();
var choices = data;
var matches = [];
for (let i=0; i{
let target = event.target;
if(target.classList.contains('sidekick_link')) {
let video = target.dataset.video;
videoModalBody.innerHTML = video+sidekickModalLinks;
}
});
videoModal.addEventListener("show.bs.modal",(event)=>{
let btn = event.relatedTarget;
if(btn.dataset.sidekick_alt) {
sidekickModalLinks = '';
} else {
sidekickModalLinks = '';
}
document.getElementById("videoModalLabel").innerHTML = btn.dataset.title;
videoModalBody.innerHTML = btn.dataset.content+sidekickModalLinks;
});
videoModal.addEventListener("hidden.bs.modal",()=>{
document.getElementById("videoModalLabel").innerHTML = "";
videoModalBody.innerHTML = "";
});
}
//TRACK ALL CLICKS ON PHONE NUMBERS W/ HREF %PHONE%
var bounce = false; // debounce check
var telLinks = document.querySelectorAll('a[href^="tel:"]');
telLinks.forEach(function(elem){
elem.addEventListener('click',function(){
// See if CID is set
let urlParams = new URLSearchParams(window.location.search);
let afterSplit = urlParams.get('cid') !== null ? "cid:" + urlParams.get('cid') : "no_ad_id";
// If everything went well shows split[1], if not then de default message is shown
if (!bounce){
var trackerName = ga.getAll()[0].get('name');
ga(trackerName + '.send', 'event', { eventCategory: 'tel:link', eventAction:'click', eventLabel:'phone_num_'+afterSplit, eventValue: 1 });
bounce = true;
}
});
});
//LOAD CSS IF APPROPRIATE
function loadCSS(event) {
console.log("loadCSS");
let scrollPosition = window.pageYOffset || document.documentElement.scrollTop;
let load = false;
if(event.type == "scroll" || event == "load") {
if(scrollPosition > 5) {
load = true;
}
} else if(event.type == "click" || event.type == "keydown") {
load = true;
}
if(load === true) {
loadCss('SiteCSS',(jsMin === true ? '/css/sitemin.'+cssFingerprint+'.css':'/css/site.'+cssFingerprint+'.css'));
window.removeEventListener("scroll",loadCSS);
document.removeEventListener("click",loadCSS);
document.removeEventListener("keydown",loadCSS);
}
}
//LOAD CSS
window.addEventListener("scroll",loadCSS);
document.addEventListener("click",loadCSS);
document.addEventListener("keydown",loadCSS);
loadCSS("load");
if(window.performance.mark) {
window.performance.mark('endJSLoad');
window.performance.measure('JSLoadMeasure', 'startJSLoad', 'endJSLoad');
var JSLoadMeasure = window.performance.getEntriesByName('JSLoadMeasure');
console.log("JSLoad: "+JSLoadMeasure[0].duration+"ms\r\nAll JS Loaded/Ran:"+window.performance.now()+"ms");
}