1<!doctype html><html lang="en-US" prefix="og: https://ogp.me/ns#"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="profile" href="https://gmpg.org/xfn/11"><link media="all" href="https://goodtimesnj.com/wp-content/cache/autoptimize/css/autoptimize_5daca45467f2b9cd05052dee5cb3adde.css" rel="stylesheet"><title>Contact Us - Good Times Inflatables</title><meta name="robots" content="follow, index, max-snippet:-1, max-video-preview:-1, max-image-preview:large"/><link rel="canonical" href="https://goodtimesnj.com/contact-us/" /><meta property="og:locale" content="en_US" /><meta property="og:type" content="article" /><meta property="og:title" content="Contact Us - Good Times Inflatables" /><meta property="og:description" content="Contact Us Need help deciding what you need? Let’s get in touch!This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply." /><meta property="og:url" content="https://goodtimesnj.com/contact-us/" /><meta property="og:site_name" content="Good Times Inflatables" /><meta property="og:updated_time" content="2023-10-30T15:18:30+00:00" /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="Contact Us - Good Times Inflatables" /><meta name="twitter:description" content="Contact Us Need help deciding what you need? Let’s get in touch!This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply." /><meta name="twitter:label1" content="Time to read" /><meta name="twitter:data1" content="Less than a minute" />
1<script type="application/ld+json" class="rank-math-schema">{"@context":"https://schema.org","@graph":[{"@type":"BreadcrumbList","@id":"https://goodtimesnj.com/contact-us/#breadcrumb","itemListElement":[{"@type":"ListItem","position":"1","item":{"@id":"https://goodtimesnj.com","name":"Home"}},{"@type":"ListItem","position":"2","item":{"@id":"https://goodtimesnj.com/contact-us/","name":"Contact Us"}}]}]}</script>
1 <link rel='dns-prefetch' href='//cdnjs.cloudflare.com' /><link rel="alternate" type="application/rss+xml" title="Good Times Inflatables » Feed" href="https://goodtimesnj.com/feed/" /><link rel="alternate" type="application/rss+xml" title="Good Times Inflatables » Comments Feed" href="https://goodtimesnj.com/comments/feed/" /><link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="https://goodtimesnj.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fgoodtimesnj.com%2Fcontact-us%2F" /><link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="https://goodtimesnj.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fgoodtimesnj.com%2Fcontact-us%2F&format=xml" /><style id="wp-img-auto-sizes-contain-inline-css">img:is([sizes=auto i],[sizes^="auto," i]){contain-intrinsic-size:3000px 1500px} 2/*# sourceURL=wp-img-auto-sizes-contain-inline-css */</style><style id="classic-theme-styles-inline-css">/*! This file is auto-generated */ 3.wp-block-button__link{color:#fff;background-color:#32373c;border-radius:9999px;box-shadow:none;text-decoration:none;padding:calc(.667em + 2px) calc(1.333em + 2px);font-size:1.125em}.wp-block-file__button{background:#32373c;color:#fff;text-decoration:none} 4/*# sourceURL=/wp-includes/css/classic-themes.min.css */</style><style id="global-styles-inline-css">:root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgb(252,185,0) 0%,rgb(255,105,0) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgb(255,105,0) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);
4--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgb(255, 255, 255), 6px 6px rgb(0, 0, 0);--wp--preset--shadow--crisp: 6px 6px 0px rgb(0, 0, 0);}.wp-block-button{--wp--preset--dimension--25: 25%;--wp--preset--dimension--50: 50%;--wp--preset--dimension--75: 75%;--wp--preset--dimension--100: 100%;}:where(body) { margin: 0; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}body{padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #32373c;border-width: 0;color: #fff;font-family: inherit;font-size: inherit;font-style: inherit;font-weight: inherit;letter-spacing: inherit;line-height: inherit;padding-top: calc(0.667em + 2px);padding-right: calc(1.333em + 2px);padding-bottom: calc(0.667em + 2px);padding-left: calc(1.333em + 2px);text-decoration: none;text-transform: inherit;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}
4.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;} 5:root :where(.wp-block-icon svg){width: 24px;} 6:where(.wp-block-gallery.is-layout-flex){gap: var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) );}:where(.wp-block-gallery.is-layout-grid){gap: var( --wp--style--gallery-gap-default, var( --gallery-block--gutter-size, var( --wp--style--block-gap, 0.5em ) ) );} 7:where(.wp-block-latest-posts.is-layout-flex){gap: 1.25em;}:where(.wp-block-latest-posts.is-layout-grid){gap: 1.25em;} 8:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;} 9:where(.wp-block-term-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-term-template.is-layout-grid){gap: 1.25em;} 10:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;} 11:root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;} 12/*# sourceURL=global-styles-inline-css */</style><link rel='stylesheet' id='slick-carousel-css-css' href='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css?ver=7.1.2' media='all' /><link rel='stylesheet' id='slick-carousel-theme-css-css' href='https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css?ver=7.1.2' media='all' />
12<script id="jquery-core-js" src="https://goodtimesnj.com/wp-includes/js/jquery/jquery.min.js?ver=3.7.1"></script>
12
12<script id="io-scripts-js-extra">var io_scripts_vars = {"io_username":"watsonanthony96","io_locationid":"0","io_phonenumber":"(732) 451-6873","io_emailaddress":"[email protected]","io_businesshours":"","io_facebooklink":"https://www.facebook.com/","io_twitterlink":"https://twitter.com/","io_instagramlink":"https://www.instagram.com/","io_youtubelink":"","io_fpnumber":"","io_companyname":"Good Times Inflatables"}; 13//# sourceURL=io-scripts-js-extra</script>
13 <link rel="https://api.w.org/" href="https://goodtimesnj.com/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://goodtimesnj.com/wp-json/wp/v2/pages/3288" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://goodtimesnj.com/xmlrpc.php?rsd" /><link rel='shortlink' href='https://goodtimesnj.com/?p=3288' />
vendor: 65 bytes, line 13
13 <script async src="https://www.googletagmanager.com/gtag/js?id=
13AW-11061098742
vendor: 12 bytes, line 13
13"></script>
13<script>
vendor: 134 bytes, lines 13-17
13window.dataLayer = window.dataLayer || []; 14 function gtag(){dataLayer.push(arguments);} 15 gtag('js', new Date()); 16 17 gtag('config', '
17AW-11061098742
vendor: 3 bytes, line 17
17');
17</script>
17<meta name="generator" content="Elementor 4.3.4; features: additional_custom_breakpoints; settings: css_print_method-external, google_font-enabled, font_display-auto">
17<script type="text/javascript">(function () { 18 var s = document.createElement("script"), 19 h = document.head; 20 s.async = 1; 21 s.src = "https://monitor.fraudblocker.com/fbt.js?sid=6-se-NMOA7EyP22aJZF8p"; 22 h.appendChild(s); 23 })();</script>
23 <noscript> <a href="https://fraudblocker.com" rel="nofollow"> <img src="https://monitor.fraudblocker.com/fbt.gif?sid=6-se-NMOA7EyP22aJZF8p" alt="Fraud Blocker" /> </a> </noscript>
23<script id='pixel-script-poptin' src='https://cdn.popt.in/pixel.js?id=4a9cd5def0446' async='true'></script>
23 <style>.e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload), 24 .e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload) * { 25 background-image: none !important; 26 } 27 @media screen and (max-height: 1024px) { 28 .e-con.e-parent:nth-of-type(n+3):not(.e-lazyloaded):not(.e-no-lazyload), 29 .e-con.e-parent:nth-of-type(n+3):not(.e-lazyloaded):not(.e-no-lazyload) * { 30 background-image: none !important; 31 } 32 } 33 @media screen and (max-height: 640px) { 34 .e-con.e-parent:nth-of-type(n+2):not(.e-lazyloaded):not(.e-no-lazyload), 35 .e-con.e-parent:nth-of-type(n+2):not(.e-lazyloaded):not(.e-no-lazyload) * { 36 background-image: none !important; 37 } 38 }</style><link rel="icon" href="https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-cropped-Good-time-inflatables-LLC-logo-32x32.png" sizes="32x32" /><link rel="icon" href="https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-cropped-Good-time-inflatables-LLC-logo-192x192.png" sizes="192x192" /><link rel="apple-touch-icon" href="https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-cropped-Good-time-inflatables-LLC-logo-180x180.png" /><meta name="msapplication-TileImage" content="https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-cropped-Good-time-inflatables-LLC-logo-270x270.png" /><style id="wp-custom-css">.grecaptcha-badge { visibility: hidden; } 39 40.search-submit{display:none;} 41 42.cartInfo{ 43 display:none !important; 44} 45.io-footer-link a { 46color: var(--e-global-color-accent, orange); 47} 48 49.catDescriptionIO.catDescriptionIO_small.elementor-widget-text-editor { 50 padding: 10px; 51 font-size: small; 52 text-align: left; 53} 54 55.io_brand { 56 margin-bottom: 20px; 57}</style></head><body class="wp-singular page-template-default page page-id-3288 wp-custom-logo wp-theme-io-kenos mega-menu-max-mega-menu-4 mega-menu-max-mega-menu-5 mega-menu-max-mega-menu-6 mega-menu-max-mega-menu-7 mega-menu-max-mega-menu-8 mega-menu-max-mega-menu-9 elementor-default elementor-kit-812 elementor-page elementor-page-3288"><header data-elementor-type="header" data-elementor-id="3423" class="elementor elementor-3423 elementor-location-header" data-elementor-post-type="elementor_library"><section class="elementor-section elementor-top-section elementor-element elementor-element-18dac2c4 elementor-section-full_width elementor-section-height-default elementor-section-height-default" data-id="18dac2c4" data-element_type="section" data-e-type="section" data-settings="{"background_background":"gradient"}"><div class="elementor-background-overlay"></div><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-639876e6" data-id="639876e6" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><section class="elementor-section elementor-inner-section elementor-element elementor-element-10400a9b elementor-section-content-middle elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="10400a9b" data-element_type="section" data-e-type="section" data-settings="{"background_background":"classic"}"><div class="elementor-background-overlay"></div><div class="elementor-container elementor-column-gap-no"><div class="elementor-column elementor-col-20 elementor-inner-column elementor-element elementor-element-736bc25b" data-id="736bc25b" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-3a6ab9dd elementor-widget elementor-widget-theme-site-logo elementor-widget-image" data-id="3a6ab9dd" data-element_type="widget" data-e-type="widget" data-widget_type="theme-site-logo.default"><div class="elementor-widget-container"> <a href="https://goodtimesnj.com"> <img width="300" height="217" src="https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-Good-time-inflatables-LLC-logo-300x217.png" class="elementor-animation-grow attachment-medium size-medium wp-image-4568" alt="" srcset="https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-Good-time-inflatables-LLC-logo-300x217.png 300w, https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-Good-time-inflatables-LLC-logo-1024x739.png 1024w, https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-Good-time-inflatables-LLC-logo-768x555.png 768w, https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-Good-time-inflatables-LLC-logo-1536x1109.png 1536w, https://goodtimesnj.com/wp-content/uploads/2024/01/cropped-Good-time-inflatables-LLC-logo-2048x1479.png 2048w" sizes="(max-width: 300px) 100v
57w, 300px" /> </a></div></div></div></div><div class="elementor-column elementor-col-20 elementor-inner-column elementor-element elementor-element-2331cf29 elementor-hidden-desktop elementor-hidden-mobile" data-id="2331cf29" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-c5866f e-grid-align-right e-grid-align-mobile-center e-grid-align-tablet-center elementor-shape-rounded elementor-grid-0 elementor-widget elementor-widget-social-icons" data-id="c5866f" data-element_type="widget" data-e-type="widget" data-widget_type="social-icons.default"><div class="elementor-widget-container"><div class="elementor-social-icons-wrapper elementor-grid" role="list"> <span class="elementor-grid-item" role="listitem"> <a class="elementor-icon elementor-social-icon elementor-social-icon-facebook elementor-repeater-item-046e794" target="_blank"> <span class="elementor-screen-only">Facebook</span> <i aria-hidden="true" class="fab fa-facebook"></i> </a> </span> <span class="elementor-grid-item" role="listitem"> <a class="elementor-icon elementor-social-icon elementor-social-icon-instagram elementor-repeater-item-42d1c29" target="_blank"> <span class="elementor-screen-only">Instagram</span> <i aria-hidden="true" class="fab fa-instagram"></i> </a> </span></div></div></div></div></div><div class="elementor-column elementor-col-20 elementor-inner-column elementor-element elementor-element-6c025e19" data-id="6c025e19" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap"></div></div><div class="elementor-column elementor-col-20 elementor-inner-column elementor-element elementor-element-2115d61 elementor-hidden-tablet" data-id="2115d61" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-77183664 e-grid-align-right e-grid-align-mobile-center e-grid-align-tablet-center elementor-shape-rounded elementor-grid-0 elementor-widget elementor-widget-social-icons" data-id="77183664" data-element_type="widget" data-e-type="widget" data-widget_type="social-icons.default"><div class="elementor-widget-container"><div class="elementor-social-icons-wrapper elementor-grid" role="list"> <span class="elementor-grid-item" role="listitem"> <a class="elementor-icon elementor-social-icon elementor-social-icon-facebook elementor-repeater-item-046e794" target="_blank"> <span class="elementor-screen-only">Facebook</span> <i aria-hidden="true" class="fab fa-facebook"></i> </a> </span> <span class="elementor-grid-item" role="listitem"> <a class="elementor-icon elementor-social-icon elementor-social-icon-instagram elementor-repeater-item-6c3313d" href="https://www.instagram.com/good_times_inflatables/?igshid=YmMyMTA2M2Y%3D" target="_blank"> <span class="elementor-screen-only">Instagram</span> <i aria-hidden="true" class="fab fa-instagram"></i> </a> </span></div></div></div><div class="elementor-element elementor-element-604f021b elementor-icon-list--layout-inline elementor-mobile-align-center elementor-tablet-align-center elementor-align-end elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list" data-id="604f021b" data-element_type="widget" data-e-type="widget" data-widget_type="icon-list.default"><div class="elementor-widget-container"><ul class="elementor-icon-list-items elementor-inline-items"><li class="elementor-icon-list-item elementor-inline-item"> <a href="tel:(732)%20451-6873"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-phone-alt"></i> </span> <span class="elementor-icon-list-text">(732) 451-6873</span> </a></li></ul></div></div></div></div><div class="elementor-column elementor-col-20 elementor-inner-column elementor-element elementor-element-2a97e033 elementor-hidden-desktop elementor-hidden-tablet" data-id="2a97e033" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-2af96042 elementor-align-left elementor-mobile-align-center elementor-tablet-align-center elementor-widget elementor-widget-button" data-id="2af96042" data-element_type="widget" data-e-type="widget" data-widget_type="button.default"><div class="elementor-widget-container"><div class="elementor-button-wrapper"> <a class="elementor-button elementor-button-link elementor-size-md elementor-animation-grow" href="https://goodtimesnj.com/io_quoteform/"> <span class="elementor-button-content-wrapper"> <span class="elementor-button-text">Book Now</span> </span> </a></div></div></div></div></div></div></section><section class="elementor-section elementor-inner-section elementor-element elementor-element-537619ae elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="537619ae" data-element_type="section" data-e-type="section" data-settings="{"background_background":"gradient","sticky":"top","sticky_on":["desktop","tablet","mobile"],"sticky_offset":0,"sticky_effects_offset":0,"sticky_anchor_link_offset":0}"><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-49071e97 elementor-hidden-mobile" data-id="49071e97" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-36bc9d17 elementor-align-left elementor-mobile-align-center elementor-tablet-align-center elementor-widget elementor-widget-button" data-id="36bc9d17" data-element_type="widget" data-e-type="widget" data-widget_type="button.default"><div class="elementor-widget-container"><div class="elementor-button-wrapper"> <a class="elementor-button elementor-button-link elementor-size-md elementor-animation-grow" href="https://goodtimesnj.com/io_quoteform/"> <span class="elementor-button-content-wrapper"> <span class="elementor-button-text">Book Now</span> </span> </a></div></div></div></div></div><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-28afc507" data-id="28afc507" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-32fefaef elementor-widget elementor-widget-wp-widget-maxmegamenu" data-id="32fefaef" data-element_type="widget" data-e-type="widget" data-widget_type="wp-widget-maxmegamenu.default"><div class="elementor-widget-container"><div id="mega-menu-wrap-max_mega_menu_5" class="mega-menu-wrap"><div class="mega-menu-toggle"><div class="mega-toggle-blocks-left"></div><div class="mega-toggle-blocks-center"><div class='mega-toggle-block mega-menu-toggle-block mega-toggle-block-1' id='mega-toggle-block-1'><span aria-expanded="false" aria-haspopup="true" role="button" class='mega-toggle-label'><span class='mega-toggle-label-closed'></span><span class='mega-toggle-label-open'></span></span></div></div><div class="mega-toggle-blocks-right"></div></div><ul id="mega-menu-max_mega_menu_5" class="mega-menu max-mega-menu mega-menu-horizontal mega-no-js" data-event="hover_intent" data-effect="fade_up" data-effect-speed="200" data-effect-mobile="disabled" data-effect-speed-mobile="0" data-mobile-force-width="body" data-second-click="go" data-document-click="collapse" data-vertical-behaviour="standard" data-breakpoint="600" data-unbind="true" data-mobile-state="collapse_all" data-mobile-direction="vertical"><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-home mega-has-icon mega-icon-left mega-menu-item-3451" id="mega-menu-item-3451"><a class="dashicons-admin-home mega-menu-link" href="https://goodtimesnj.com/">Home</a></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-megamenu mega-menu-item-has-children mega-align-bottom-left mega-has-icon mega-icon-left mega-menu-item-3450" id="mega-menu-item-3450"><a class="dashicons-cart mega-menu-link" href="https://goodtimesnj.com/rentals/" aria-expanded="false" aria-controls="mega-sub-menu-3450">Inventory<span class="mega-indicator" aria-hidden="true"></span></a><ul class="mega-sub-menu" id='mega-sub-menu-3450'><li class="mega-menu-item mega-menu-item-type-widget widget_widget_featured mega-menu-column-standard mega-menu-columns-6-of-6 mega-menu-item-widget_featured-3" style="--columns:6; --span:6" id="mega-menu-item-widget_featured-3"><div class="widget-text wp_widget_plugin_box panel-grid panel-has-style" style="margin-top:0px;">
57<script>jQuery(document).ready(function(){ 58 jQuery('.io_mm_item .io_item2_list').css('box-shadow', 'none') 59 jQuery('.io_mm_item .io_item2_list').addClass('nohover') 60 61 jQuery('.io_mm_item .io_item2_listcat').css('box-shadow', 'none') 62 jQuery('.io_mm_item .io_item2_listcat').addClass('nohover') 63 })</script>
63<div class="io_mm_outer io_widget_59350 " style="grid-template-columns:repeat(4, calc((100% - 45px)/4)); display:grid;"><style>.io_widget_59350 .io_item2_list_inner .rentNameIO_button {display:none !important;} .io_widget_59350 .io_item2_list_inner .rentNameIO_price {display:none !important;} .io_widget_59350 .io_item2_list .view-product-button {display:none !important;} .io_widget_59350 .io_item2_listcat .view-product-button {display:none !important;} .io_widget_59350 .io_item2_listcat .catDescriptionIO {display:none;}</style><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_timesnjc" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://goodtimesnj.com/rentals/bounce-houses/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://goodtimesnj.com/wp-content/uploads/2025/06/IMG_7452_1724720842_big.jpeg" alt="Bounce Houses" title="Bounce Houses" /></div> </a><div class="cat_div_inner"> <a href="https://goodtimesnj.com/rentals/bounce-houses/"><p class="rentNameIO elementor-heading-title">Bounce Houses</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor">Inflatable bounce houses are great for letting some energy flow out. You can also purchase combo bouncers that include a slide or basketball hoop constructed inside, as well as a bounce zone. We specialize in bounce houses rentals and are glad to cater to the needs of your event.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_timesnjc" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://goodtimesnj.com/rentals/obstacle-course/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://goodtimesnj.com/wp-content/uploads/2026/02/IMG_5771_1707514930_big.jpg" alt="Obstacle Courses" title="Obstacle Courses" /></div> </a><div class="cat_div_inner"> <a href="https://goodtimesnj.com/rentals/obstacle-course/"><p class="rentNameIO elementor-heading-title">Obstacle Courses</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p style="font-family: Tahoma, Geneva, sans-serif;"> Obstacle course inflatables can provide greater interaction and are a fun way for kids to race each other for friendly competitive fun!</p></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_timesnjc" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://goodtimesnj.com/rentals/water-rides/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://goodtimesnj.com/wp-content/uploads/2025/06/IMG_4207_1724721128_big.jpeg" alt="Slides" title="Slides" /></div> </a><div class="cat_div_inner"> <a href="https://goodtimesnj.com/rentals/water-rides/"><p class="rentNameIO elementor-heading-title">Slides</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor">Water slides and water rides are a great option to cool off on an extremely hot summer day! Get wet and have fun with these fun rental water slides as well as water bounce houses.<br>Water rides and slides are an excellent way to cool down an extremely hot summer day! Enjoy getting wet with these water slides and water bounce houses.<br>Water rides and slides are an ideal way to cool down on a hot summer day! Let yourself get wet and have fun by playing on these fun rental water slides as well as water bounce houses.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_timesnjc" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://goodtimesnj.com/rentals/dunk-tanks/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://goodtimesnj.com/wp-content/uploads/2025/06/IMG_5070_1731948676_big.jpeg" alt="Dunk Tanks" title="Dunk Tanks" /></div> </a><div class="cat_div_inner"> <a href="https://goodtimesnj.com/rentals/dunk-tanks/"><p class="rentNameIO elementor-heading-title">Dunk Tanks</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_timesnjc" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://goodtimesnj.com/rentals/games/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://goodtimesnj.com/wp-content/uploads/2026/02/IMG_0182_1733270859_big.jpeg" alt="Games" title="Games" /></div> </a><div class="cat_div_inner"> <a href="https://goodtimesnj.com/rentals/games/"><p class="rentNameIO elementor-heading-title">Games</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p style="font-family: Tahoma, Geneva, sans-serif;"><br></p><br>Games rentals offer an engaging way to bring people together, providing a diverse selection of interactive activities perfect for events, parties, or gatherings. They come in many forms, from classic board games and video games to thrilling physical challenges, offering endless entertainment for all ages.</div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_timesnjc" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://goodtimesnj.com/rentals/chairs-and-tables/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://goodtimesnj.com/wp-content/uploads/2025/07/IMG_0084_1717795049_big.png" alt="Chairs Tables & Tents" title="Chairs Tables & Tents" /></div> </a><div class="cat_div_inner"> <a href="https://goodtimesnj.com/rentals/chairs-and-tables/"><p class="rentNameIO elementor-heading-title">Chairs Tables & Tents</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"></div> </a></div></div></div><div class="io_mm_item elementor-widget-heading simpleCart_ioShelfItem" name="maindiv_timesnjc" style="text-align:center"><div class="io_item2_listcat elementor-widget-heading"> <a href="https://goodtimesnj.com/rentals/generators/"><div class="cat_div"><div class="btn btn-primary view-product-button">View Products</div> <img class="cat_img" src="https://goodtimesnj.com/wp-content/uploads/2026/04/IMG_0083_1717794836_big.jpeg" alt="Generators" title="Generators" /></div> </a><div class="cat_div_inner"> <a href="https://goodtimesnj.com/rentals/generators/"><p class="rentNameIO elementor-heading-title">Generators</p><div class="catDescriptionIO catDescriptionIO_small elementor-widget-text-editor"><p style="font-family: Tahoma, Geneva, sans-serif;"><br></p></div> </a></div></div></div></div></div><style>.io_mm_item .io_item2_list, .io_mm_item .io_item2_listcat, .io_mm_item .io_item2_listrent { margin-bottom: 0px !important; }</style></li></ul></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-current-menu-ancestor mega-current-menu-parent mega-current_page_parent mega-current_page_ancestor mega-menu-item-has-children mega-align-bottom-left mega-menu-flyout mega-has-icon mega-icon-left mega-menu-item-3449" id="mega-menu-item-3449"><a class="dashicons-info-outline mega-menu-link" href="https://goodtimesnj.com/about-us/" aria-expanded="false" aria-controls="mega-sub-menu-3449">About Us<span class="mega-indicator" aria-hidden="true"></span></a><ul class="mega-sub-menu" id='mega-sub-menu-3449'><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-3448" id="mega-menu-item-3448"><a class="mega-menu-link" href="https://goodtimesnj.com/faqs/">FAQs</a></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-current-menu-item mega-page_item mega-page-item-3288 mega-current_page_item mega-menu-item-3445" id="mega-menu-item-3445"><a class="mega-menu-link" href="https://goodtimesnj.com/contact-us/" aria-current="page">Contact Us</a></li><li class="mega-menu-item mega-menu-item-type-post_type mega-menu-item-object-page mega-menu-item-3447" id="mega-menu-item-3447"><a class="mega-menu-link" href="https://goodtimesnj.com/employment/">Employment</a></li></ul></li></ul></div></div></div></div></div><div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-3f76f008" data-id="3f76f008" data-element_type="column" data-e-type="column" data-settings="{"background_background":"classic"}"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-738fa01d ioCart elementor-view-default elementor-widget elementor-widget-icon" data-id="738fa01d" data-element_type="widget" data-e-type="widget" data-widget_type="icon.default"><div class="elementor-widget-container"><div class="elementor-icon-wrapper"><div class="elementor-icon"> <i aria-hidden="true" class="fas fa-shopping-cart"></i></div></div></div></div></div></div></div></section></div></div></div></section></header><main id="main" class="site-main" role="main"><header class="page-header io_phshow"><div class ="elementor-widget-heading"><p id="breadcrumbs" class="io-entry-title elementor-heading-title"><a href="https://goodtimesnj.com">Home</a><span class="separator"> » </span><span class="last">Contact Us</span></p></div></header><div class="page-content"><div data-elementor-type="wp-page" data-elementor-id="3288" class="elementor elementor-3288" data-elementor-post-type="page"><section class="elementor-section elementor-top-section elementor-element elementor-element-8e7331d elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="8e7331d" data-element_type="section" data-e-type="section"><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-85af7fd" data-id="85af7fd" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-e8735dc elementor-widget elementor-widget-heading" data-id="e8735dc" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default"><div class="elementor-widget-container"><h1 class="elementor-heading-title elementor-size-default">Contact Us</h1></div></div><div class="elementor-element elementor-element-1462b40 elementor-widget elementor-widget-text-editor" data-id="1462b40" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"><p>Need help deciding what you need? Let’s get in touch!</p></div></div><div class="elementor-element elementor-element-f2f47e5 elementor-button-align-stretch elementor-widget elementor-widget-form" data-id="f2f47e5" data-element_type="widget" data-e-type="widget" data-settings="{"step_next_label":"Next","step_previous_label":"Previous","button_width":"100","step_type":"number_text","step_icon_shape":"circle"}" data-widget_type="form.default"><div class="elementor-widget-container"><form class="elementor-form" method="post" name="New Form" aria-label="New Form"> <input type="hidden" name="post_id" value="3288"/> <input type="hidden" name="form_id" value="f2f47e5"/> <input type="hidden" name="referer_title" value="Contact Us - Good Times Inflatables" /> <input type="hidden" name="queried_id" value="3288"/><div class="elementor-form-fields-wrapper elementor-labels-above"><div class="elementor-field-type-text elementor-field-group elementor-column elementor-field-group-firstname elementor-col-50 elementor-field-required"> <label for="form-field-firstname" class="elementor-field-label"> First name </label> <input size="1" type="text" name="form_fields[firstname]" id="form-field-firstname" class="elementor-field elementor-size-sm elementor-field-textual" required="required"></div><div class="elementor-field-type-text elementor-field-group elementor-column elementor-field-group-lastname elementor-col-50 elementor-field-required"> <label for="form-field-lastname" class="elementor-field-label"> Last Name </label> <input size="1" type="text" name="form_fields[lastname]" id="form-field-lastname" class="elementor-field elementor-size-sm elementor-field-textual" required="required"></div><div class="elementor-field-type-tel elementor-field-group elementor-column elementor-field-group-cellphone elementor-col-50 elementor-field-required"> <label for="form-field-cellphone" class="elementor-field-label"> Phone </label> <input size="1" type="tel" name="form_fields[cellphone]" id="form-field-cellphone" class="elementor-field elementor-size-sm elementor-field-textual" required="required" pattern="[0-9()#&+*-=.]+" title="Only numbers and phone characters (#, -, *, etc) are accepted."></div><div class="elementor-field-type-email elementor-field-group elementor-column elementor-field-group-email elementor-col-50 elementor-field-required"> <label for="form-field-email" class="elementor-field-label"> Email </label> <input size="1" type="email" name="form_fields[email]" id="form-field-email" class="elementor-field elementor-size-sm elementor-field-textual" required="required"></div><div class="elementor-field-type-acceptance elementor-field-group elementor-column elementor-field-group-oktotext elementor-col-100"> <label for="form-field-oktotext" class="elementor-field-label"> Text notifications okay? </label><div class="elementor-field-subgroup"> <span class="elementor-field-option"> <input type="checkbox" name="form_fields[oktotext]" id="form-field-oktotext" class="elementor-field elementor-size-sm elementor-acceptance-field" checked="checked"> </span></div></div><div class="elementor-field-type-hidden elementor-field-group elementor-column elementor-field-group-okToTextPresent elementor-col-100"> <input size="1" type="hidden" name="form_fields[okToTextPresent]" id="form-field-okToTextPresent" class="elementor-field elementor-size-sm elementor-field-textual" value="1"></div><div class="elementor-field-type-textarea elementor-field-group elementor-column elementor-field-group-notes elementor-col-100"> <label for="form-field-notes" class="elementor-field-label"> Message </label><textarea class="elementor-field-textual elementor-field elementor-size-sm" name="form_fields[notes]" id="form-field-notes" rows="4"></textarea></div><div class="elementor-field-type-recaptcha_v3 elementor-field-group elementor-column elementor-field-group-field_0b7cf9f elementor-col-100 recaptcha_v3-bottomright"><div class="elementor-field" id="form-field-field_0b7cf9f"><div class="elementor-g-recaptcha" data-sitekey="6LcSNw8eAAAAAN1cy4N20ZlzWX4YetiG7zmLXN_f" data-type="v3" data-action="Form" data-badge="bottomright" data-size="invisible"></div></div></div><div class="elementor-field-type-text"> <input size="1" type="text" name="form_fields[website_url]" id="form-field-website_url" class="elementor-field elementor-size-sm " style="display:none !important;"></div><div class="elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons"> <button class="elementor-button elementor-size-sm" type="submit"> <span class="elementor-button-content-wrapper"> <span class="elementor-button-text">Send</span> </span> </button></div></div></form></div></div><div class="elementor-element elementor-element-9052145 elementor-widget elementor-widget-text-editor" data-id="9052145" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"> This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Privacy Policy</a> and <a href="https://policies.google.com/terms" target="_blank" rel="noope
63ner">Terms of Service</a> apply.</div></div></div></div></div></section></div></div></main><footer data-elementor-type="footer" data-elementor-id="3442" class="elementor elementor-3442 elementor-location-footer" data-elementor-post-type="elementor_library"><section class="elementor-section elementor-top-section elementor-element elementor-element-bf6ac06 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="bf6ac06" data-element_type="section" data-e-type="section" data-settings="{"background_background":"classic"}"><div class="elementor-background-overlay"></div><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-34f4dbec" data-id="34f4dbec" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-2888c14d elementor-widget elementor-widget-heading" data-id="2888c14d" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default"><div class="elementor-widget-container"><h2 class="elementor-heading-title elementor-size-xl">Contact Us</h2></div></div><div class="elementor-element elementor-element-8b59e7a elementor-widget elementor-widget-text-editor" data-id="8b59e7a" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"><p>Have questions? We have answers! Can’t find what you’re looking for or curious about one of our products? Don’t hesitate to give us a call or use our <a href="#io_contactform">contact form</a> to reach out to us anytime!</p></div></div><div class="elementor-element elementor-element-76bdb6cc elementor-icon-list--layout-inline elementor-mobile-align-start elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list" data-id="76bdb6cc" data-element_type="widget" data-e-type="widget" data-widget_type="icon-list.default"><div class="elementor-widget-container"><ul class="elementor-icon-list-items elementor-inline-items"><li class="elementor-icon-list-item elementor-inline-item"> <a href="tel:%20(732)%20451-6873"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-phone-alt"></i> </span> <span class="elementor-icon-list-text"> (732) 451-6873</span> </a></li><li class="elementor-icon-list-item elementor-inline-item"> <a href="mailto:[email protected]"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-envelope"></i> </span> <span class="elementor-icon-list-text">[email protected]</span> </a></li></ul></div></div><div class="elementor-element elementor-element-4aca896a elementor-icon-list--layout-inline elementor-mobile-align-start elementor-list-item-link-full_width elementor-widget elementor-widget-icon-list" data-id="4aca896a" data-element_type="widget" data-e-type="widget" data-widget_type="icon-list.default"><div class="elementor-widget-container"><ul class="elementor-icon-list-items elementor-inline-items"><li class="elementor-icon-list-item elementor-inline-item"> <span class="elementor-icon-list-icon"> <i aria-hidden="true" class="fas fa-map-marked-alt"></i> </span> <span class="elementor-icon-list-text">Bayville, NJ 08721</span></li></ul></div></div></div></div><div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-20aed77e" data-id="20aed77e" data-element_type="column" data-e-type="column"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-232712f5 elementor-button-align-stretch elementor-widget elementor-widget-form" data-id="232712f5" data-element_type="widget" data-e-type="widget" data-settings="{"step_next_label":"Next","step_previous_label":"Previous","button_width":"100","step_type":"number_text","step_icon_shape":"circle"}" data-widget_type="form.default"><div class="elementor-widget-container"><form class="elementor-form" method="post" id="io_contactusform" name="Request Call Back" aria-label="Request Call Back"> <input type="hidden" name="post_id" value="3442"/> <input type="hidden" name="form_id" value="232712f5"/> <input type="hidden" name="referer_title" value="Good Times Inflatables - Party Rental and Bounce House Rental" /> <input type="hidden" name="queried_id" value="109"/><div class="elementor-form-fields-wrapper elementor-labels-"><div class="elementor-field-type-text elementor-field-group elementor-column elementor-field-group-firstandlastname elementor-col-33"> <label for="form-field-firstandlastname" class="elementor-field-label elementor-screen-only"> Name </label> <input size="1" type="text" name="form_fields[firstandlastname]" id="form-field-firstandlastname" class="elementor-field elementor-size-sm elementor-field-textual" placeholder="Name"></div><div class="elementor-field-type-email elementor-field-group elementor-column elementor-field-group-email elementor-col-33 elementor-field-required"> <label for="form-field-email" class="elementor-field-label elementor-screen-only"> Email </label> <input size="1" type="email" name="form_fields[email]" id="form-field-email" class="elementor-field elementor-size-sm elementor-field-textual" placeholder="Email" required="required"></div><div class="elementor-field-type-tel elementor-field-group elementor-column elementor-field-group-cellphone elementor-col-33"> <label for="form-field-cellphone" class="elementor-field-label elementor-screen-only"> Phone </label> <input size="1" type="tel" name="form_fields[cellphone]" id="form-field-cellphone" class="elementor-field elementor-size-sm elementor-field-textual" placeholder="Phone" pattern="[0-9()#&+*-=.]+" title="Only numbers and phone characters (#, -, *, etc) are accepted."></div><div class="elementor-field-type-textarea elementor-field-group elementor-column elementor-field-group-notes elementor-col-100"> <label for="form-field-notes" class="elementor-field-label elementor-screen-only"> Message </label><textarea class="elementor-field-textual elementor-field elementor-size-sm" name="form_fields[notes]" id="form-field-notes" rows="3" placeholder=""I need help from a human sales rep.""></textarea></div><div class="elementor-field-type-acceptance elementor-field-group elementor-column elementor-field-group-oktotext elementor-col-100"> <label for="form-field-oktotext" class="elementor-field-label elementor-screen-only"> Text notifications okay? </label><div class="elementor-field-subgroup"> <span class="elementor-field-option"> <input type="checkbox" name="form_fields[oktotext]" id="form-field-oktotext" class="elementor-field elementor-size-sm elementor-acceptance-field" checked="checked"> <label for="form-field-oktotext">Text notifications okay?</label> </span></div></div><div class="elementor-field-type-hidden elementor-field-group elementor-column elementor-field-group-oktotext elementor-col-100"> <input size="1" type="hidden" name="form_fields[oktotext]" id="form-field-oktotext" class="elementor-field elementor-size-sm elementor-field-textual" value="1"></div><div class="elementor-field-type-recaptcha_v3 elementor-field-group elementor-column elementor-field-group-field_1a42aac elementor-col-100 recaptcha_v3-bottomright"><div class="elementor-field" id="form-field-field_1a42aac"><div class="elementor-g-recaptcha" data-sitekey="6LcSNw8eAAAAAN1cy4N20ZlzWX4YetiG7zmLXN_f" data-type="v3" data-action="Form" data-badge="bottomright" data-size="invisible"></div></div></div><div class="elementor-field-type-text"> <input size="1" type="text" name="form_fields[website_url]" id="form-field-website_url" class="elementor-field elementor-size-sm " style="display:none !important;"></div><div class="elementor-field-group elementor-column elementor-field-type-submit elementor-col-100 e-form__buttons"> <button class="elementor-button elementor-size-sm elementor-animation-grow" type="submit" id="io_cub"> <span class="elementor-button-content-wrapper"> <span class="elementor-button-icon"> <i aria-hidden="true" class="far fa-paper-plane"></i> </span> <span class="elementor-button-text">Send</span> </span> </button></div></div></form></div></div><div class="elementor-element elementor-element-0f4864b elementor-widget elementor-widget-text-editor" data-id="0f4864b" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"> This site is protected by reCAPTCHA and the Google <a href="https://policies.google.com/privacy">Privacy Policy</a> and <a href="https://policies.google.com/terms">Terms of Service</a> apply.</div></div></div></div></div></section><section class="elementor-section elementor-top-section elementor-element elementor-element-68564b35 elementor-section-full_width elementor-section-height-default elementor-section-height-default" data-id="68564b35" data-element_type="section" data-e-type="section"><div class="elementor-container elementor-column-gap-default"><div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-443383c1" data-id="443383c1" data-element_type="column" data-e-type="column" data-settings="{"background_background":"classic"}"><div class="elementor-widget-wrap elementor-element-populated"><div class="elementor-element elementor-element-8938c3 elementor-widget elementor-widget-text-editor" data-id="8938c3" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default"><div class="elementor-widget-container"><p>Copyright © <span id="io_fbs">Good Times Inflatables </span>All Rights Reserved | Rental Software Powered By <a href="https://www.inflatableoffice.com/" target="_blank" rel="noopener">InflatableOffice</a></p></div></div></div></div></div></section></footer>
63<script type="speculationrules">{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/io-kenos/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}</script>
63 <img src="https://rental.software/include/iotracking.php" style="display:none;" importance="low" alt="dynamic io trk code" /><style>.io_product_price_4h,.io_product_price_8h,.io_product_price_24h,.io_product_price_additionalday{display:none}.io_product_price_24h{display: grid !important} 64 .io_product_cust_price 65 { 66 display: none !important; 67 } 68 #item_live_price_time_set_message 69 { 70 display: none !important; 71 } 72 73 /* ALWAYS hide toggle buttons and list view on inventory/all-items pages (no category ID) */ 74 body.io-no-category-id .io_view_toggle_container, 75 body.io-no-category-id .io_list_view_content 76 { 77 display: none !important; 78 } 79 80 /* Force grid/tile layout on pages without category IDs */ 81 body.io-no-category-id .io_catdiv2.list-view { 82 display: grid !important; 83 grid-template-columns: repeat(auto-fit, minmax(250px, 350px)) !important; 84 grid-gap: 10px !important; 85 margin: 50px !important; 86 max-width: none !important; 87 justify-content: space-evenly !important; 88 } 89 body.io-no-category-id .io_catdiv2.list-view .io_item2_list { 90 display: block !important; 91 flex-direction: column !important; 92 margin-bottom: 0 !important; 93 padding: 0 !important; 94 align-items: initial !important; 95 text-align: center !important; 96 } 97 body.io-no-category-id .io_catdiv2.list-view .cat_div { 98 flex: initial !important; 99 margin-right: 0 !important; 100 position: relative !important; 101 } 102 body.io-no-category-id .io_catdiv2.list-view .cat_img { 103 width: 100% !important; 104 height: auto !important; 105 object-fit: cover !important; 106 } 107 body.io-no-category-id .io_catdiv2.list-view .io_item2_list_inner { 108 flex: initial !important; 109 margin-top: initial !important; 110 display: block !important; 111 flex-direction: initial !important; 112 justify-content: initial !important; 113 min-height: auto !important; 114 height: auto !important; 115 } 116 117 .io_all_item_cat{ 118 display:none; 119 float:none; 120 width:100%; 121 margin-top:20px; 122 }</style>
122<script>var io_wp_local_path = ""; 123 var io_checkavail = "warn"; 124 var io_hidetimes = "off"; 125 var io_user_country = "US"; 126 var io_user_currency = "USD"; 127 var io_default_start_time = "11:00 am"; 128 var io_default_end_time = "5:00 pm"; 129 var io_default_duration = 6.00; 130 var io_force_blank_timepickers = ""; 131 var io_hide_end_time = ""; 132 var io_cart_date_format = "m/d/yy"; 133 var io_cart_message = ""; 134 var io_cart_time_format = "g:i a"; 135 var io_multidayquote = "on"; 136 var io_cartdayselect = "dropdown_options"; 137 var io_cartAllowSameDay = "off"; 138 var io_overnightPickupTime = "10:00 am"; 139 var io_incartupsell = "on"; 140 var io_distancecharge = "on"; 141 var io_deliverymethod = "off"; 142 var io_brand = "IO"; 143 var io_restrict_times = "on"; 144 var io_restrict_time_start = "8:00 am"; 145 var io_restrict_time_end = "7:45 pm"; 146 var io_default_state = "NJ"; 147 var io_hide_zero = "1"; 148 var io_weekEndPrice = ""; 149 var io_weekDayText = ""; 150 var io_weekEndText = ""; 151 var io_weekendDefine = ""; 152 var io_accessory_price = ""; 153 var io_accessory_select = ""; 154 var io_upsell_price = ""; 155 var io_cart_party_planner_email = "on"; 156 var io_cart_party_planner_destination = "https://goodtimesnj.com/plan-a-party/"; 157 var io_hideQuantityAvail = "off"; 158 var io_company_timeslots = []; 159 var io_info_required = ""; 160 var io_always_display_live_price = ""; 161 var io_default_delivery_method = ""; 162 var io_hide_live_prices = 1; 163 var io_info_required_data = []; 164 var io_prices = {"0":"isset","override_groups":[],"1":"io_product_price_24h"}; 165 var io_delivery_prices = {"default":[], "override":[]}; 166 var io_custom_prices = {"default":[], "override":[]}; 167 var io_delivery_methods = {"Drop-Off":{"restricted":[],"id":"83333"}}; 168 var io_customer_geolocation = ""; 169 var io_customer_ip = "114.119.156.9"; 170 var io_delivery_methods_restrict = null; 171 var io_pagename = "Good Times Inflatables"; 172 var io_categoryVariantImages = ""; 173 //var io_seocitylinktext = "Professional delivery to <span class=\"io_city_list\">%%landing_pages%%</span> and surrounding areas. Please submit a quote or contact us to be sure we service your area."; 174 jQuery( document ).ready(function() { 175 176 //force all quote form links to use cart data 177 //removing back to cart shortcode as this needs to only be done if cart is not empty IO-22561 178 /* 179 let headerBookButton = jQuery("a[href$='io_quoteform/']"); 180 headerBookButton.addClass("ioCart_link"); 181 headerBookButton.attr("href", "javascript:;"); 182 */ 183 184 185 let last_cat_name = ""; 186 let ioTrigger = false; 187 jQuery(".io_all_item_cat").each(function() { 188 current_cat_name = jQuery(this).html(); 189 if(last_cat_name !== current_cat_name) { 190 jQuery(this).show(); 191 ioTrigger = true; 192 } 193 last_cat_name = current_cat_name; 194 }); 195 196 // Setup gen page blocks 197 let io_divs = document.querySelectorAll(".io_item2_list, .io_item2_listcat, .io_item2_listrent, .io_all_item_cat"); 198 let io_divscat = document.querySelectorAll(".io_item2_listcat"); 199 let io_divsrent = document.querySelectorAll(".io_item2_listrent"); 200 let io_divcat = document.querySelector(".io_catdiv2"); 201 let io_pcc = document.querySelector(".page-content"); 202 let io_html; 203 204 if (io_divs.length > 0) { 205 for (let i of io_divs) { 206 if(i.parentNode.className.indexOf("io_mm_") === -1){ 207 io_divcat.appendChild(i); 208 } 209 } 210 if(io_divcat!==null) io_divcat.style.display = "grid"; 211 } 212 213 if (ioTrigger) { 214 let pageBlock = document.querySelector(".io_catdiv2"); 215 pageBlock.classList.add("elementor-widget-heading"); 216 let scanRes = pageBlock.querySelectorAll(".io_item2_listrent"); 217 pageBlock.style.display = "block"; 218 pageBlock.style.margin = "auto"; 219 pageBlock.style.textAlign = "center"; 220 pageBlock.style.marginLeft = "5px"; 221 pageBlock.style.marginRight = "5px"; 222 for (let i of scanRes) { 223 i.style.display = "inline-block"; 224 i.style.marginLeft = "5px"; 225 i.style.marginRight = "5px"; 226 } 227 } 228 229 /* fix font color on older sites */ 230 if(jQuery("#cartData").css("background-color")=="rgb(35, 36, 37)"){ 231 jQuery("#cartData").css("color","white"); 232 } 233 });</script>
233<style>.ui-datepicker-trigger{display:none}</style><div id="cartPopover"><div id="ioCartLoadingOverlay" aria-hidden="true"><div class="io-spinner" role="status" aria-live="polite" aria-label="Loading"></div></div><div id="triangle"></div><div id="cartCalendarTimePickerContainer"><div id="cartCalendar"></div><div id="cartTimePicker"><div id="div-overnight"> Days <select style="color:black;" name="whatday" id="whatday" onchange="endDisplay();"><option value="Same Day" selected="selected">Single Day</option><option value="Overnight">Overnight</option><option value="Multi-Day">Multi-Day</option> </select></div> <br><div id="ioCartTimeSelectContainer"><div> <span class="calTimeLabel calTimeLabelStart">Start</span> <i class="fas fa-calendar-check"></i> <input type="text" name="dateStart" class="ioCartDateInput" readonly="readonly" /> <i class="fas fa-clock"></i> <input type="text" name="timeStart" class="timepicker" style="width:75px;" /></div><div> <span class="calTimeLabel calTimeLabelEnd">End</span> <i class="fas fa-calendar-check"></i> <input type="text" name="dateEnd" class="ioCartDateInput" readonly="readonly" /> <i class="fas fa-clock"></i> <input type="text" name="timeEnd" class="timepicker" style="width:75px;" /></div></div> <br><div id="ioDeliveryMethodContainer" style="display:none; text-align: center;"></div> <br><div id="ioAdditonalInformationContainer" style="display:none; text-align: center;"><div class="io_info_modal_data_container" id="io_info_modal_address"> <label for="address" id="io_iml_address_label" style="width:105px"> Street Address </label> <input class="io_modal_input_address" style="margin-left:5px" id="io_im_address" name="address" type="text"></input> <br></div><div class="io_info_modal_data_container" id="io_info_modal_city"> <label for="city" id="io_iml_city_label" style="width:105px"> City </label> <input class="io_modal_input_city" style="margin-left:5px" id="io_im_city" name="city" type="text"></input> <br></div><div class="io_info_modal_data_container" id="io_info_modal_zip"> <label for="zip" id="io_iml_zip_label" style="width:105px"> Zip Code </label> <input class="io_modal_input_zip" id="io_im_zip" style="margin-left:5px" name="zip" type="text"></input></div></div> <br><div class="elementor-widget-button" style="padding:10px;display:inline-block;"> <a onclick="calApply()" href="javascript:;" 234 class="elementor-button-link elementor-button elementor-size-sm elementor-animation-grow" 235 style="text-decoration: none;">Apply</a></div><div class="elementor-widget-button" style="padding:10px;display:inline-block;"> <a onclick="calCancel()" href="javascript:;" 236 class="elementor-button-link elementor-button elementor-size-sm elementor-animation-grow simpleCart_cancel" 237 style="text-decoration: none;">Cancel</a></div></div><div id="cartDateRange" class="ioDateRange" onclick="calSetDateRange(1)" style="display:none;"></div><div class="changeDateLinkWrapper elementor-widget-button"><div id="changeDateLink" onclick="calSetDateRange(1)" class="elementor-button elementor-animation-grow">Change Date</div></div></div><div id="cartPartyBuilderEmailContainer" style="display:none;text-align:center"><p>Provide an email address here to recieve our free party planner!</p> <input type="text" id="cartPartyBuilderEmailInput"><div class="elementor-widget-button" style="display:inline-block;"> <a onclick="io_party_planner_email_submit()" href="javascript:;" class="elementor-button-link elementor-button elementor-size-sm" style="padding: 6px 15px;text-decoration: none;">Go</a></div><div id="cartPartyBuilderEmailWarning" style="display:none">Pleave provide a valid email address.</div> <br><br></div><div id="cartCustomMessage" style="display:none;text-align:center"></div><div id="cartWarning" class="clearfix"></div><div id="deliveryMethodWarning" class="clearfix">Some items are not available for the selected delivery method.</div> <span class="io_locationRedirectLink">You may not be on the correct site. Click here to change location.</span><div id="cartData" class="clearfix"><div class="simpleCart_items"></div></div><div class="cartSubtotalBox"> Subtotal (estimate):<div id="cartSubtotal"></div></div><div class="checkDeliveryCartContainer"><div id="checkDeliveryMessage" class="cartDeliverytotalBox"><a class="cartLink" href="javascript:;" onClick="showAddressEntry(true)">Check Delivery</a></div><div id="deliverSubtotalContainer" class="cartDeliverytotalBox"> Delivery Fee (<span><a class="cartLink" href="javascript:;" onClick="showAddressEntry(true)">Change Address</a></span>):<div id="deliverySubtotal"></div></div></div><div id="cartCheckoutButton" class="clearfix"><div class="elementor-widget-button"> <a href="javascript:cartHide();
237" class="simpleCart_continue elementor-button elementor-size-sm elementor-animation-grow io_button">Continue Shopping</a> <a href="javascript:;" class="simpleCart_checkout elementor-button elementor-size-sm elementor-animation-grow io_button">Checkout</a></div><div id="cart-carousel-container" style="display:none"> <label> Some items you may be interested in: </label> <br><div class="cart-carousel"></div></div><div class="ioLink"><a href="https://www.inflatableoffice.com" target="_blank">powered by io</a></div></div></div>
237<script>/* configurable globals */ 238 var start_default = "11:00 am"; 239 if(io_default_start_time != "") start_default = io_default_start_time; 240 var end_default = "3:00 pm"; 241 if(io_default_end_time != "") end_default = io_default_end_time; 242 243 if(io_user_currency){ 244 var currency = io_user_currency; 245 } else{ 246 var currency = "USD"; 247 } 248 249 if(io_user_country){ 250 var country = io_user_country; 251 } else{ 252 var country = "US"; 253 } 254 255 256 var timeFormat = "g:i a"; 257 if(io_cart_time_format != "") timeFormat = io_cart_time_format; 258 var dateFormat = "m/d/yy"; 259 if(io_cart_date_format != "") dateFormat = io_cart_date_format; 260 261 var restrictTimes = false; 262 if(io_restrict_times === "on") restrictTimes = true; 263 var restrictTimeStart = start_default; 264 if(io_restrict_time_start != "") restrictTimeStart = io_restrict_time_start; 265 var restrictTimeEnd = end_default; 266 if(io_restrict_time_end != "") restrictTimeEnd = io_restrict_time_end; 267 268 269 var multi_day = true; 270 if(io_multidayquote === "off" || io_cartdayselect == "Single Day") multi_day = false; 271 var in_cart_upsell = false; 272 if(io_incartupsell === "on") in_cart_upsell = true; 273 var io_distance_charge = false; 274 if(io_distancecharge === "on") io_distance_charge = true; 275 276 /* other globals */ 277 var pallet_color1 = ""; /* set in onready */ 278 /* track the date start/end of calendar clicking */ 279 var click_count = 0; 280 281 /* for configuring upsell carosel in cart */ 282 var cart_carousel_set = false; 283 284 /* for checking when we remove an item from the cart */ 285 var last_remove = 0; 286 var last_upsell_call = 0; 287 288 /* for buffering cart qty changes checkAvail calls for qty change only */ 289 var last_checkAvail_call = 0; 290 291 /* for cart loading animation */ 292 var io_cart_loading_active = false; 293 var io_cart_loading_count = 0; 294 var io_cart_loading_fallback_timer = null; 295 296 /*var start_default = "11:00"; 297 var end_default = "15:00"; 298 var currency = "EUR"; 299 var timeFormat = "G:i"; 300 var dateFormat = "d/m/yy";*/ 301 302 303 /* For weekday weekend pricing */ 304 var use_weekday_weekend = false; 305 if(io_weekEndPrice == "on") use_weekday_weekend = true; 306 307 /* Accessory and Upsell Prices */ 308 var show_accessory_price = false; 309 if(io_accessory_price == "on") show_accessory_price = true; 310 var show_upsell_price = false; 311 if(io_upsell_price == "on") show_upsell_price = true; 312 313 /* For customer geolocation shortcode */ 314 var storage_key = 'io_customer_location'; 315 316 /*<editor-fold defaultstate="collapsed" desc="On Ready">*/ 317 jQuery(document).ready(function () { 318 pallet_color1 = "var( --e-global-color-accent,green )"; 319 if(pallet_color1=="rgba(0, 0, 0, 0)" || pallet_color1=="rgb(255, 255, 255)") pallet_color1="rgb(25, 147, 35)"; 320 321 /*<editor-fold defaultstate="collapsed" desc="SimpleCart Init">*/ 322 simpleCart({ 323 currency: currency, 324 cartColumns: [{ 325 view: "image", 326 attr: "image", 327 label: "Image" 328 }, 329 { 330 attr: "name", 331 label: "Name" 332 }, 333 { 334 attr: "encoded", 335 label: false 336 }, 337 { 338 attr: "rentalid", 339 label: false 340 }, 341 { 342 attr: "availability", 343 label: false 344 }, 345 { 346 view: "decrement", 347 label: false, 348 text: "<i class='fas far fa-minus-square' style='color:" + pallet_color1 + "'></i>" 349 }, 350 { 351 view: "calculate_area", 352 label: false 353 }, 354 { 355 view:"input", 356 attr:"quantity" 357 358 }, 359 { 360 attr: "qtyincrement", 361 label: false 362 }, 363 { 364 attr: "inputtype", 365 label: false 366 }, 367 { 368 attr: "qtytype", 369 label: false 370 }, 371 { 372 attr: "vendorid", 373 label: false 374 }, 375 { 376 view: "increment", 377 label: false, 378 text: "<i class='fas far fa-plus-square' style='color:" + pallet_color1 + "'></i>" 379 }, 380 { 381 attr: "price", 382 label: "Price", 383 view: 'currency' 384 }, 385 { 386 view: "remove", 387 label: false,
388 text: "<i class='fas fa-trash' style='color:" + pallet_color1 + "'></i>" 389 }, 390 { 391 attr: "total", 392 label: "SubTotal", 393 view: 'currency' 394 }, 395 { 396 attr: "timeslots", 397 label: false 398 }, 399 { 400 attr: "timeslots-orig", 401 label: false 402 }, 403 { 404 attr: "href", 405 label: false 406 }, 407 { 408 attr: "linkqty", 409 label: false 410 }, 411 { 412 attr: "acc_dd_parent_limit", 413 label: false 414 } 415 ], 416 checkout: { 417 type: "SendForm", 418 method: "GET", 419 url: io_wp_local_path+"/io_quoteform/", 420 extra_data: { 421 /* name: decodeURIComponent("Good Times Inflatables".replace(/[+]/gi, " ")), */ 422 clear_rentals: "1", 423 selected_only: "1", 424 wp_checkout: "1", 425 startdate: "", 426 enddate: "", 427 starttime: "", 428 endtime: "", 429 io_custguid: "" 430 } 431 } 432 }); 433 434 simpleCart.bind('update', cart_onUpdate); 435 simpleCart.bind('beforeSave', cart_hideTimepickerWrapper); 436 simpleCart.bind('beforeRemove', cart_beforeRemove); 437 simpleCart.bind('afterRemove', cart_afterRemove); 438 simpleCart.bind('afterQtyChange', cart_afterQtyChange); 439 simpleCart.bind('beforeCheckout', cart_beforeCheckout); 440 simpleCart.bind('afterAdd', cart_afterAdd); 441 simpleCart.bind('beforeAdd', cart_beforeAdd); 442 simpleCart.bind('load', cart_afterLoad) 443 /*</editor-fold>*/ 444 445 /* showAvail(""); */ 446 let io_star_pic = document.querySelector("#io_star_pic"); 447 if (io_star_pic != null) { 448 let io_star_src = io_star_pic.src; 449 if (io_star_src.indexOf("0star") > -1 || io_star_src.indexOf("1star") > -1 || io_star_src.indexOf("2star") > -1 || 450 io_star_src.indexOf("3star") > -1) { 451 io_star_pic.style.display = "none"; 452 } 453 } 454 455 /*<editor-fold desc="Build Thumb Images">*/ 456 /* build multiple thumb images */ 457 458 /*</editor-fold>*/ 459 460 /*<editor-fold desc="Set up Accessories">*/ 461 /* Add Add To Cart Buttons */ 462 let button_add = document.querySelector("#bookNowBtn"); 463 var main_id = 0; 464 if(jQuery(".io_product_container .item_rentalid")){ 465 main_id = jQuery(".io_product_container .item_rentalid").first().text(); 466 } 467 /* if main item is dd but not pkg (linen code) */ 468 if(jQuery(".io_acc_accessorydd").text()==1 && jQuery(".io_acc_ispackage").text()!=1){ 469 /* if order is defined, then reorder here. */ 470 var acc_cls = jQuery('.io_product_accessories') 471 acc_cls.hide(); 472 let pkg = document.querySelector(".io_product_acc_pkg"); 473 if(pkg==undefined){ 474 pkg = document.createElement("div"); 475 pkg.classList.add("io_product_acc_pkg"); 476 pkg.style.textAlign = "center"; 477 acc_cls.after(pkg); 478 } 479 for (let [key, value] of acc_obj_relate) { 480 elem = getAccElem(key,main_id); 481 if(elem){ 482 btn = makeAccBtn(elem,main_id); 483 pkg.append(btn); 484 } 485 486 } 487 let line = document.createElement("div"); 488 line.innerHTML = "<br>"; 489 pkg.append(line.cloneNode(true)); 490 for (let [key, value] of acc_obj_relate) { 491 for (key2 in acc_obj_relate.get(key)) { 492 if(Object.keys(value[key2]).length > 0){ 493 /* 3rd level */ 494 pkg.append(line.cloneNode(true)); 495 for (key3 in acc_obj_relate.get(key)[key2]) { 496 elem = getAccElem(key3,key2); 497 if(elem){ 498 btn = makeAccBtn(elem,key2); 499 btn.style.display = "none"; 500 pkg.append(btn); 501 } 502 } 503 }else{ 504 elem = getAccElem(key2,key); 505 if(elem){ 506 btn = makeAccBtn(elem,key); 507 btn.style.display = "none"; 508 pkg.append(btn); 509 } 510 511 } 512 } 513 } 514 }else { 515 let access_array = document.querySelectorAll(".io_acc_li"); 516 let count = 0; 517 for (let i of access_array) { 518 let path = i.id.replace("io_acc_",""); 519 count++; 520 let newButton = button_add.cloneNode(true); 521 newButton.id = button_add.id + count; 522 newButton.classList.remove("elementor-animation-grow"); 523 newButton.classList.add("elementor-animation-shrink"); 524 525 let path_arr = path.split("_"); 526 let pid = parseInt(path_arr[0]); 527 let this_id = parseInt(path_arr[1]); 528 if(path_arr.length==1) pid=0; 529 530 if(jQuery("#io_acc_accessorydd_"+path).first().text()==1){ 531 /* display different to provide choices in dd */ 532 //main_id = pid; 533 }else{ 534 /* hide accessories inside a pkg when under an accessory choice item until clicked */ 535 if(jQuery("#io_acc_accessorydd_"+main_id+"_"+pid).first().text()==1){ 536 }else{ 537 /* jpa - not finished/tested yet */ 538 /*jQuery("#io_acc_"+path).hide();*/ 539 } 540 /* Fix broken images for accessories. */ 541 let img_box = document.querySelectorAll(".io_acc_li_img_thumb"); 542 let firstImg = true; 543 let lastAcc = ""; 544 for (let i of img_box) { 545 if(lastAcc=="") lastAcc = i.id;
546 if(lastAcc!=i.id){ 547 lastAcc = i.id; 548 firstImg = true; 549 } 550 let io_img_src = i.src; 551 if(io_img_src!==null) io_img_src = io_img_src.toLowerCase(); 552 let io_img_datasrc = i.getAttribute("data-src"); 553 if(io_img_datasrc===null){ 554 io_img_datasrc = ""; 555 }else{ 556 io_img_datasrc = io_img_datasrc.toLowerCase(); 557 } 558 if ((io_img_src.indexOf("io_noimage.png") >= 0 || io_img_datasrc.indexOf("io_noimage.png") >= 0) || (io_img_src.indexOf(".jpg") == -1 && io_img_src.indexOf(".jpe") == -1 && io_img_src.indexOf(".png") == -1 && io_img_src.indexOf(".gif") == -1 && io_img_src.indexOf(".tif") == -1 && io_img_src.indexOf(".webp") == -1)){ 559 i.style.display = "none"; 560 }else if(!firstImg && jQuery("#io_acc_accessorydd_"+main_id+"_"+pid).first().text()!=1){ 561 i.style.display = "none"; 562 } 563 firstImg = false; 564 } 565 if(jQuery("#io_acc_accessorydd_"+main_id+"_"+pid).first().text()==1){ 566 /* Make the accessory category look more mike a label. */ 567 jQuery("#iothumb_"+main_id+"_"+pid).hide(); 568 jQuery("#io_acc_"+main_id+"_"+pid).css("border", "none"); 569 jQuery("#io_acc_"+main_id+"_"+pid).css("width", "100%"); 570 jQuery("#io_acc_"+main_id+"_"+pid).css("margin-bottom", "5vh"); 571 jQuery("#io_acc_"+main_id+"_"+pid).css("box-shadow", "none"); 572 jQuery("#io_acc_shortname_"+pid).css("font-weight", "bold"); 573 jQuery("#io_acc_shortname_"+pid).css("position", "absolute"); 574 /* Make this auto selected to fix an issue where we can not add to cart if this item is 575 a child of another hidden accessory on screen */ 576 jQuery("#io_acc_"+main_id+"_"+pid).prop("selected", true); 577 accessory_cat_text = jQuery("#io_acc_shortname_"+pid).first().text(); 578 /* This is necessary to make sure there are not multiple colons. */ 579 if(!accessory_cat_text.includes(":")){ 580 jQuery("#io_acc_shortname_"+pid).text(accessory_cat_text+":"); 581 } 582 /* Remove Href so we do not open images on click for dd accessories. */ 583 jQuery("[id^=io_acc_imgbig_"+pid+"_]").removeAttr("href"); 584 585 /* Get the accessory limit for this set of acessories, then set up click events. */ 586 /* Unbind is used to prevent cascading calls. */ 587 accLmt = parseInt(jQuery("#io_acc_accessorylimit_"+main_id+"_"+pid).prop("textContent")); 588 jQuery("[id^=io_acc_"+pid+"_]").unbind("click").click({pid: pid, accLmt: accLmt}, accDDClicked); 589 jQuery("[id^=io_acc_"+pid+"_]").css("cursor", "pointer"); 590 /* Set up the slected property of all children accessories. Default to false. */ 591 jQuery("[id^=io_acc_"+pid+"_]").prop("selected", false); 592 /* We need to add a hidden button so we can simulate a click on add_item for the cart. */ 593 let newButton = button_add.cloneNode(true); 594 newButton.id = button_add.id + count; 595 newButton.classList.remove("elementor-animation-grow"); 596 newButton.setAttribute("style", "display: none !important"); 597 i.appendChild(newButton); 598 }else{ 599 let button_wrap = document.createElement("div"); 600 button_wrap.classList.add("elementor-widget-button"); 601 button_wrap.classList.add("io_access_button"); 602 button_wrap.appendChild(newButton); 603 let req = false; 604 if(jQuery("#io_acc_required_"+path).first().text()>0) req = true; 605 if(!req){ 606 i.appendChild(button_wrap); 607 }else{ 608 var textnode = document.createTextNode("Included"); 609 i.appendChild(textnode); 610 } 611 } 612 } 613 } 614 } 615 /*</editor-fold>*/ 616 617 let upsell_array = document.querySelectorAll(".io_upsell_li"); 618 count = 0; 619 for (let i of upsell_array) { 620 count++; 621 let newButton = button_add.cloneNode(true); 622 newButton.id = button_add.id + count; 623 newButton.classList.remove("elementor-animation-grow"); 624 newButton.classList.add("elementor-animation-shrink"); 625 626 let button_wrap = document.createElement("div"); 627 button_wrap.classList.add("elementor-widget-button"); 628 button_wrap.classList.add("io_upsell_button"); 629 button_wrap.appendChild(newButton); 630 i.appendChild(button_wrap); 631 } 632 633 if(io_deliverymethod == "on" && jQuery(".calDeliveryMethodLabel").length==0){ 634 let delivery_method_container = jQuery("#ioDeliveryMethodContainer").first(); 635 delivery_method_container.append('<span class="calDeliveryMethodLabel">Select Delivery Method</span>'); 636 let delivery_method_html = '<select class="ioDeliveryMethods" onchange="deliveryMethodSelected()">'; 637 let delivery_methods = Object.keys(io_delivery_methods) 638 for(const index in delivery_methods){ 639 if(!io_delivery_methods_restrict){ 640 delivery_method_html += '<option value="'+delivery_methods[index]+'">'+delivery_methods[index]+'</option>'; 641 if(index == 0 && !getCookie("io_delivery_method")) setCookie("io_delivery_method", delivery_methods[index], 14); 642 }else if( !io_delivery_methods_restrict.includes( io_delivery_methods[ delivery_methods[index] ]["id"] ) ){ 643 delivery_method_html += '<option value="'+delivery_methods[index]+'">'+delivery_methods[index]+'</option>'; 644 if(index == 0 && !getCookie("io_delivery_method")) setCookie("io_delivery_method", delivery_methods[index], 14); 645 } 646 } 647 delivery_method_container.append(delivery_method_html); 648 delivery_method_container.show(); 649 if(getCookie("io_delivery_method")){ 650 jQuery(".ioDeliveryMethods").val(getCookie("io_delivery_method")); 651 } 652 }else{
653 setCookie("io_delivery_method", "", 14); 654 } 655 656 let allow_same_day = 1; 657 if(io_cartAllowSameDay == "on"){ 658 allow_same_day = 0; 659 } 660 661 /*<editor-fold desc="Cart Calandar and Time Settings Setup">*/ 662 //var fullmonth_array = jQuery.datepicker.regional["en"].monthNames; 663 jQuery("#cartCalendar").datepicker({ 664 changeMonth: true, 665 changeYear: true, 666 //monthNamesShort : fullmonth_array, 667 dateFormat: dateFormat, 668 rangeSelect: true, 669 numberOfMonths: 1, 670 stepMonths: 1, 671 prevText: "<< Previous Months", 672 nextText: "Next Months >>", 673 speed: "fast", 674 showOn: "both", 675 onChangeMonthYear: cal_onChangeMonthYear, 676 onSelect: cal_onSelect, 677 buttonText: "Calendar", 678 minDate: allow_same_day, 679 firstDay: 0 680 }); 681 jQuery(".ui-datepicker-trigger").hide(); 682 if(restrictTimes){ 683 jQuery(".timepicker").timepicker({ 684 startTime: new Date(0, 0, 10, 0, 0, 0), 685 endTime: new Date(0, 0, 0, 20, 0, 0, 0), 686 minTime:restrictTimeStart, 687 maxTime:restrictTimeEnd, 688 /*show24Hours: $show24Hours,*/ 689 timeFormat: timeFormat, 690 separator: ":", 691 className: "elementor-widget-text-editor", 692 step: 15, 693 disableTouchKeyboard: true 694 }).keypress(function(e){ 695 e.preventDefault(); 696 }); 697 } else{ 698 jQuery(".timepicker").timepicker({ 699 startTime: new Date(0, 0, 10, 0, 0, 0), 700 endTime: new Date(0, 0, 0, 20, 0, 0, 0), 701 /*show24Hours: $show24Hours,*/ 702 timeFormat: timeFormat, 703 separator: ":", 704 className: "elementor-widget-text-editor", 705 step: 15, 706 disableTouchKeyboard: true 707 }); 708 } 709 710 /* if we have company wide timeslots, alter time select in cart. Do this only if we are set to single day only */ 711 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){ 712 let time_select_container = jQuery("#ioCartTimeSelectContainer").first(); 713 time_select_container.empty(); 714 let selected_date_html = '<span style="margin-right: 5px !important" class="calTimeLabel">Date</span><i class="fas fa-calendar-check"></i><input style="margin-left: 5px !important" type="text" name="dateStart" class="ioCartDateInput" readonly="readonly" /><input style="display: none !important" type="text" name="dateEnd" class="ioCartDateInput" readonly="readonly" />' 715 time_select_container.append(selected_date_html); 716 time_select_container.append("<br>") 717 time_select_container.append('<span class="calTimeLabel">Select Timeslot</span>'); 718 let timeslot_html = '<select class="ioCartCompanyTimeslots">'; 719 for(i=0; i<io_company_timeslots.length; ++i){ 720 timeslot_html += io_company_timeslots[i]; 721 } 722 timeslot_html += "</select>" 723 time_select_container.append(timeslot_html); 724 725 } 726 727 // Timeslot element on Quote Form 728 const timeslotSelectElement = jQuery(".controls select[name=timeslot]"); 729 730 /* jQuery( ".datepicker" ).datepicker({dateFormat: "m/d/yy",minDate:0}); */ 731 /* jQuery( ".datepicker" ).val(getCookie("checkDate")); */ 732 start_date = getCookie("io_dateStart"); 733 end_date = getCookie("io_dateEnd"); 734 start_time = getCookie("io_timeStart"); 735 end_time = getCookie("io_timeEnd"); 736 jQuery("input[name=dateStart]").val(start_date); 737 jQuery("input[name=dateEnd]").val(end_date); 738 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day" && getCookie("io_company_timeslot_selected")){ 739 jQuery(".ioCartCompanyTimeslots").val(getCookie("company_timeslot_selected")); 740 // Set it on the quote page too. 741 timeslotSelectElement.val(getCookie("io_company_timeslot_selected")); 742 } else{ 743 jQuery("input[name=timeStart]").val(start_time); 744 jQuery("input[name=timeEnd]").val(end_time); 745 } 746 747 timeslotSelectElement.on('change', function() { 748 // IO-31167: Upon timeslot change on Quote Form, 749 // update timeslot cookie value for persistence 750 if(this.value) { 751 setCookie('io_company_timeslot_selected', this.value, 14); 752 } 753 }); 754 755 if (jQuery("input[name=dateEnd]").val() != "") {
756 setCalBackground(); 757 jQuery("#cartSubtotal").html(simpleCart.toCurrency(simpleCart.total())); 758 if(getCookie("io_dateApplied") === "true") calCancel(); 759 else { 760 jQuery("input[name=dateStart]").val(getCookie("io_dateStart")); 761 jQuery("input[name=dateEnd]").val(getCookie("io_dateEnd")); 762 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day" && getCookie("io_company_timeslot_selected")){ 763 jQuery(".ioCartCompanyTimeslots").val(getCookie("io_company_timeslot_selected")); 764 } 765 else if(io_force_blank_timepickers == "on") 766 { 767 setCookie("io_timeStart", "", 14); 768 setCookie("io_timeEnd", "", 14); 769 jQuery('[name=timeStart]').val(""); 770 jQuery('[name=timeEnd]').val(""); 771 } 772 else{ 773 jQuery("input[name=timeStart]").val(getCookie("io_timeStart")); 774 jQuery("input[name=timeEnd]").val(getCookie("io_timeEnd")); 775 } 776 777 jQuery(".changeDateLinkWrapper").hide(); 778 } 779 } 780 /*</editor-fold>*/ 781 782 jQuery("#io-dialog").dialog({ 783 autoOpen: false, 784 resizable: false, 785 modal: true, 786 dialogClass: "noTitleStuff", 787 width: 350, 788 open: function () { 789 jQuery(".ui-widget-overlay").bind("click", function () { 790 jQuery("#io-dialog").dialog("close"); 791 }) 792 } 793 }); 794 795 /* change jquery calendar next/prev buttons to fa arrows w/matching site color */ 796 jQuery("#cartCalendar .ui-datepicker-prev").addClass("fas fa-arrow-left").css("color", pallet_color1); 797 jQuery("#cartCalendar .ui-datepicker-next").addClass("fas fa-arrow-right").css("color", pallet_color1); 798 799 /* hide sections if not set */ 800 if(jQuery(".io_product_circuits_right").first().text()=="0"){jQuery(".io_product_circuits_right,.io_product_circuits_left").hide();} 801 if(jQuery(".io_city_list").html()==""){jQuery(".io_landingpages").hide();} 802 /* using this instead as it will handle custom ones added */ 803 let io_field_valbox = document.querySelector(".io_product_infobox"); 804 if (io_field_valbox != null || io_field_valbox != undefined) { 805 let io_field_valarr = io_field_valbox.querySelectorAll(".io_product_detail_box"); 806 for (let i of io_field_valarr) { 807 let check = i.querySelector("p:nth-child(2)"); 808 if (check != null && check.innerText == "") i.style.display = "none"; 809 } 810 } 811 812 /* Hide description if there is no description */ 813 desc_box = document.querySelector(".io_product_desc") 814 if(desc_box != null && desc_box.innerText.length == 0 && desc_box.innerHTML.length == 0){ 815 desc_detail_box = desc_box.parentElement; 816 desc_detail_box.style.display = "none"; 817 } 818 819 if(document.querySelector(".io_product_reviewbox")!=null){ 820 if (document.querySelector(".io_product_reviewbox").innerText == "") { 821 if(document.querySelector(".io_star_rating")!=null) document.querySelector(".io_star_rating a").style.display = "none"; 822 } 823 } 824 825 let rid = jQuery(".io_product_container .item_rentalid").first().text(); 826 let regex = new RegExp("^io_product_price_.*_" + rid + "$"); 827 for (const price_index in io_prices){ 828 if(regex.test(io_prices[price_index])){ 829 use_weekday_weekend = false; 830 } 831 } 832 833 /* hide end date input. */ 834 if(!multi_day){ 835 /* TODO: Need to wait and see if this is necessary. If so needs to be more involved than this. */ 836 /* jQuery("input[name=dateEnd]").style("visibility", "hidden"); */ 837 } 838 /* Call page avail now so we can display live price if its enabled */ 839 setTimeout(function(){ 840 if(jQuery(".io_acc_accessorydd").text()==1 && jQuery(".io_acc_ispackage").text()!=1){ 841 jQuery("#bookNowBtn").removeClass("item_add").addClass("item_add_off").trigger("classChange"); 842 checkAvailPageOnly(); 843 }else{ 844 checkAvailPageOnly(); 845 } 846 },50); 847 848 /* Adjust picbox for header heights */ 849 setTimeout(adjustPicBoxForHeader,500); 850 851 /* Show buttons for distance charge check if the setting is on. Hide or show map button if applicable*/ 852 if(io_distance_charge){ 853 jQuery(".delivery_charge_check_container").show(); 854 jQuery(".calc_price_with_map_container").hide(); 855 jQuery(".checkDeliveryCartContainer").show(); 856 } else { 857 jQuery(".delivery_charge_check_container").hide(); 858 jQuery(".calc_price_with_map_container").hide(); 859 jQuery(".checkDeliveryCartContainer").hide(); 860 } 861 if(io_brand=="EH"){ 862 jQuery(".delivery_charge_check_container").hide(); 863 jQuery(".eh_additional_description").show(); 864 } 865 if(jQuery(".io_product_infobox .item_inputtype").text() === "Map"){ 866 jQuery(".delivery_charge_check_container").hide(); 867 jQuery(".checkDeliveryCartContainer").hide(); 868 jQuery(".calc_price_with_map_container").show(); 869 } 870 871 /* If we have delivery set in cookie, be sure to show the charge in the cart. */ 872 if(getCookie("io_deliveryFee") && simpleCart.items().length > 0) { 873 setDeliverySubtotal(getCookie("io_deliveryFee")); 874 jQuery("#deliverSubtotalContainer").show(); 875 jQuery("#checkDeliveryMessage").hide(); 876 } else{ 877 jQuery("#deliverSubtotalContainer").hide(); 878 } 879 880 /* moved back here for IO-22561 */ 881 if(simpleCart.items().length > 0){ 882 let headerBookButton = jQuery("a[href$='io_quoteform/']"); 883 headerBookButton.addClass("ioCart_link"); 884 headerBookButton.attr("href", "javascript:;"); 885 } 886 jQuery(".cartInfo").unbind("click").one("click", function(event){ 887 event.stopPropagation(); 888 event.stopImmediatePropagation(); 889 cartShow(); 890 }); 891 jQuery(".ioCart,.ioCart_link").unbind("click").one("click", function(event){ 892 event.stopPropagation(); 893 event.stopImmediatePropagation(); 894 cartShow(); 895 }); 896 897 /* hide if click outside cart */ 898 jQuery(document).mouseup(function(e){ 899 var container = jQuery("#cartPopover"); 900 var cartButton = jQuery(".cartInfo, .ioCart, .ioCart_link"); 901 var addButton = jQuery(".item_add"); 902 var timePicker = jQuery(".ui-timepicker-wrapper"); 903 904 if(jQuery(".cartInfo, .ioCart, .ioCart_link").hasClass("open")){ 905 if(!container.is(e.target) && container.has(e.target).length === 0 && !cartButton.is(e.target) && cartButton.has(e.target).length === 0 && !addButton.is(e.target) && addButton.has(e.target).length === 0 && !timePicker.is(e.target) && timePicker.has(e.target).length === 0 && !jQuery(".address_entry").is(e.target) && jQuery(".address_entry").has(e.target).length === 0){ 906 cartHide(); 907 } 908 } 909 }); 910 911 if(!getCookie("io_state") && io_default_state){
912 setCookie("io_state", io_default_state, 14); 913 } 914 if(country != "US") { 915 jQuery("#io_cd_state").replaceWith('<input id="io_cd_state" style="display: table-cell" name="state" type="text"></input>'); 916 jQuery("#io_cdl_zip_label").text("Postal code"); 917 if(country == "CA"){ 918 jQuery("#io_cdl_state_label").text("Province"); 919 } else if(country == "AU"){ 920 jQuery("#io_cdl_city_label").text("Suburb"); 921 } 922 } else{ 923 jQuery("#io_cd_zip").attr("type", "number"); 924 } 925 /* Set up on change events to stop end timepickers from allowing users to pick times before start time */ 926 setTimeout(restrictEndTimepickers, 500); 927 if(io_hide_end_time == "on" && io_default_duration > 0){ 928 jQuery('[name="timeEnd"]').parent().hide(); 929 // Hide end time stuff on checkout page and in the text. 930 jQuery(".io_event_body_time .control-group:nth-child(2)").hide(); 931 jQuery(".io_event_body_time_display_text").text(jQuery(".io_event_body_time_display_text").text().replace(/\s*→.*/, "")) 932 jQuery('[name="timeStart"]').change(function(){ 933 const regex = /^(\d{1,2}):(\d{2})(?:\s*([AP]M))?$/i; 934 const match = this.value.match(regex); 935 936 let hours = parseInt(match[1], 10); 937 const minutes = parseInt(match[2], 10); 938 const period = match[3] ? match[3].toUpperCase() : null; 939 940 if (period) { 941 if (period === "PM" && hours !== 12) hours += 12; 942 if (period === "AM" && hours === 12) hours = 0; 943 } 944 945 const baseDate = new Date(1970, 0, 1, hours, minutes); 946 const newTime = new Date(baseDate.getTime() + io_default_duration * 3600000); 947 948 if (period) { 949 // 12-hour 950 let newHours = newTime.getHours(); 951 const newMinutes = newTime.getMinutes(); 952 const newPeriod = newHours >= 12 ? "PM" : "AM"; 953 newHours = newHours % 12; 954 if (newHours === 0) newHours = 12; 955 let end_time = `${newHours}:${newMinutes.toString().padStart(2, "0")} ${newPeriod}`; 956 jQuery('[name="timeEnd"]').val(end_time); 957 } else { 958 // 24 hour 959 let end_time = `${newTime.getHours().toString().padStart(2, "0")}:${newTime.getMinutes().toString().padStart(2, "0")}`; 960 jQuery('[name="timeEnd"]').val(end_time); 961 } 962 }); 963 } 964 965 /* If we have a custom message in cart, display it. */ 966 if(io_cart_message){ 967 show_cart_message(); 968 } 969 970 /* code for day select in cart */ 971 if(io_cartdayselect == "dropdown_options" && io_multidayquote === "on"){ 972 saved_whatday = getCookie("io_whatday"); 973 if(saved_whatday) jQuery("#whatday").val(saved_whatday); 974 endDisplay(); 975 setCalBackground(); 976 } else{ 977 jQuery("#div-overnight").hide(); 978 jQuery("#whatday").val(""); 979 } 980 981 checkRestrictedDeliveries() 982 /* If we are using the information gathering tool, we do not want to show this message. */ 983 if( live_pricing_is_on() && io_info_required == "off" ){ 984 if(!event_time_set() && io_always_display_live_price != "on"){ 985 jQuery("#item_live_price_time_set_message").show(); 986 }else{ 987 jQuery("#item_live_price_time_set_message").hide(); 988 } 989 } 990 991 992 /* Check if information gathering header exists. If it does, Remove set even button and add some classes on onclicks */ 993 if(jQuery("#ioInfoHeader").length){ 994 remove_set_event_buttton(); 995 add_classes_and_onClicks(); 996 header_increment_step(); 997 } 998 999 jQuery(".io_acc_li").each(function() { 1000 if(jQuery(this).find(".item_required").first().text() > 0 && jQuery(this).find(".item_accessorydd").first().text() == 1){ 1001 jQuery(jQuery(jQuery(this).parent()).prev()).appendTo(".io_product_requiredDD_accessories"); 1002 jQuery(jQuery(this).parent()).appendTo(".io_product_requiredDD_accessories"); 1003 jQuery(".io_product_requiredDD_accessories").show(); 1004 } 1005 }); 1006 1007 if(jQuery(".io_product_accessories .io_acc_li").length == 0) jQuery(".io_product_accessories").hide(); 1008 1009 /* Hide the cart add button for items with required accessories on category page */ 1010 jQuery(".item_hasRequiredAcc").each(function() { 1011 if (this.innerText == '1') { 1012 let rental_id_element = jQuery(this).parent().find(".item_rentalid")[0]; 1013 let addCartButton = jQuery(".io_item2_list_inner .add_cart_" + rental_id_element.innerText).find('.io_button'); 1014 addCartButton.removeClass("item_add"); 1015 addCartButton.html('<i class="fas fa-arrow-right"></i>'); 1016 1017 let itemHref = jQuery(this).parent().find(".item_href").text(); 1018 addCartButton.attr('href', itemHref); 1019 } 1020 }); 1021 1022 1023 /* If they have same day selection allowed, need to update checkout page datepicker on delay to make sure it works */ 1024 if(io_cartAllowSameDay == "on"){ 1025 setTimeout(allow_same_day_select_on_checkout, 500); 1026 } 1027 1028 if(io_info_required_data && io_info_required == "on"){ 1029 let io_required_data = io_info_required_data; 1030 jQuery("#ioAdditonalInformationContainer").show(); 1031 for (const [data, value] of Object.entries(io_required_data)) { 1032 if(value == 1){ 1033 jQuery("#io_info_modal_"+data).css("display", "inline-flex") 1034 jQuery("#io_im_"+data).val(getCookie(data)); 1035 } 1036 } 1037 show_or_hide_required_info_message() 1038 } 1039 if(jQuery(".bootstrap-timepicker").length == 0) { 1040 if (!/Mobi|Android/i.test(navigator.userAgent)) { 1041 jQuery("#cartPopover").scroll(function () { 1042 jQuery("[name=timeStart]").timepicker("hide"); 1043 jQuery("[name=timeEnd]").timepicker("hide"); 1044 }); 1045 jQuery(window).scroll(function () { 1046 jQuery("#cartPopover [name=timeStart]").timepicker("hide"); 1047 jQuery("#cartPopover [name=timeEnd]").timepicker("hide"); 1048 }); 1049 } 1050 } 1051 1052 if(jQuery(".io_product_infobox .item_inputtype").text() == "Map"){
1053 simpleCart.items().forEach(function (item, index){ 1054 if(item.get("rentalid") === jQuery(".io_product_infobox .item_rentalid").text()){ 1055 if(item.get("quantity") > 1){ 1056 let units; 1057 if(jQuery(".io_product_infobox .item_qtytype").text() == "Area"){ 1058 units = "sq meters" 1059 if(country === "US") units = "sq feet" 1060 }else if(jQuery(".io_product_infobox .item_qtytype").text() == "Perimeter"){ 1061 units = "meters" 1062 if(country === "US") units = "feet" 1063 } 1064 set_price_on_item_page(units, item.get("quantity")); 1065 } 1066 } 1067 }); 1068 } 1069 /* IO-21808 */ 1070 jQuery(".io_product_price_box").each(function() { 1071 let classes = jQuery(this).attr("class"); 1072 jQuery(this).attr("class", classes.replace(":", "_")); 1073 }); 1074 1075 /* Set time instructions (IO-21496) */ 1076 set_cart_time_instructions(); 1077 1078 if(io_accessory_select === "on"){ 1079 if(jQuery(".io_product_acc_pkg").children().length > 0){ 1080 let main_rental_id = jQuery(".item_rentalid").text(); 1081 let sel_div = jQuery("<div class=\"io_product_acc_pkg\" style=\"display:flex; margin-top:10px;\"></div>"); 1082 let sel = jQuery("<select class=\"io_product_acc_pkg\" onchange=\"accOnClick(this)\" />"); 1083 sel.append("<option value=\"\" selected=\"selected\" style=\"display:none\" disabled>Select one..</option>") 1084 jQuery("[id^=io_acc_shortname_"+main_rental_id+"]").each(function(){ 1085 sel.append("<option value="+this.id+">"+this.innerHTML+"</option>") 1086 if(this.id.split("_").length > 4){ 1087 let split_id = this.id.split("_"); 1088 let option_rental_id = split_id[split_id.length - 1]; 1089 let sel2 = jQuery("<select id=\"io_product_acc_pkg_sel_"+option_rental_id+"\" style=\"display:none; margin-left:5px;\" onchange=\"accOnClick(this)\" />"); 1090 sel2.append("<option value=\"\" selected=\"selected\" style=\"display:none\" disabled>Select one..</option>") 1091 jQuery("[id^=io_acc_shortname_"+option_rental_id+"_]").each(function(){ 1092 sel2.append("<option value="+this.id+">"+this.innerHTML+"</option>") 1093 }); 1094 sel_div.append(sel2); 1095 } 1096 }); 1097 sel_div.prepend(sel); 1098 jQuery(".io_product_acc_pkg").replaceWith(sel_div); 1099 } 1100 } 1101 if(io_cart_party_planner_email === "on" && io_cart_party_planner_destination){ 1102 jQuery("#cartPartyBuilderEmailContainer").show() 1103 if(getCookie("io_email")){ 1104 jQuery("#cartPartyBuilderEmailInput").val(getCookie("io_email")); 1105 } 1106 } 1107 1108 if(io_brand == "PW"){ 1109 jQuery(".io_product_price_box").attr("style", "display: none !important;"); 1110 jQuery(".io_product_price_sqfoot").attr("style", "display: grid !important;"); 1111 } 1112 1113 setTimeout(simpleCart.init, 100); 1114 if(io_hide_zero == 1){ 1115 jQuery(".io_product_price_top_left").each(function (){ 1116 if(Number(this.innerText.replace(/[^0-9.-]+/g,"")) == 0){ 1117 jQuery(this).parent().attr('style','display:none !important'); 1118 } 1119 }); 1120 jQuery(".io_product_price_left").each(function (){ 1121 if(Number(this.innerText.replace(/[^0-9.-]+/g,"")) == 0){ 1122 jQuery(this).parent().attr('style','display:none !important'); 1123 } 1124 }); 1125 } 1126 if (io_categoryVariantImages == 'on'){ 1127 jQuery(".io_category_thumbox").show(); 1128 jQuery('.view-product-button').addClass('view-product-button2') 1129 } 1130 let giftcard_value = jQuery(".item_giftcardvalue"); 1131 if(giftcard_value && giftcard_value.text()){ 1132 jQuery(".delivery_charge_check_container").hide(); 1133 } 1134 1135 if (io_customer_geolocation == 'on') initializeGeolocation(); 1136 }); /*end of on-ready*/ 1137 /*</editor-fold>*/ 1138 1139 /*<editor-fold defaultstate="collapsed" desc="Helper Functions">*/ 1140 function phraseUpdateCount(inputElement) 1141 { 1142 //read the text and strip out spaces 1143 const fullText = inputElement.value; 1144 const lettersOnly = fullText.replace(/\s+/g, ""); 1145 const count = lettersOnly.length; 1146 1147 const cookieKey = inputElement.classList[0]; 1148 1149 document.querySelector(".item_quantity").textContent = count; 1150
1151 setCookie(cookieKey, fullText, 45); 1152 } 1153 function io_party_planner_email_submit(){ 1154 let valid_regex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|.(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 1155 let email = jQuery("#cartPartyBuilderEmailInput").val(); 1156 if(email){ 1157 if(email.match(valid_regex)){ 1158 setCookie("io_email", email, 14); 1159 window.open(io_cart_party_planner_destination, '_blank').focus(); 1160 }else{ 1161 jQuery("#cartPartyBuilderEmailWarning").show(); 1162 } 1163 }else{ 1164 jQuery("#cartPartyBuilderEmailWarning").show(); 1165 } 1166 } 1167 1168 function rid_in_batch(rid, batch_ids){ 1169 let result = batch_ids.filter(function(batch){ 1170 if(batch.includes(this)) return true; 1171 }, rid); 1172 return result 1173 } 1174 1175 function set_cart_time_instructions(){ 1176 /* Making it clearer that customers need to set the time in order to see pricing and availability. */ 1177 let instructions_container = jQuery("<p id=\"ioCartTimeInstructions\"></p>"); 1178 let instructions = ""; 1179 1180 if(multi_day){ 1181 instructions += "Select the event date or date range using the calendar"; 1182 }else{ 1183 instructions += "Select the event date using the calendar"; 1184 } 1185 instructions += "."; 1186 instructions_container.text(instructions); 1187 jQuery("#cartCalendar").append(instructions_container); 1188 } 1189 1190 function live_pricing_is_on(){ 1191 /* 1192 Checks to see if live pricing is on. Assumes it is on unless one of the following conditions: 1193 The setting Hide Live Price is off. 1194 The setting Show Weekend/Weekday Pricing is off. 1195 Delivery method pricing is enabled by default. 1196 We are on an item page that uses delivery method pricing. 1197 */ 1198 if(io_hide_live_prices != 1 || io_weekEndPrice != "on" || 1199 io_delivery_prices["default"].length != 0 || jQuery(".io_product_infobox .item_rentalid").innerText in io_delivery_prices["override"] || 1200 io_custom_prices["default"].length != 0 || jQuery(".io_product_infobox .item_rentalid").innerText in io_delivery_prices["override"]){ 1201 return false; 1202 } 1203 return true; 1204 } 1205 1206 function allow_same_day_select_on_checkout(){ 1207 jQuery(".jquery-datepicker").datepicker("option", "minDate", 0); 1208 } 1209 1210 function show_or_hide_required_info_message(){ 1211 if(io_info_required == "on"){ 1212 if(!all_info_provided()){ 1213 jQuery("#io_all_prices").hide(); 1214 jQuery("#item_additonal_info_open_message").show(); 1215 }else{ 1216 jQuery("#io_all_prices").show(); 1217 jQuery("#item_additonal_info_open_message").hide(); 1218 } 1219 } 1220 } 1221 1222 function all_info_provided(){ 1223 /* This is used for when the "Hide all pricing on page until information is provided" setting is on price settings. */ 1224 let all_data_provided = true; 1225 let io_required_data = io_info_required_data; 1226 for (const [data, value] of Object.entries(io_required_data)) { 1227 if(value == 1){ 1228 if(!getCookie(data)){ 1229 all_data_provided = false 1230 } 1231 } 1232 } 1233 1234 if(live_pricing_is_on() && !event_time_set()) { 1235 all_data_provided = false; 1236 } 1237 1238 return all_data_provided; 1239 } 1240 1241 function event_time_set(){ 1242 if(getCookie("io_timeStart") && 1243 getCookie("io_timeEnd") && 1244 getCookie("io_dateStart") && 1245 getCookie("io_dateEnd")){ 1246 return true; 1247 } else{ 1248 return false 1249 } 1250 } 1251 1252 function show_cart_message(){ 1253 message_container = jQuery("#cartCustomMessage"); 1254 message_container.html(io_cart_message); 1255 message_container.show(); 1256 } 1257 1258 function deliveryMethodSelected(){ 1259 setCookie("io_delivery_method", jQuery(".ioDeliveryMethods option:selected").text(), 14); 1260 checkRestrictedDeliveries(); 1261 } 1262 1263 function adjustPicBoxForHeader(){ 1264 /* For some reason its hard to get css with querySelector so we use jQuery to get the picbox. */ 1265 pic_box = jQuery(".io_product_picbox"); 1266 io_header = document.querySelector(".io_header"); 1267 if(pic_box != null && pic_box.css("position") == "sticky"){ 1268 if(io_header != null){ 1269 header_height = io_header.offsetHeight; 1270 pic_box.css("top", (10+header_height).toString()+"px"); 1271 } 1272 else{ 1273 possible_headers = document.querySelectorAll("header,section")
1274 possible_headers.forEach((ele) =>{ 1275 if(ele.style.top == "0px" && (ele.style.position == "fixed" || ele.style.position == "sticky")){ 1276 header = ele; 1277 header_height = header.offsetHeight; 1278 pic_box.css("top", (10+header_height).toString()+"px"); 1279 1280 } 1281 }); 1282 } 1283 } 1284 } 1285 function cart_times_all_set(){ 1286 if(jQuery("#ioCartTimeSelectContainer [name=dateStart]").val() == ""){ 1287 return false; 1288 } 1289 if(io_hidetimes === "off" || io_hidetimes === ""){ 1290 if(jQuery("#ioCartTimeSelectContainer [name=timeStart]").val() == ""){ 1291 return false; 1292 } 1293 if(jQuery("#ioCartTimeSelectContainer [name=timeEnd]").val() == ""){ 1294 return false; 1295 } 1296 } 1297 1298 return true; 1299 } 1300 function checkRestrictedDeliveries(){ 1301 let items = simpleCart.items() 1302 let restrictions_found = false; 1303 for(i in items){ 1304 let rid = items[i].get("rentalid"); 1305 if(typeof jQuery(".ioDeliveryMethods").val() != "undefined"){ 1306 if(io_delivery_methods[jQuery(".ioDeliveryMethods").val()]["restricted"].includes(rid)){ 1307 jQuery("#deliveryMethodWarning").show(); 1308 restrictions_found = true; 1309 } 1310 } 1311 } 1312 if(!restrictions_found){ 1313 jQuery("#deliveryMethodWarning").hide(); 1314 } 1315 } 1316 1317 function display_cart_warning(item){ 1318 let cart_warning_container = jQuery("#cartWarning"); 1319 1320 // Check if an event date if not we should tell them to set it. 1321 event_times = getAvailTimes(); 1322 if(!event_times[0] || !event_times[1]){ 1323 cart_warning_container.text("Please set the date and time for your event above."); 1324 cart_warning_container.show(); 1325 return false; 1326 } 1327 1328 let item_name = item.get("name"); 1329 let item_timeslots = item.get("timeslots"); 1330 let timeslot_name = getTimeslotName(item_timeslots); 1331 1332 let stop_loop = false; 1333 if(item_timeslots){ 1334 if(jQuery(item_timeslots).nodeName == "SELECT"){ 1335 /* NOTE: It should not be possible for timeslots to be empty. 1336 But in the event they somehow are, we should have this here. */ 1337 /* timeslots */ 1338 var timeslot_sel_range = jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val(); 1339 if(typeof timeslot_sel_range != "undefined"){ 1340 var [start_time, end_time] = break_timeslot_sel_range(timeslot_sel_range); 1341 } 1342 }else{ 1343 /* timepickers */ 1344 let [start_timepicker, end_timepicker] = get_cart_timepickers(timeslot_name); 1345 var start_time = start_timepicker.value; 1346 var end_time = end_timepicker.value; 1347 } 1348 if(!start_time || !end_time){ 1349 cart_warning_container.text("Please select a time range for the following item: " + item_name); 1350 cart_warning_container.show() 1351 stop_loop = true; 1352 } 1353 } else{ 1354 cart_warning_container.text("Some items are not available on this date."); 1355 cart_warning_container.show() 1356 } 1357 return stop_loop 1358 } 1359 1360 const io_personal_cookie_keys = ["io_email", "io_phone", "io_address", "io_city", "io_state", "io_zip"]; 1361 1362 function ioHasMarketingConsent(){ 1363 if(typeof cmplz_has_consent !== 'function'){ 1364 return true; 1365 } 1366 return cmplz_has_consent('marketing'); 1367 } 1368 1369 function ioUnwrapStoredValue(raw) { 1370 // Fully peel any {v,e} wrapper layers that may have accumulated when an 1371 // older plugin version re-saved an already-wrapped value (IO-36799). Cart 1372 // values (dates, times, addresses) are never JSON objects, so any layer 1373 // that parses to a {v,...} object is a wrapper to unwrap. Returns 1374 // { value, expired, malformed } describing the innermost stored string. 1375 var value = (raw == null) ? "" : String(raw); 1376 for (var depth = 0; depth < 25; depth++) { 1377 var trimmed = value.trim(); 1378 if (trimmed.charAt(0) !== '{') break; // plain value -> done 1379 var obj; 1380 try { 1381 obj = JSON.parse(trimmed); 1382 } catch (e) { 1383 break; // not parseable -> stop, keep value 1384 } 1385 if (!obj || typeof obj !== 'object' || !('v' in obj)) break; // not our wrapper 1386 if (obj.e && Date.now() > obj.e) { 1387 return { value: "", expired: true, malformed: false }; 1388 } 1389 value = (obj.v != null) ? String(obj.v) : ""; 1390 } 1391 // Only flag as malformed if what remains still looks like our own broken 1392 // {"v":...} wrapper (e.g. truncated) -- never an ordinary value that just 1393 // happens to start with "{", which must be preserved untouched. 1394 var malformed = /^\s*\{\s*"v"\s*:/.test(value); 1395 return { value: value, expired: false, malformed: malformed }; 1396 } 1397 1398 function setCookie(cname, cvalue, exdays) { 1399 if(io_personal_cookie_keys.indexOf(cname) !== -1 && !ioHasMarketingConsent()){ 1400 return; 1401 } 1402 // Store values in localStorage with an io_ prefix for uniqueness and emulate expiration
1403 try { 1404 // Unwrap first so an already-wrapped value can never be re-wrapped and 1405 // compound into nested {v,e} layers (IO-36799). 1406 var clean = ioUnwrapStoredValue(cvalue).value; 1407 var expiresAt = (typeof exdays === 'number' && exdays > 0) 1408 ? Date.now() + (exdays * 24 * 60 * 60 * 1000) 1409 : null; 1410 var payload = JSON.stringify({ v: clean, e: expiresAt }); 1411 window.localStorage.setItem(cname, payload); 1412 } catch (e) { 1413 // Swallow errors to keep behavior similar to cookie writes silently failing 1414 console.log(e); 1415 } 1416 } 1417 1418 function getCookie(cname) { 1419 // Read values from localStorage honoring expiration; return empty string if missing/expired 1420 try { 1421 var raw = window.localStorage.getItem(cname); 1422 if (!raw) return ""; 1423 var result = ioUnwrapStoredValue(raw); 1424 if (result.expired || result.malformed) { 1425 // Drop expired or corrupted entries so they self-heal instead of being 1426 // rendered as raw JSON in the date/time fields (IO-36799). 1427 try { window.localStorage.removeItem(cname); } catch (e) {} 1428 return ""; 1429 } 1430 return result.value; 1431 } catch (e) { 1432 return ""; 1433 } 1434 } 1435 async function fetchAndSetCookie(name) { 1436 var requestInit = { credentials: "include" }; 1437 fetch("https://rental.software/include/get_cookie.php?name=" + name, requestInit).then(function (response) { 1438 return response.json(); 1439 }).then(function (response) { 1440 return handleResponse(name, response); 1441 }); 1442 } 1443 1444 function handleResponse(name, response) { 1445 var currentCookieValue = getCookie(name); 1446 if (!!response.value && currentCookieValue !== response.value) { 1447 setCookie(name, response.value, 14); 1448 } 1449 return response.value; 1450 } 1451 1452 function clearIoPersonalDataForNoConsent(){ 1453 io_personal_cookie_keys.forEach(function(key){ 1454 try { 1455 window.localStorage.removeItem(key); 1456 } catch (e) { 1457 console.log(e); 1458 } 1459 }); 1460 1461 var trackingUrl = (window.location.href.indexOf("localhost") > -1) 1462 ? "http://localhost/io/bugs/include/iotracking.php" 1463 : "https://rental.software/include/iotracking.php"; 1464 var clearImg = new Image(); 1465 clearImg.src = trackingUrl + "?action=remove&nocache=" + Math.random(); 1466 } 1467 1468 document.addEventListener("cmplz_status_change", function (e) { 1469 if (e.detail.category === 'marketing' && e.detail.value === 'deny') { 1470 clearIoPersonalDataForNoConsent(); 1471 } 1472 }); 1473 1474 function break_timeslot_sel_range(timeslot_sel_range){ 1475 /* Takes a time range given by selected timeslot and gets the start and end time removing meridiem.*/ 1476 timeslot_sel_arr = timeslot_sel_range.split(" - "); 1477 var start_time = timeslot_sel_arr[0].replace("am"," am").replace("pm"," pm").replace(" "," "); 1478 var end_time = timeslot_sel_arr[1].replace("am"," am").replace("pm"," pm").replace(" "," "); 1479 1480 return Array(start_time, end_time); 1481 } 1482 function getAvailTimes(){ 1483 /* 1484 Commonly used helper function. Accomplishes two things: 1485 Returns an array containing start_date, start_time, and event duration. 1486 Sets cookies for start and end date, and start and end time. 1487 1488 Uses the inputs available in the cart if they are filled out, so dateStart, dateEnd, timeStart, and timeEnd. 1489 If timeslots are being used in cart it chooses the selected timeslot and breaks it on - and gets the start ane end time from that. 1490 */ 1491 let start_date = jQuery("input[name=dateStart]").val(); 1492 let end_date = jQuery("input[name=dateEnd]").val(); 1493 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){ 1494 let cart_company_timeslot_selected = jQuery(".ioCartCompanyTimeslots option:selected").first().val(); 1495 if(cart_company_timeslot_selected){ 1496 setCookie("io_company_timeslot_selected", cart_company_timeslot_selected, 14); 1497 cart_company_timeslot_selected = cart_company_timeslot_selected.split("-"); 1498 var start_time = cart_company_timeslot_selected[0].trim(); 1499 var end_time = cart_company_timeslot_selected[1].trim(); 1500 } 1501 } else { 1502 var start_time = jQuery("input[name=timeStart]").val(); 1503 var end_time = jQuery("input[name=timeEnd]").val(); 1504 } 1505 1506 if (start_date.length == 0) { 1507 start_date = getCookie("io_dateStart"); 1508 end_date = getCookie("io_dateEnd"); 1509 start_time = getCookie("io_timeStart"); 1510 end_time = getCookie("io_timeEnd"); 1511 } 1512 1513 const has_selected_company_timeslot = io_company_timeslots.length != 0 1514 && io_cartdayselect == "single_day" 1515 && jQuery(".ioCartCompanyTimeslots option:selected").first().val(); 1516 1517 if(io_hidetimes === "on" 1518 && io_force_blank_timepickers != "on" 1519 && !has_selected_company_timeslot) { 1520 start_time = start_default; 1521 end_time = end_default; 1522 jQuery("input[name=timeStart]").val(start_time); 1523 jQuery("input[name=timeEnd]").val(end_time); 1524 } 1525 1526 if(io_force_blank_timepickers != "on") 1527 { 1528 if(start_time.length == 0) 1529 { 1530 start_time = start_default; 1531 } 1532 if(end_time.length == 0) 1533 { 1534 end_time = end_default; 1535 } 1536 } 1537 1538 1539 /* no past dates */ 1540 if(start_date.length != 0 && convertDateStringtoDateObject(start_date, start_time) < new Date()){ 1541 start_date=""; 1542 end_date=""; 1543 } 1544 /* setCookie("checkDate", start_date, 14); */
1545 setCookie("io_dateStart", start_date, 14); 1546 setCookie("io_dateEnd", end_date, 14); 1547 setCookie("io_timeStart", start_time, 14); 1548 setCookie("io_timeEnd", end_time, 14); 1549 /* If we are using the information gathering tool, we do not want to show this message.*/ 1550 if( live_pricing_is_on() && io_info_required == "off" ){ 1551 if(!event_time_set() && io_always_display_live_price != "on"){ 1552 jQuery("#item_live_price_time_set_message").show(); 1553 }else{ 1554 jQuery("#item_live_price_time_set_message").hide(); 1555 } 1556 } 1557 1558 var newDate1 = convertDateStringtoDateObject(start_date, start_time); 1559 var newDate2 = convertDateStringtoDateObject(end_date, end_time); 1560 let time_duration = ((newDate2 - newDate1) / 3600) / 1000; 1561 return [start_date,start_time,time_duration]; 1562 } 1563 1564 function getAllRentalIDsFromCart(){ 1565 let rental_ids = ""; 1566 jQuery("[id^='cartItem_']").each(function(){ 1567 children = this.children 1568 for(let i = 0; i < children.length; ++i){ 1569 if(children[i].className == "item-rentalid") { 1570 rental_ids += children[i].innerText + "|"; 1571 break; 1572 } 1573 } 1574 }); 1575 return rental_ids 1576 } 1577 /*</editor-fold>*/ 1578 1579 /*<editor-fold defaultstate="collapsed" desc="Info Header Functions">*/ 1580 function init_date_timepicker_for_info_header(){ 1581 jQuery(".ioInfoDatepicker").datepicker({ 1582 changeMonth: true, 1583 changeYear: true, 1584 dateFormat: dateFormat, 1585 rangeSelect: true, 1586 numberOfMonths: 1, 1587 stepMonths: 1, 1588 speed: "fast", 1589 showOn: "both", 1590 onChangeMonthYear: cal_onChangeMonthYear, 1591 buttonText: "Calendar", 1592 minDate: 1, 1593 firstDay: 0 1594 }); 1595 jQuery("#ioHeaderDateStart").datepicker("option", { onSelect: function() { 1596 set_info_header_end_date(); 1597 saveInfoHeader(); 1598 // Add more functions if needed 1599 } 1600 }); 1601 1602 if(restrictTimes){ 1603 jQuery(".ioInfoTimepicker").timepicker({ 1604 startTime: new Date(0, 0, 10, 0, 0, 0), 1605 endTime: new Date(0, 0, 0, 20, 0, 0, 0), 1606 minTime:restrictTimeStart, 1607 maxTime:restrictTimeEnd, 1608 /*show24Hours: $show24Hours,*/ 1609 timeFormat: timeFormat, 1610 separator: ":", 1611 className: "elementor-widget-text-editor", 1612 step: 15, 1613 disableTouchKeyboard: true 1614 }); 1615 } else{ 1616 jQuery(".ioInfoTimepicker").timepicker({ 1617 startTime: new Date(0, 0, 10, 0, 0, 0), 1618 endTime: new Date(0, 0, 0, 20, 0, 0, 0), 1619 /*show24Hours: $show24Hours,*/ 1620 timeFormat: timeFormat, 1621 separator: ":", 1622 className: "elementor-widget-text-editor", 1623 step: 15, 1624 disableTouchKeyboard: true 1625 }); 1626 } 1627 setTimeout(setUpTimeRestrictions_infoHeaderTimepickers, 500); 1628 } 1629 1630 function saveInfoHeader(){ 1631 let info_header_start_date = jQuery("[id$=ioHeaderDateStart]"); 1632 let info_header_end_date = jQuery("[id$=ioHeaderDateEnd]"); 1633 let info_header_start_time = jQuery("[id$=ioHeaderTimeStart]"); 1634 let info_header_end_time = jQuery("[id$=ioHeaderTimeEnd]"); 1635 let info_header_address = jQuery("[id$=ioHeaderAddress]"); 1636 let info_header_city = jQuery("[id$=ioHeaderCity]"); 1637 let info_header_state = jQuery("[id$=ioHeaderState]"); 1638 let info_header_zip = jQuery("[id$=ioHeaderZipCode]"); 1639 let info_header_phone = jQuery("[id$=ioHeaderPhone]"); 1640 let info_header_email = jQuery("[id$=ioHeaderEmail]"); 1641 1642 if(info_header_start_time.val()) setCookie("io_timeStart", info_header_start_time.val(), 14); 1643 if(info_header_end_time.val()) setCookie("io_timeEnd", info_header_end_time.val(), 14); 1644 if(info_header_start_date.val()) setCookie("io_dateStart", info_header_start_date.val(), 14); 1645 if(info_header_end_date.val()) setCookie("io_dateEnd", info_header_end_date.val(), 14); 1646 if(info_header_address.val()) setCookie("io_address", info_header_address.val(), 14); 1647 if(info_header_city.val()) setCookie("io_city", info_header_city.val(), 14); 1648 if(info_header_state.val()) setCookie("io_state", info_header_state.val(), 14); 1649 if(info_header_zip.val()) setCookie("io_zip", info_header_zip.val(), 14); 1650 if(info_header_phone.val()) setCookie("io_phone", info_header_phone.val(), 14); 1651 if(info_header_email.val()) setCookie("io_email", info_header_email.val(), 14); 1652 1653 /* Set information in the cart. */ 1654 calCancel(); 1655 1656 header_increment_step(); 1657 1658 /* Stop form from doing anything else for elementor */ 1659 // jpa - still allow, turn off actions in form if wanted. to turn off io lead submission use the plugin settings 1660 //event.preventDefault(); 1661 //event.stopPropagation(); 1662 return true; 1663 } 1664 1665 function set_info_header_values(){ 1666 let info_header_start_date = jQuery("[id$=ioHeaderDateStart]"); 1667 let info_header_end_date = jQuery("[id$=ioHeaderDateEnd]"); 1668 let info_header_start_time = jQuery("[id$=ioHeaderTimeStart]"); 1669 let info_header_end_time = jQuery("[id$=ioHeaderTimeEnd]"); 1670 let info_header_street = jQuery("[id$=ioHeaderAddress]"); 1671 let info_header_city = jQuery("[id$=ioHeaderCity]"); 1672 let info_header_state = jQuery("[id$=ioHeaderState]"); 1673 let info_header_zip = jQuery("[id$=ioHeaderZipCode]"); 1674 let info_header_phone = jQuery("[id$=ioHeaderPhone]"); 1675 let info_header_email = jQuery("[id$=ioHeaderEmail]"); 1676 1677 if(getCookie("io_timeStart")) info_header_start_time.val(getCookie("io_timeStart")); 1678 if(getCookie("io_timeEnd")) info_header_end_time.val(getCookie("io_timeEnd")); 1679 if(getCookie("io_dateStart")) info_header_start_date.val(getCookie("io_dateStart")); 1680 if(getCookie("io_dateEnd")) info_header_end_date.val(getCookie("io_dateEnd")); 1681 if(getCookie("io_address")) info_header_street.val(getCookie("io_address")); 1682 if(getCookie("io_city")) info_header_city.val(getCookie("io_city")); 1683 if(getCookie("io_state")) info_header_state.val(getCookie("io_state")); 1684 if(getCookie("io_zip")) info_header_zip.val(getCookie("io_zip")); 1685 if(getCookie("io_phone")) info_header_phone.val(getCookie("io_phone")); 1686 if(getCookie("io_email")) info_header_email.val(getCookie("io_email")); 1687 } 1688 1689 function add_classes_and_onClicks(){ 1690 1691 /* First set up for dates */ 1692 let info_header_start_date = jQuery("#ioHeaderDateStart"); 1693 let info_header_end_date = jQuery("#ioHeaderDateEnd"); 1694 info_header_start_date.addClass("ioInfoDatepicker"); 1695 info_header_end_date.addClass("ioInfoDatepicker"); 1696 1697 /* Now Timepickers */ 1698 let info_header_start_time = jQuery("#ioHeaderTimeStart"); 1699 let info_header_end_time = jQuery("#ioHeaderTimeEnd"); 1700 info_header_start_time.addClass("ioInfoTimepicker"); 1701 info_header_end_time.addClass("ioInfoTimepicker"); 1702 1703 /* Add the onClick to the button */ 1704 let button = jQuery("#ioInfoHeaderSubmit"); 1705 button.click(saveInfoHeader); 1706 button.css("cursor", "pointer"); 1707 1708 /* Init datepicker and timepickers */ 1709 init_date_timepicker_for_info_header(); 1710 1711 /* Lastly set the values if they are set already */ 1712 set_info_header_values(); 1713 } 1714 1715 function remove_set_event_buttton(){ 1716 let set_event_button = jQuery(".pageDateRangeWrapper"); 1717 if(set_event_button.length > 0) set_event_button.hide(); 1718 } 1719 1720 function set_info_header_end_date(){ 1721 if(!jQuery("#ioHeaderDateEnd").val()){ 1722 jQuery("#ioHeaderDateEnd").val(jQuery("#ioHeaderDateStart").val()) 1723 } 1724 jQuery("#ioHeaderDateEnd").datepicker("option", { minDate: new Date(jQuery("#ioHeaderDateStart").val()) }); 1725 } 1726 1727 function header_increment_step(){ 1728 let active = jQuery(".io-step-active"); 1729 1730 switch(active.attr("id")){ 1731 case "io-step-1": 1732 if (/Mobi|Android/i.test(navigator.userAgent)) { 1733 jQuery("#io-step-2,#io-step-3,#io-step-4").hide(); 1734 } 1735 if(check_header_step_one(active)){ 1736 active.removeClass("io-step-active"); 1737 active.addClass("io-step-done") 1738 jQuery("#io-step-2").addClass("io-step-active") 1739 header_increment_step(); 1740 } 1741 break; 1742 case "io-step-2": 1743 if (/Mobi|Android/i.test(navigator.userAgent)) { 1744 jQuery("#io-step-2,#io-step-3,#io-step-4").show(); 1745 } 1746 if(simpleCart.items().length > 0){ 1747 active.removeClass("io-step-active"); 1748 active.addClass("io-step-done") 1749 jQuery("#io-step-3").addClass("io-step-active") 1750 header_increment_step(); 1751 } 1752 break; 1753 case "io-step-3": 1754 if (/Mobi|Android/i.test(navigator.userAgent)) { 1755 jQuery("#io-step-2,#io-step-3,#io-step-4").show(); 1756 } 1757 if(document.location.href.indexOf("io_quoteconfirm") >= 0){ 1758 active.removeClass("io-step-active"); 1759 active.addClass("io-step-done") 1760 jQuery("#io-step-4").addClass("io-step-active") 1761 header_increment_step(); 1762 } 1763 break; 1764 case "io-step-4": 1765 if (/Mobi|Android/i.test(navigator.userAgent)) { 1766 jQuery("#io-step-2,#io-step-3,#io-step-4").show(); 1767 } 1768 break; 1769 } 1770 } 1771 1772 function check_header_step_one(active) { 1773 var allInputs = active.find('input'); 1774 1775 for (var i = 0; i < allInputs.length; i++) { 1776 if (jQuery(allInputs[i]).val() === "") { 1777 return false; // Return false if any input is empty 1778 } 1779 } 1780 return true; // Return true if all inputs have a value 1781 } 1782 1783 /*</editor-fold>*/ 1784 1785 /*<editor-fold defaultstate="collapsed" desc="Accessory Click Functions">*/ 1786 function accDDClicked(event){ 1787 this_element = jQuery(this) 1788 if(!this_element.prop("selected")){ 1789 pid = event.data.pid 1790 accLmt = event.data.accLmt 1791 all_elements = jQuery("[id^=io_acc_"+pid+"_]") 1792 let count = 0; 1793 /* Tried using .filter and .length to get the count of selected items but could not make it work. */ 1794 for(i = 0; i < all_elements.length; ++i){ 1795 if(all_elements[i].selected){ 1796 ++count; 1797 } 1798 } 1799 if(accLmt == 0){ 1800 this_element.css("border", "5px solid #bbb"); 1801 this_element.prop("selected", true); 1802 } else if(count >= accLmt){ 1803 let selected_value = jQuery("[id^=io_acc_"+pid+"_]").filter(function() { 1804 return this["selected"]; 1805 }); 1806 /* be sure to unselect other slected values if our acc limit has been reached. */ 1807 selected_value.prop("selected", false); 1808 selected_value.css("border", "1px solid #bbb"); 1809 } 1810 this_element.css("border", "5px solid #bbb"); 1811 this_element.prop("selected", true); 1812 } else{ 1813 this_element.prop("selected", false); 1814 this_element.css("border", "1px solid #bbb"); 1815 } 1816 } 1817 1818 /* when accessory choice is clicked */ 1819 function accOnClick(acc_select=null){ 1820 /* set name/img back to original main in case they are just clicking on a 1st level size option */ 1821 jQuery("#bookNowBtn").removeClass("item_add").addClass("item_add_off").trigger("classChange"); 1822 jQuery(".io_product_title.item_name").html(main_name_orig); 1823 jQuery(".io_product_container .item_image").first().attr("src",main_img_src); 1824 jQuery(".io_product_container .item_image").first().attr("data-src",main_img_src); 1825 jQuery(".io_product_container .item_encoded").first().html(main_encoded); 1826 jQuery(".io_product_container .io_image_big").first().attr("src",main_img_src); 1827 jQuery(".io_product_container .io_image_big").first().attr("data-src",main_img_src); 1828 let main_id = jQuery(".io_product_container .item_rentalid").first().text();
1829 let main_id_arr = main_id.split(":") 1830 jQuery(".io_product_container .item_rentalid").html(main_id_arr[0]); 1831 let clk_id; 1832 if(jQuery(acc_select).find(":selected").val()){ 1833 clk_id = jQuery(acc_select).find(":selected").val().replace("io_acc_shortname_",""); 1834 }else{ 1835 clk_id = this.id.replace("io_acc_shortname_",""); 1836 } 1837 clk_id = clk_id.replace("iothumb_",""); 1838 let click_id_arr = clk_id.split("_"); 1839 /* let pid = main_id; */ 1840 /* if(main_id.split("_").length>1) pid = parseInt(click_id_arr[0]); */ 1841 let acc_obj_relate_is_map = acc_obj_relate instanceof Map; 1842 let acc_obj_relate_entries = acc_obj_relate_is_map ? acc_obj_relate.entries() : Object.entries(acc_obj_relate); 1843 for (let [key, value] of acc_obj_relate_entries) { 1844 let id = key; 1845 let children = acc_obj_relate_is_map ? acc_obj_relate.get(key) : value; 1846 if(Object.keys(children).length>0){ 1847 for (key2 in children) { 1848 if(Object.keys(children[key2]).length > 0){ 1849 /* 3rd level */ 1850 for (key3 in children[key2]) { 1851 displayPackageChoices(clk_id,key2,key3,children[key2]); 1852 } 1853 }else{ 1854 displayPackageChoices(clk_id,key,key2,children); 1855 } 1856 } 1857 }else{ 1858 displayPackageChoices(clk_id,0,id,acc_obj_relate); 1859 } 1860 } 1861 } 1862 1863 /* show/hide accessory levels as needed */ 1864 /* clk_id: one they clicked on, pid: parentid, id: iterator, arr: relationship array */ 1865 function displayPackageChoices(clk_id,pid,id,arr){ 1866 let main_id = jQuery(".io_product_container .item_rentalid").first().text(); 1867 let main_arr = main_id.split("_"); 1868 if(main_arr.length>1) main_id = parseInt(main_arr[0]); 1869 let click_id_arr = clk_id.split("_"); 1870 elem = getAccElem(id,pid); 1871 if(click_id_arr[0]==pid || click_id_arr[1]==pid || pid==0){ 1872 elem.style.display="inline-block"; 1873 }else{ 1874 elem.style.display="none"; 1875 } 1876 if(click_id_arr[1]==id && (click_id_arr[0]==pid || (pid==0 && click_id_arr[0]==main_id) ) || (click_id_arr.length==1 && click_id_arr[0]==id)){ 1877 jQuery("#bookNowBtn").removeClass("item_add_off").addClass("item_add").trigger("classChange"); 1878 updateMainItem(id,pid); 1879 } 1880 } 1881 1882 /* update it with accessory data for choices */ 1883 var main_img_src = jQuery("#single_image").first().attr("href"); 1884 var main_name_orig = jQuery(".io_product_title.item_name").html(); 1885 var main_encoded = jQuery(".io_product_container .item_encoded").html(); 1886 var main_desc = jQuery(".io_product_detailbox .io_product_desc").html(); 1887 function updateMainItem(id,pid){ 1888 /* update add to cart btn, name, img, desc */ 1889 let name = ""; 1890 let name_enc = ""; 1891 let main_id = jQuery(".io_product_container .item_rentalid").first().text(); 1892 let main_arr = main_id.split(":"); 1893 if(main_arr.length>1) main_id = main_arr[0]; 1894 if(pid!=0){ 1895 name += jQuery("#io_acc_itemname_"+pid).html()+":"; 1896 name_enc += jQuery("#io_acc_itemname_"+pid).html()+":"; 1897 name += jQuery("#io_acc_shortname_"+id).html(); 1898 name_enc += jQuery("#io_acc_itemname_"+id).html(); 1899 }else{ 1900 pid = main_id; 1901 name += jQuery("#io_acc_itemname_"+id).html(); 1902 name_enc += jQuery("#io_acc_itemname_"+id).html(); 1903 } 1904 jQuery(".io_product_container .item_encoded").html(encodeURIComponent(name_enc.replace(/[\u2032\u2019]+/ig,"'"))); 1905 jQuery(".io_product_container .item_rentalid").html(main_id+":"+pid+"_"+id); 1906 jQuery(".io_product_title.item_name").html(name); 1907 // Make sure the description actually displays text. 1908 let acc_desc = jQuery("#io_acc_desc_"+pid+"_"+id).first(); 1909 if(acc_desc.length>0 && acc_desc.text()){ 1910 jQuery(".io_product_container .io_product_desc").first().html(jQuery("#io_acc_desc_"+pid+"_"+id).first()[0].innerHTML); 1911 } 1912 1913 /* swap accessory image with main image pic for drop-down type items (linens) */ 1914 let img = jQuery("#io_acc_imgbig_"+pid+"_"+id).first().attr("href"); 1915 if(img==null) img = jQuery("#iothumb_"+pid+"_"+id).first().attr("src") 1916 if(img==null){ 1917 }else{ 1918 if(img.length==0 && pid==main_id){ 1919 /* for 1 level dd items that have no img, use the main img */ 1920 img = main_img_src; 1921 } 1922 jQuery(".io_product_container .io_image_big").first().attr("src",img); 1923 jQuery(".io_product_container .io_image_big").first().attr("data-src",
1923img); 1924 jQuery(".io_product_container .item_image").first().attr("src",jQuery("#iothumb_"+pid+"_"+id).first().attr("src")); 1925 jQuery(".io_product_container .item_image").first().attr("data-src",jQuery("#iothumb_"+pid+"_"+id).first().attr("src")); 1926 1927 jQuery("#single_image").first().attr("href",img).show(); 1928 } 1929 checkAvailFilter(); 1930 } 1931 1932 /* get either img or text for accessory choices */ 1933 function getAccElem(id,pid){ 1934 let path =pid+"_"+id; 1935 if(pid==0){ 1936 path=id; 1937 } 1938 let elem = null; 1939 try{ 1940 elem = document.querySelector("#ioAccButtonWrapper_"+path); 1941 }catch(e){} 1942 if(elem == null){ 1943 try{ 1944 elem = document.querySelector("#iothumb_"+path); 1945 }catch(e){} 1946 } 1947 if(elem==null){ 1948 try{ 1949 elem = document.querySelector("#io_product_acc_pkg_sel_"+pid); 1950 }catch(e){} 1951 if(elem!=null) return elem; 1952 }else{ return elem; } 1953 if(elem == null){ 1954 try{ 1955 elem = document.querySelector("#io_acc_shortname_"+path); 1956 }catch(e){} 1957 }else if(elem.src=="" | elem.getAttribute("data-src")==""){ 1958 try{ 1959 elem = document.querySelector("#io_acc_shortname_"+path); 1960 }catch(e){} 1961 }else if(elem.src.substr(-1)=="/"){ 1962 try{ 1963 elem = document.querySelector("#io_acc_shortname_"+path); 1964 }catch(e){} 1965 } 1966 if(elem==null){ 1967 try{ 1968 elem = document.querySelector("#io_acc_shortname_"+id); 1969 }catch(e){} 1970 } 1971 return elem; 1972 } 1973 1974 /* create the accessory choice btn (img/text) */ 1975 function makeAccBtn(button_add,pid){ 1976 let newButton; 1977 if(button_add.nodeName=="IMG"){ 1978 newButton = button_add; 1979 let id = newButton.id.replace("iothumb_"+pid,""); 1980 var wrapper = document.createElement("div"); 1981 wrapper.setAttribute("id", "ioAccButtonWrapper_"+pid+id); 1982 wrapper.style.display = "inline-block"; 1983 wrapper.appendChild(newButton); 1984 let acc_name = document.createElement("span"); 1985 acc_name.style.overflow = "hidden"; 1986 acc_name.style.textOverflow = "ellipsis"; 1987 acc_name.style.maxWidth = "80px"; 1988 acc_name.style.display = "block"; 1989 acc_name.style.whiteSpace = "nowrap"; 1990 acc_name.textContent = jQuery("#io_acc_shortname"+id).text(); 1991 acc_name.classList.add("accTextName"); 1992 acc_name.setAttribute("id", "io_acc_shortname_"+pid+id); 1993 wrapper.appendChild(document.createElement("br")); 1994 wrapper.appendChild(acc_name); 1995 1996 }else{ 1997 newButton = button_add.cloneNode(true); 1998 let id = newButton.id.replace("io_acc_shortname_",""); 1999 newButton.id = "io_acc_shortname_" + pid + "_" + id; 2000 } 2001 newButton.classList.add("elementor-animation-grow"); 2002 newButton.classList.remove("item_image"); 2003 newButton.style="cursor:pointer;border: solid 1px grey"; 2004 newButton.classList.add("io_access_button"); 2005 newButton.style.display = "inline-block"; 2006 newButton.style.verticalAlign = "top"; 2007 newButton.onclick=accOnClick; 2008 if(newButton.nodeName=="IMG"){ 2009 newButton.style.minWidth = "80px"; 2010 newButton.style.width = "80px"; 2011 newButton.style.margin = "2px"; 2012 newButton.style.height = "80px"; 2013 }else{ 2014 newButton.style.margin = "0px 2px 0px 2px"; 2015 } 2016 if(button_add.nodeName=="IMG"){ 2017 return wrapper 2018 } 2019 2020 return newButton; 2021 } 2022 /* when clicking the thumb swatches under main image (2nd image for an item) */ 2023 function updateMainPic(img) { 2024 let container = img.parentElement; 2025 while (container && !container.querySelector(".io_image_big")) { 2026 container = container.parentElement; 2027 } 2028 2029 const main_img = container ? container.querySelector(".io_image_big") : null; 2030 if (!main_img) return; 2031 2032 const dataBigSrc = img.getAttribute("data-big-src"); 2033 if (dataBigSrc) { 2034 main_img.src = dataBigSrc; 2035 return; 2036 } 2037 2038 let thumb_id = img.id; 2039 let big_id = thumb_id.replace("thumb", "big"); 2040 const img_big = document.getElementById(big_id); 2041 2042 if (img_big && img_big.href) { 2043 main_img.src = img_big.href; 2044 } 2045 } 2046 /*</editor-fold>*/ 2047 2048 /*<editor-fold defaultstate="collapsed" desc="Calendar Functions">*/ 2049 function calApply() { 2050 /* reset timeslots if filtering is on */ 2051 filterTimeslotsByDay_itemTimeslots();
2052 simpleCart.update(); 2053 2054 /* Prevent zero-duration selection: disallow identical start and end date/time */ 2055 try 2056 { 2057 var ds = jQuery("input[name=dateStart]").val(); 2058 var de = jQuery("input[name=dateEnd]").val(); 2059 var ts = jQuery("input[name=timeStart]").val(); 2060 var te = jQuery("input[name=timeEnd]").val(); 2061 if(ts && te && ds && de) 2062 { 2063 var s24 = convert12HourTo24Hour(ts); 2064 var e24 = convert12HourTo24Hour(te); 2065 var sObj = buildDateObj(ds.split("/"), s24); 2066 var eObj = buildDateObj(de.split("/"), e24); 2067 if(sObj && eObj && typeof sObj.getTime === 'function' && typeof eObj.getTime === 'function') 2068 { 2069 if(eObj.getTime() === sObj.getTime()) 2070 { 2071 alert("Please choose an end time that's after the start time."); 2072 jQuery("input[name=timeEnd]").val(""); 2073 return false; 2074 } 2075 } 2076 } 2077 }catch(e){} 2078 2079 if(cart_times_all_set()){ 2080 ioCartLoaderActivate(); 2081 setCookie("io_dateApplied", "true", 1) 2082 checkAvailAll(); 2083 // If no availability calls were made, hide loader shortly after 2084 setTimeout(function() 2085 { 2086 if(io_cart_loading_active && io_cart_loading_count === 0) 2087 { 2088 io_cart_loading_active = false; 2089 ioCartShowOverlay(false); 2090 } 2091 }, 300); 2092 calCancel(); 2093 } 2094 2095 2096 let io_required_data = io_info_required_data; 2097 for (const [data, value] of Object.entries(io_required_data)) { 2098 if(value == 1){ 2099 setCookie(data, jQuery("#io_im_"+data).val(), 14); 2100 } 2101 } 2102 2103 /* Check if information gathering header exists. If it does, update the times on there. */ 2104 if(jQuery("#ioInfoHeader").length){ 2105 jQuery("#ioHeaderTimeStart").val(jQuery("[name=timeStart]").val()); 2106 jQuery("#ioHeaderTimeEnd").val(jQuery("[name=timeEnd]").val()); 2107 jQuery("#ioHeaderDateStart").val(jQuery("[name=dateStart]").val()); 2108 jQuery("#ioHeaderDateEnd").val(jQuery("[name=dateEnd]").val()); 2109 header_increment_step(); 2110 } 2111 2112 show_or_hide_required_info_message() 2113 /* if(!cartStayOpen) cartHide(); */ 2114 } 2115 2116 function calCancel() { 2117 click_count = 0; 2118 start_date = getCookie("io_dateStart"); 2119 end_date = getCookie("io_dateEnd"); 2120 start_time = getCookie("io_timeStart"); 2121 end_time = getCookie("io_timeEnd"); 2122 jQuery("input[name=dateStart]").val(start_date); 2123 jQuery("input[name=dateEnd]").val(end_date); 2124 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day" && getCookie("io_company_timeslot_selected")){ 2125 jQuery(".ioCartCompanyTimeslots").val(getCookie("io_company_timeslot_selected")); 2126 } else{ 2127 jQuery("input[name=timeStart]").val(start_time); 2128 jQuery("input[name=timeEnd]").val(end_time); 2129 } 2130 setCalBackground(); 2131 2132 jQuery(".ioDateRange").html(smartFormatDateRange()) 2133 jQuery("#cartCalendar, #cartTimePicker").hide(); 2134 jQuery(".ioDateRange").show(); 2135 jQuery(".changeDateLinkWrapper").show(); 2136 } 2137 2138 /* var cartStayOpen = false; */ 2139 function calSetDateRange(stayOpen) { 2140 /* 2141 if(stayOpen==1){ 2142 cartStayOpen = true; 2143 }else{ 2144 cartStayOpen = false; 2145 } 2146 */ 2147 jQuery(".changeDateLinkWrapper").hide(); 2148 jQuery("#cartCalendar, #cartTimePicker").show(); 2149 jQuery("#cartDateRange").hide(); 2150 } 2151 2152 function smartFormatDateRange() { 2153 let start_date = jQuery("input[name=dateStart]").val(); 2154 let end_date = jQuery("input[name=dateEnd]").val(); 2155 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){ 2156 let cart_company_timeslot_selected = jQuery(".ioCartCompanyTimeslots option:selected").first().val(); 2157 if(cart_company_timeslot_selected){ 2158 setCookie("io_company_timeslot_selected", cart_company_timeslot_selected, 14); 2159 cart_company_timeslot_selected = cart_company_timeslot_selected.split("-"); 2160 var start_time = cart_company_timeslot_selected[0].trim(); 2161 var end_time = cart_company_timeslot_selected[1].trim(); 2162 } 2163 } else { 2164 var start_time = jQuery("input[name=timeStart]").val(); 2165 var end_time = jQuery("input[name=timeEnd]").val(); 2166 } 2167 2168 let text = ""; 2169 text = start_date; 2170 if(io_hidetimes!="on") text += " " + start_time; 2171 2172 if (start_date == end_date) { 2173 if(io_hidetimes!="on"){ 2174 text += " <i class='fas fa-arrow-right' style='padding:5px;'></i> "; 2175 text += end_time; 2176 } 2177 } else { 2178 text += " <i class='fas fa-arrow-right' style='padding:5px;'></i> "; 2179 text += end_date; 2180 if(io_hidetimes!="on") text += " " + end_time; 2181 } 2182 /* text += " <i class='fas fa-pencil-alt' style='margin-left:9px;color:"+pallet_color1+";'></i> "; */ 2183 2184 return text; 2185 } 2186 2187 2188 function resetCalButtons() { 2189 jQuery("#cartCalendar .ui-datepicker-prev").addClass("fas fa-arrow-left").css("color", pallet_color1); 2190 jQuery("#cartCalendar .ui-datepicker-next").addClass("fas fa-arrow-right").
2190css("color", pallet_color1); 2191 } 2192 2193 function cal_onChangeMonthYear(year, month, obj) { 2194 setTimeout(resetCalButtons, 10); 2195 setTimeout(setCalBackground, 10); 2196 } 2197 2198 function cal_onSelect(dateText, obj) { 2199 setTimeout(resetCalButtons, 10); 2200 let whatday_choice = ""; 2201 if(io_cartdayselect === "dropdown_options" && io_multidayquote === "on"){ 2202 let choice_obj = jQuery("#whatday"); 2203 if(choice_obj){ 2204 whatday_choice = choice_obj.val(); 2205 } 2206 } 2207 2208 click_count++; 2209 end_timepicker = jQuery("input[name=timeEnd]"); 2210 let timeStart = jQuery("input[name=timeStart]").val(); 2211 if(io_force_blank_timepickers != "on") 2212 { 2213 if (timeStart == "") { 2214 jQuery("input[name=timeStart]").val(start_default); 2215 jQuery("input[name=timeEnd]").val(end_default); 2216 } 2217 } 2218 2219 if (click_count == 1 || !multi_day || whatday_choice==="Same Day" || whatday_choice==="Overnight") { 2220 jQuery("input[name=dateStart]").val(dateText); 2221 jQuery("input[name=dateEnd]").val(dateText) 2222 end_timepicker.timepicker("option",{"minTime": jQuery("input[name=timeStart]").val()}); 2223 if(EndTimeLessThanStartTime( 2224 jQuery("input[name=timeStart]").val(), 2225 end_timepicker.val(), 2226 jQuery("[name='dateStart']").val(), 2227 jQuery("[name='dateEnd']").val() ) ) { 2228 end_timepicker.val(""); 2229 } 2230 if(io_cartAllowSameDay == "on"){ 2231 restrictStartTimepickerOnSameDaySelect(dateText, jQuery("input[name=timeStart]"), end_timepicker); 2232 } 2233 } else if (click_count == 2) { 2234 jQuery("input[name=dateEnd]").val(dateText); 2235 let start_date_str = jQuery("input[name=dateStart]").val(); 2236 let start_date_obj = convertDateStringtoDateObject(start_date_str); 2237 let end_date_obj = convertDateStringtoDateObject(dateText); 2238 if(end_date_obj < start_date_obj){ 2239 jQuery("input[name=dateStart]").val(dateText); 2240 if(io_cartAllowSameDay == "on"){ 2241 restrictStartTimepickerOnSameDaySelect(dateText, jQuery("input[name=timeStart]"), end_timepicker); 2242 } 2243 } else{ 2244 end_timepicker.timepicker("option",{"minTime": io_restrict_time_start}); 2245 } 2246 click_count = 0; 2247 } else { 2248 click_count = 0; 2249 } 2250 //custom code for suncoast_event 2251 if(io_cartdayselect === "dropdown_options" && io_multidayquote === "on"){ 2252 endDisplay(); 2253 //daysSelect(); 2254 } 2255 filterTimeslotsByDay_companyTimeslots(); 2256 2257 setTimeout(setCalBackground, 10); 2258 } 2259 2260 function endDisplay(){ 2261 //todo: need to figure out if these work and set triggers 2262 // trigger enddisplay after date is selected or possibly when dateEnd changes? 2263 let choice = jQuery("#whatday").val(); 2264 2265 setCookie("io_whatday", choice, 14); 2266 let dateStart = jQuery("[name=dateStart]"); 2267 let timeStart = jQuery("[name=timeStart]"); 2268 let dateEnd = jQuery("[name=dateEnd]"); 2269 let timeEnd = jQuery("[name=timeEnd]"); 2270 if(choice==='Overnight'){ 2271 let startdate = dateStart.val(); 2272 let starttime = io_overnightPickupTime; 2273 let endcalc_date_obj = new Date(buildDateobjectstring(startdate,dateFormat,starttime)); 2274 let duration_hrs = 24; 2275 let end_date_obj = new Date(endcalc_date_obj.getTime()+duration_hrs*60*60*1000); 2276 if(!isNaN(end_date_obj)){ 2277 dateEnd.val(getFormatteddate(end_date_obj)); 2278 timeEnd.val(getFormattedtime(end_date_obj)); 2279 timeEnd.attr('readonly','readonly'); 2280 } 2281 }else if(choice==='Multi-Day'){ 2282 let startdate = dateStart.val(); 2283 let starttime = timeStart.val() || start_default; 2284 let start_date_obj = new Date(buildDateobjectstring(startdate, dateFormat, starttime)); 2285 if(!isNaN(start_date_obj)){ 2286 //dateEnd.val(getFormatteddate(start_date_obj)); 2287 let cal = jQuery("#cartCalendar"); 2288 let origOnSelect = cal.datepicker("option", "onSelect"); 2289 cal.datepicker("option", "onSelect", null); 2290 cal.datepicker("setDate", start_date_obj); 2291 cal.datepicker("option", "onSelect", origOnSelect); 2292 } 2293 timeEnd.removeAttr('readonly'); 2294 if(io_force_blank_timepickers == "on" && !timeEnd.val()){ 2295 timeEnd.val(""); 2296 } else if(!timeEnd.val()){ 2297 timeEnd.val(end_default); 2298 } 2299 }else{ 2300 let startdate = dateStart.val(); 2301 let starttime = timeStart.val() || start_default; 2302 let start_date_obj = new Date(buildDateobjectstring(startdate, dateFormat, starttime)); 2303 if(!isNaN(start_date_obj)){ 2304 dateEnd.val(getFormatteddate(start_date_obj)); 2305 let cal = jQuery("#cartCalendar"); 2306 let origOnSelect = cal.datepicker("option", "onSelect"); 2307 cal.datepicker("option", "onSelect", null); 2308 cal.datepicker("setDate", start_date_obj); 2309 cal.datepicker("option", "onSelect", origOnSelect); 2310 } 2311 timeEnd.removeAttr('readonly'); 2312 if(io_force_blank_timepickers == "on" && !timeEnd.val()){ 2313 timeEnd.val(""); 2314 } else if(!timeEnd.val()){ 2315 timeEnd.val(end_default); 2316 } 2317 click_count = 0; 2318 }
2319 setTimeout(setCalBackground, 10); 2320 } 2321 function setCalBackground() { 2322 let dateStart_string = jQuery("input[name=dateStart]").val(); 2323 let dateEnd_string = jQuery("input[name=dateEnd]").val(); 2324 2325 if (dateFormat == "d/m/yy") { 2326 let dateStartArray = dateStart_string.split("/"); 2327 let dateEndArray = dateEnd_string.split("/"); 2328 var dateStart = new Date(dateStartArray[2], Number(dateStartArray[1])-1, dateStartArray[0]); 2329 var dateEnd = new Date(dateEndArray[2], Number(dateEndArray[1])-1, dateEndArray[0]); 2330 } else { 2331 var dateStart = new Date(dateStart_string); 2332 var dateEnd = new Date(dateEnd_string); 2333 } 2334 2335 2336 let sday = dateStart.getDate(); 2337 let smonth = dateStart.getMonth(); 2338 let syear = dateStart.getFullYear(); 2339 2340 let eday = dateEnd.getDate(); 2341 let emonth = dateEnd.getMonth(); 2342 let eyear = dateEnd.getFullYear(); 2343 2344 /* clear any (in case of cancel) */ 2345 jQuery(".ui-datepicker-calendar [data-handler=selectDay]").css("background-color","initial"); 2346 2347 /* set the selected ones */ 2348 jQuery("#cartCalendar [data-month=" + smonth + "][data-year=" + syear + "], #cartCalendar [data-month=" + 2349 emonth + "][data-year=" + eyear + "]").each(function (i) { 2350 let cday = jQuery(this).find("a").first().text(); 2351 let cmonth = jQuery(this).attr("data-month"); 2352 let cyear = jQuery(this).attr("data-year"); 2353 /* let dateCurrent = new Date(Date.UTC(cyear,cmonth,cday,12)); */ 2354 let dateCurrent = new Date(cyear, cmonth, cday); 2355 if (click_count == 1 && dateEnd_string.length == 0) dateEnd = dateStart; 2356 if (dateCurrent.getTime() == dateStart.getTime() && dateCurrent.getTime() == dateEnd.getTime()) { 2357 jQuery(this).css("border-radius", "6px 6px 6px 6px"); 2358 } else if (dateCurrent.getTime() == dateStart.getTime()) { 2359 jQuery(this).css("border-radius", "6px 0 0 6px"); 2360 } else if (dateCurrent.getTime() == dateEnd.getTime()) { 2361 jQuery(this).css("border-radius", "0 6px 6px 0"); 2362 } 2363 2364 if (dateCurrent >= dateStart && dateCurrent <= dateEnd) { 2365 jQuery(this).css("background-color", pallet_color1); 2366 } 2367 2368 2369 }); 2370 } 2371 /*</editor-fold>*/ 2372 2373 /*<editor-fold defaultstate="collapsed" desc="Timeslot/Timepicker Functions">*/ 2374 /* called from simplecart */ 2375 function timeslotChange(){ 2376 checkAvailCartTimeslots(); 2377 } 2378 function filterTimeslotsByDay_companyTimeslots(){ 2379 var weekday = new Array(); 2380 weekday[0] = "Sunday"; 2381 weekday[1] = "Monday"; 2382 weekday[2] = "Tuesday"; 2383 weekday[3] = "Wednesday"; 2384 weekday[4] = "Thursday"; 2385 weekday[5] = "Friday"; 2386 weekday[6] = "Saturday"; 2387 2388 let times = getAvailTimes(); 2389 let start_date = times[0]; 2390 var newDate1 = convertDateStringtoDateObject(start_date); 2391 let day = weekday[new Date(newDate1).getDay()]; 2392 2393 let selected_option_label = jQuery(".ioCartCompanyTimeslots option:selected").first().text().toLowerCase(); 2394 if(optionHasDay(weekday, selected_option_label)){ 2395 if(selected_option_label.indexOf(day.toLowerCase()) === -1){ 2396 jQuery(".ioCartCompanyTimeslots").val(""); 2397 } 2398 } 2399 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){ 2400 jQuery(".ioCartCompanyTimeslots > option").each(function() { 2401 if(optionHasDay(weekday, this.text.toLowerCase())){ 2402 for(i=0; i<weekday.length; ++i){ 2403 if(day.toLowerCase() == weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) !== -1){ 2404 jQuery(this).show(); 2405 day_missing = false; 2406 } else if(day.toLowerCase() != weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) === -1){ 2407 jQuery(this).hide(); 2408 } 2409 } 2410 } 2411 }); 2412 } 2413 } 2414 2415 function filterTimeslotsByDay_itemTimeslots(){ 2416 var weekday = new Array(); 2417 weekday[0] = "Sunday"; 2418 weekday[1] = "Monday"; 2419 weekday[2] = "Tuesday"; 2420 weekday[3] = "Wednesday"; 2421 weekday[4] = "Thursday"; 2422 weekday[5] = "Friday"; 2423 weekday[6] = "Saturday"; 2424 2425 let times = getAvailTimes(); 2426 let start_date = times[0]; 2427 var newDate1 = convertDateStringtoDateObject(start_date); 2428 let day = weekday[new Date(newDate1).getDay()]; 2429 2430 simpleCart.each(function (item, x) { 2431 var timeslots_html = item.get('timeslots'); 2432 if(typeof timeslots_html != "undefined" && jQuery.parseHTML(timeslots_html)[0].nodeName == "SELECT"){ 2433 if(timeslots_html.length > 0){ 2434 var timeslot_name = getTimeslotName(timeslots_html); 2435 if(typeof item.get("timeslots-orig") == "undefined"){ 2436 var timeslots_obj = jQuery.parseHTML(timeslots_html); 2437 } else{ 2438 var timeslots_obj = jQuery.parseHTML(item.get('timeslots-orig')); 2439 } 2440 jQuery(timeslots_obj).find("option").each(function(){ 2441 if(optionHasDay(weekday, this.text.toLowerCase())){ 2442 for(i=0; i<weekday.length; ++i){ 2443 if(day.toLowerCase() == weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) !== -1){ 2444 /* jQuery(this).show(); */ 2445 } else if(day.toLowerCase() != weekday[i].toLowerCase() && this.text.toLowerCase().indexOf(day.toLowerCase()) === -1){ 2446 jQuery(this).remove(); 2447 } 2448 } 2449 } 2450 }); 2451 if(typeof item.get("timeslots-orig") == "undefined") item.set("timeslots-orig",item.get("timeslots")); 2452 item.set("timeslots",'<select class="simpleCart_timeslots" name="'+timeslot_name+'">'+jQuery(timeslots_obj).html()+'</select>'); 2453 } 2454 } 2455 }); 2456 } 2457 2458 function optionHasDay(weekdays, option_label){ 2459 for(i=0; i<weekdays.length; ++i){ 2460 if(option_label.indexOf(weekdays[i].toLowerCase()) !== -1){ 2461 return true; 2462 } 2463 } 2464 return false;
2465 } 2466 2467 function getTimeslotName(timeslots_html){ 2468 if(typeof timeslots_html=="undefined") return ""; 2469 var timeslot_name_s = timeslots_html.indexOf('name="'); 2470 timeslot_name_s += 6; 2471 var timeslot_name_e = timeslots_html.indexOf('"',timeslot_name_s); 2472 var timeslot_name = timeslots_html.substr(timeslot_name_s,timeslot_name_e-timeslot_name_s); 2473 return timeslot_name; 2474 } 2475 function setTimeslotSelected(item, timeslot_name){ 2476 jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option").not(":selected").removeAttr("selected"); 2477 jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").attr("selected","selected"); 2478 if(jQuery(".item-timeslots [name=\""+timeslot_name+"\"]").length>0){ 2479 item.set("timeslots",jQuery(".item-timeslots [name=\""+timeslot_name+"\"]")[0].outerHTML); 2480 } 2481 2482 /* set on quote page */ 2483 jQuery(".controls [name=\""+timeslot_name+"\"] option").not(":selected").removeAttr("selected"); 2484 jQuery(".controls [name=\""+timeslot_name+"\"] option[value='"+jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val()+"']").attr("selected","selected"); 2485 } 2486 2487 function setTimePicker(item, timepicker_name){ 2488 let [start_timepicker, end_timepicker] = get_cart_timepickers(timepicker_name); 2489 let start_time = start_timepicker.value; 2490 let end_time = end_timepicker.value; 2491 2492 if(!start_time){ 2493 start_timepicker.style.borderColor = "red"; 2494 } else{ 2495 start_timepicker.style.borderColor = ""; 2496 } 2497 if(!end_time){ 2498 end_timepicker.style.borderColor = "red"; 2499 } else{ 2500 end_timepicker.style.borderColor = ""; 2501 } 2502 2503 let start_timepicker_html = start_timepicker.outerHTML; 2504 let end_timepicker_html = end_timepicker.outerHTML; 2505 if(document.querySelectorAll(".item-timeslots [name=\""+timepicker_name+"\"]").length>0){ 2506 start_timepicker_html = addOrReplaceValueInTimepicker(start_timepicker_html, start_time); 2507 end_timepicker_html = addOrReplaceValueInTimepicker(end_timepicker_html, end_time); 2508 item.set("timeslots", '<div name="'+timepicker_name+'"> Start: '+start_timepicker_html+' End: '+end_timepicker_html+'</div>'); 2509 } 2510 /* set on quote page */ 2511 /* For linen type items with timepickers */ 2512 let rental_id = item.get("rentalid"); 2513 let split_on_colon = rental_id.split(":"); 2514 if(split_on_colon.length > 1){ 2515 fix_time_name_for_linen_rid(timepicker_name, split_on_colon, start_time, end_time, rental_id) 2516 }else{ 2517 let quote_page_start_timepicker = document.querySelectorAll(".controls [name=\""+timepicker_name.replace("io_timepicker_", "starttime_")+"\"]")[0]; 2518 let quote_page_end_timepicker = document.querySelectorAll(".controls [name=\""+timepicker_name.replace("io_timepicker_", "endtime_")+"\"]")[0]; 2519 if(quote_page_start_timepicker != null && quote_page_end_timepicker != null){ 2520 quote_page_start_timepicker.value = start_time; 2521 quote_page_end_timepicker.value = end_time; 2522 } 2523 } 2524 } 2525 2526 function fix_time_name_for_linen_rid(time_name, split_rid, start_time, end_time, rental_id){ 2527 for(let x = 0; x < split_rid.length; x++){ 2528 temp_timepicker_name = time_name.replace(rental_id, split_rid[x]); 2529 let quote_page_start_timepicker = document.querySelectorAll(".controls [name=\""+temp_timepicker_name.replace("io_timepicker_", "starttime_")+"\"]")[0]; 2530 let quote_page_end_timepicker = document.querySelectorAll(".controls [name=\""+temp_timepicker_name.replace("io_timepicker_", "endtime_")+"\"]")[0]; 2531 if(quote_page_start_timepicker != null && quote_page_end_timepicker != null){ 2532 quote_page_start_timepicker.value = start_time; 2533 quote_page_end_timepicker.value = end_time; 2534 } 2535 } 2536 } 2537 2538 function addOrReplaceValueInTimepicker(timepicker_html, time_value){ 2539 if(timepicker_html.includes("value=")){ 2540 timepicker_html = [timepicker_html.slice(0, timepicker_html.indexOf("value=")), 'value="'+time_value+'"', timepicker_html.slice(timepicker_html.length-1)].join(""); 2541 }else{ 2542 /* No value defined. Add it at the end of the outer html. */ 2543 let position = timepicker_html.lastIndexOf(">"); 2544 timepicker_html = [timepicker_html.slice(0, position), ' value="'+time_value+'"', timepicker_html.slice(position)].join(""); 2545 } 2546 return timepicker_html 2547 } 2548 2549 function restrictEndTimepickers(){ 2550 setUpTimeRestrictions_cartTimepickers() 2551 setUpTimeRestrictions_timeBasedItems() 2552 } 2553 2554 function setUpTimeRestrictions_timeBasedItems(){ 2555 jQuery("input[name^=start_timeslot_]").change(function() 2556 { 2557 end_timepicker = jQuery("input[name='"+this.name.replace("start", "end")+"']"); 2558 end_timepicker = jQuery(end_timepicker[end_timepicker.length - 1]); 2559 end_timepicker.timepicker("option",{"minTime": jQuery(this).val()}); 2560 if( EndTimeLessThanStartTime( jQuery(this).val(), end_timepicker.val(), "0/0/0", "0/0/0" ) ){ 2561 end_timepicker.val(""); 2562 } 2563 }); 2564 } 2565 2566 function setUpTimeRestrictions_cartTimepickers(){ 2567 jQuery("input[name=timeStart]").change(function() 2568 { 2569 end_timepicker = jQuery("[name='"+this.name.replace("Start", "End")+"']"); 2570 if(jQuery("[name='dateStart']").val() === jQuery("input[name='dateEnd']").val()){ 2571 end_timepicker.timepicker("option",{"minTime": jQuery(this).val()}); 2572 if(EndTimeLessThanStartTime( 2573 jQuery(this).val(), 2574 end_timepicker.val(), 2575 jQuery("[name='dateStart']").val(), 2576 jQuery("[name='dateEnd']").val() ) ) { 2577 end_timepicker.val(""); 2578 } 2579 } 2580 }); 2581 } 2582 2583 function setUpTimeRestrictions_infoHeaderTimepickers(){ 2584 jQuery("#ioHeaderTimeStart").change(function() 2585 { 2586 end_timepicker = jQuery("#ioHeaderTimeEnd"); 2587 if(jQuery("#ioHeaderDateStart").val() === jQuery("#ioHeaderDateEnd").val()){ 2588 end_timepicker.timepicker("option",{"minTime": jQuery(this).val()}); 2589 if(EndTimeLessThanStartTime( 2590 jQuery(this).val(), 2591 end_timepicker.val(), 2592 jQuery("#ioHeaderDateStart").val(), 2593 jQuery("#ioHeaderDateEnd").val() ) ) { 2594 end_timepicker.val(""); 2595 } 2596 } 2597 }); 2598 } 2599 2600 /* 2601 helper function to see if the value from a start timepicker is less than the string value of an end timepicker. 2602 2603 param start_time: string representation of the start time picker. 12hr or 24hr. 2604 param end_time: string representation of the end time picker. 12hr or 24hr. 2605 param start_date: string representation of the start date, seperated by "/". Can be wither d/m/y or m/d/y. Pass "0/0/0" if dates do not matter. 2606 param end_date: string representation of the end date, seperated by "/". Can be wither d/m/y or m/d/y. Pass "0/0/0" if dates do not matter. 2607 2608 */ 2609 function EndTimeLessThanStartTime(start_time, end_time, start_date, end_date){ 2610 if(!start_time || !end_time) return false;
2611 start_time = convert12HourTo24Hour(start_time); 2612 end_time = convert12HourTo24Hour(end_time); 2613 var split_start_date = start_date.split("/"); 2614 var split_end_date = end_date.split("/"); 2615 var startDate = buildDateObj(split_start_date, start_time); 2616 var endDate = buildDateObj(split_end_date, end_time); 2617 if(endDate < startDate){ 2618 return true; 2619 } else { 2620 return false; 2621 } 2622 } 2623 function get_cart_timepickers(timepicker_name){ 2624 let start_timepicker = document.getElementsByName(timepicker_name.replace("io_timepicker_", "start_timeslot_")); 2625 let end_timepicker = document.getElementsByName(timepicker_name.replace("io_timepicker_", "end_timeslot_")); 2626 start_timepicker = start_timepicker[start_timepicker.length-1]; 2627 end_timepicker = end_timepicker[end_timepicker.length-1]; 2628 return Array(start_timepicker, end_timepicker); 2629 } 2630 function restrictStartTimepickerOnSameDaySelect(start_date_str, start_timepicker, end_timepicker){ 2631 let selected_date_obj = convertDateStringtoDateObject(start_date_str); 2632 let current_date_obj = new Date(); 2633 if(current_date_obj.getDate() == selected_date_obj.getDate() && 2634 current_date_obj.getMonth() == selected_date_obj.getMonth() && 2635 current_date_obj.getYear() == selected_date_obj.getYear()){ 2636 let next_hour_time_stamp = current_date_obj.setMinutes(60); 2637 let next_hour_str = getFormattedtime(new Date(next_hour_time_stamp)) 2638 start_timepicker.timepicker("option",{"minTime": next_hour_str}); 2639 2640 /* If the time in the input box is less than the time we just restricted too, then clear time inputs */ 2641 restricted_time_obj = convertDateStringtoDateObject(start_date_str, next_hour_str); 2642 currently_selected_time_obj = convertDateStringtoDateObject(start_date_str, start_timepicker.val()); 2643 if(currently_selected_time_obj < restricted_time_obj){ 2644 start_timepicker.val(next_hour_str); 2645 end_timepicker.val(""); 2646 end_timepicker.timepicker("option",{"minTime": next_hour_str}); 2647 } 2648 }else{ 2649 start_timepicker.timepicker("option",{"minTime": restrictTimeStart}); 2650 } 2651 } 2652 /*</editor-fold>*/ 2653 2654 /*<editor-fold defaultstate="collapsed" desc="Simple Cart Bound Functions">*/ 2655 function cart_onUpdate() { 2656 /* need slight delay so simplecart updates before this runs */ 2657 setTimeout(cart_onUpdate2, 500); 2658 try{ 2659 for(var i=0;i<document.getElementsByClassName("ioCart").length;i++){ 2660 document.getElementsByClassName("ioCart")[i].setAttribute("cnt", simpleCart.items().length); 2661 } 2662 }catch(e){} 2663 } 2664 2665 function cart_onUpdate2() { 2666 jQuery("#cartSubtotal").html(simpleCart.toCurrency(simpleCart.total())); 2667 if(io_checkavail=="off") return; 2668 jQuery("#cartWarning").hide(); 2669 let hasUnavail = false; 2670 gift_cards_only = false; 2671 simpleCart.each(function (item, x) { 2672 let item_id = item.get("id"); 2673 var giftCardValue = item.get("giftcardvalue"); 2674 if (giftCardValue && giftCardValue.trim()) { 2675 gift_cards_only = true; 2676 } 2677 let avail = 0; 2678 let stop_loop = false; 2679 if (item.get("availability") != null) avail = item.get("availability").replace(" available", ""); 2680 let quantity = Number(item.get("quantity")); 2681 if(item.get("inputtype") == "Map"){ 2682 quantity = 1 2683 } 2684 if(typeof item.get("availability") != 'undefined'){ 2685 if (quantity > Number(avail) || avail == "not") { 2686 /* item.set("availability","<span style=color:red>"+item.get("availability")+"</span>"); */ 2687 setTimeout(function () { 2688 jQuery("#cartItem_" + item_id + " .item-availability").css("color", "red") 2689 }, 10); 2690 //jQuery("#cartWarning").show(); 2691 stop_loop = display_cart_warning(item); 2692 hasUnavail = true; 2693 } else { 2694 jQuery("#cartItem_" + item_id + " .item-availability").css("color", "inherit"); 2695 } 2696 }else{ 2697 event_times = getAvailTimes(); 2698 if(!event_times[0] || !event_times[1]){ 2699 jQuery("#cartWarning").text("Please set the date and time for your event above."); 2700 jQuery("#cartWarning").show() 2701 } 2702 } 2703 2704 var timeslots_html = item.get("timeslots"); 2705 if(typeof timeslots_html != "undefined"){ 2706 if(timeslots_html.length > 0){ 2707 var timeslot_name = getTimeslotName(timeslots_html); 2708 if(timeslots_html.indexOf("<select") >= 0){ 2709 setTimeslotSelected(item, timeslot_name); 2710 }else{ 2711 setTimePicker(item, timeslot_name); 2712 } 2713 } 2714 } 2715 if(stop_loop){ 2716 return false;
2717 } 2718 }); 2719 2720 if(gift_cards_only){ 2721 jQuery("#cartCalendarTimePickerContainer").hide(); 2722 }else{ 2723 jQuery("#cartCalendarTimePickerContainer").show(); 2724 } 2725 2726 if(hasUnavail && io_checkavail!="off"){ 2727 jQuery(".simpleCart_checkout").removeClass("simpleCart_checkout").addClass("simpleCart_checkout_off").trigger("classChange").click(cartShow); 2728 }else if(io_checkavail!="off"){ 2729 jQuery(".simpleCart_checkout_off").removeClass("simpleCart_checkout_off").addClass("simpleCart_checkout").trigger("classChange"); 2730 } 2731 2732 add_cart_buttons = document.querySelectorAll("[class*=add_cart_]"); 2733 if(add_cart_buttons){ 2734 for(let i = 0; i < add_cart_buttons.length; ++i){ 2735 add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("fa-cart-arrow-down", "fa-shopping-cart"); 2736 add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("Added to Cart", "Add to Cart"); 2737 add_cart_buttons[i].style.filter = "brightness(100%)"; 2738 simpleCart.each(function (item, x) { 2739 if( add_cart_buttons[i].className.includes( item.get("rentalid") ) ){ 2740 add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("fa-shopping-cart", "fa-cart-arrow-down"); 2741 add_cart_buttons[i].innerHTML = add_cart_buttons[i].innerHTML.replace("Add to Cart", "Added to Cart"); 2742 add_cart_buttons[i].style.filter = "brightness(90%)"; 2743 } 2744 }); 2745 } 2746 } 2747 2748 /* init time-based items */ 2749 if(document.location.href.indexOf("io_quoteform") == -1){ 2750 let today = new Date(); 2751 let io_dd = today.getDate(); 2752 let io_mm = today.getMonth() + 1; 2753 let io_yyyy = today.getFullYear(); 2754 if(restrictTimes){ 2755 jQuery(".item-timeslots .timepicker").each( function() { 2756 if(this.name.includes("end")){ 2757 start_timepicker = jQuery("input[name='"+this.name.replace("end", "start")+"']"); 2758 start_timepicker = jQuery(start_timepicker[start_timepicker.length - 1]); 2759 2760 if (io_force_blank_timepickers == "on") 2761 { 2762 start_timepicker.val(""); 2763 jQuery(this).timepicker({ 2764 startTime: "", 2765 endTime: "", 2766 minTime: restrictTimeStart, 2767 maxTime: restrictTimeEnd, 2768 timeFormat: timeFormat, 2769 separator: ":", 2770 className: "elementor-widget-text-editor", 2771 step: 15, 2772 disableTouchKeyboard: true 2773 }); 2774 } 2775 else 2776 { 2777 // Existing logic if "force blank" is not active 2778 if (start_timepicker.val() != "") { 2779 jQuery(this).timepicker({ 2780 startTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + start_default), 2781 endTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + end_default), 2782 minTime: start_timepicker.val(), 2783 maxTime: restrictTimeEnd, 2784 timeFormat: timeFormat, 2785 separator: ":", 2786 className: "elementor-widget-text-editor", 2787 step: 15, 2788 disableTouchKeyboard: true 2789 }); 2790 } else { 2791 jQuery(this).timepicker({ 2792 startTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + start_default), 2793 endTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + end_default), 2794 minTime: restrictTimeStart, 2795 maxTime: restrictTimeEnd, 2796 timeFormat: timeFormat, 2797 separator: ":", 2798 className: "elementor-widget-text-editor", 2799 step: 15, 2800 disableTouchKeyboard: true 2801 }); 2802 } 2803 } 2804 2805 } 2806 else { 2807 if (io_force_blank_timepickers == "on") 2808 { 2809 start_timepicker.val(""); 2810 jQuery(this).timepicker({ 2811 startTime: "", 2812 endTime: "", 2813 minTime: restrictTimeStart, 2814 maxTime: restrictTimeEnd, 2815 timeFormat: timeFormat, 2816 separator: ":", 2817 className: "elementor-widget-text-editor", 2818 step: 15, 2819 disableTouchKeyboard: true 2820 }); 2821 } 2822 else 2823 { 2824 jQuery(this).timepicker({ 2825 startTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + start_default), 2826 endTime: new Date(io_mm+"/"+io_dd+"/"+io_yyyy + " " + end_default), 2827 minTime:restrictTimeStart, 2828 maxTime:restrictTimeEnd, 2829 timeFormat: timeFormat, 2830 separator: ":", 2831 className: "elementor-widget-text-editor", 2832 step: 15, 2833 disableTouchKeyboard: true 2834 }); 2835 } 2836 } 2837 }); 2838 } else{ 2839 jQuery(".item-timeslots .timepicker").each( function() { 2840 if(this.name.includes("end") != -1){ 2841 start_timepicker = jQuery("input[name='"+this.name.replace("end", "start")+"']"); 2842 start_timepicker = jQuery(start_timepicker[start_timepicker.length - 1]); 2843 if (io_force_blank_timepickers == "on") 2844 { 2845 start_timepicker.val(""); 2846 jQuery(this).timepicker({ 2847 startTime: "", 2848 endTime: "", 2849 minTime: restrictTimeStart, 2850 maxTime: restrictTimeEnd, 2851 timeFormat: timeFormat, 2852 separator: ":", 2853 className: "elementor-widget-text-editor", 2854 step: 15, 2855 disableTouchKeyboard: true 2856 }); 2857 } 2858 else 2859 { 2860 if (start_timepicker.val() != "") { 2861 jQuery(this).timepicker({ 2862 startTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + start_default), 2863 endTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + end_default), 2864 minTime: start_timepicker.val(), 2865 timeFormat: timeFormat, 2866 separator: ":", 2867 className: "elementor-widget-text-editor", 2868 step: 15, 2869 disableTouchKeyboard: true 2870 }); 2871 } else { 2872 jQuery(this).timepicker({ 2873 startTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + start_default), 2874 endTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + end_default), 2875 timeFormat: timeFormat, 2876 separator: ":", 2877 className: "elementor-widget-text-editor", 2878 step: 15, 2879 disableTouchKeyboard: true 2880 }); 2881 } 2882 } 2883 } 2884 else 2885 { 2886 if (io_force_blank_timepickers == "on") 2887 { 2888 start_timepicker.val(""); 2889 jQuery(this).timepicker({ 2890 startTime: "", 2891 endTime: "", 2892 minTime: restrictTimeStart, 2893 maxTime: restrictTimeEnd, 2894 timeFormat: timeFormat, 2895 separator: ":", 2896 className: "elementor-widget-text-editor", 2897 step: 15, 2898 disableTouchKeyboard: true 2899 }); 2900 } 2901 else 2902 { 2903 jQuery(this).timepicker({ 2904 startTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + start_default), 2905 endTime: new Date(io_mm + "/" + io_dd + "/" + io_yyyy + " " + end_default), 2906 timeFormat: timeFormat, 2907 separator: ":", 2908 className: "elementor-widget-text-editor", 2909 step: 15, 2910 disableTouchKeyboard: true 2911 }); 2912 } 2913 } 2914 }); 2915 } 2916 setUpTimeRestrictions_timeBasedItems(); 2917 if(!event_time_set()){ 2918 jQuery(".itemRow .item-total").hide(); 2919 }else{ 2920 jQuery(".itemRow .item-total").show(); 2921 } 2922 } 2923 } 2924 function cart_beforeCheckout(data) { 2925 data.startdate = jQuery("input[name=dateStart]").val(); 2926 data.enddate = jQuery("input[name=dateEnd]").val(); 2927 if(getCookie("guid")){ 2928 data.guid = getCookie("guid"); 2929 }else{ 2930 data.io_custguid = fetchAndSetCookie("guid"); 2931 } 2932 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){ 2933 let cart_company_timeslot_selected = jQuery(".ioCartCompanyTimeslots option:selected").first().val(); 2934 if(cart_company_timeslot_selected){
2935 setCookie("io_company_timeslot_selected", cart_company_timeslot_selected, 14); 2936 cart_company_timeslot_selected = cart_company_timeslot_selected.split("-"); 2937 data.starttime = cart_company_timeslot_selected[0]; 2938 data.endtime = cart_company_timeslot_selected[1]; 2939 } 2940 } else { 2941 data.starttime = jQuery("input[name=timeStart]").val(); 2942 data.endtime = jQuery("input[name=timeEnd]").val(); 2943 } 2944 } 2945 function cart_beforeAdd(item) { 2946 var main_id = jQuery(".io_product_container .item_rentalid").first().text(); 2947 var item_id = item.get("rentalid"); 2948 2949 timeslots = item.get("timeslots"); 2950 if(timeslots){ 2951 if(timeslots.indexOf("<select") !== -1){ 2952 timeslot_name_id_start_pos = timeslots.lastIndexOf('name="timeslot_') + 'name="timeslot_'.length; 2953 timeslot_name_id_end_pos = timeslots.indexOf('"', timeslot_name_id_start_pos); 2954 new_timeslots = [timeslots.slice(0, timeslot_name_id_start_pos), item_id, timeslots.slice(timeslot_name_id_end_pos,timeslots.length)] 2955 new_timeslots = new_timeslots.join("") 2956 item.set("timeslots", new_timeslots); 2957 }else if(timeslots.indexOf("<div name=\"io_timepicker_") !== -1){ 2958 timeslot_name_id_start_pos = timeslots.lastIndexOf('name="io_timepicker_') + 'name="io_timepicker_'.length; 2959 timeslot_name_id_end_pos = timeslots.indexOf('"', timeslot_name_id_start_pos); 2960 new_timeslots = [timeslots.slice(0, timeslot_name_id_start_pos), item_id, timeslots.slice(timeslot_name_id_end_pos,timeslots.length)] 2961 new_timeslots = new_timeslots.join("") 2962 2963 timeslot_name_id_start_pos = new_timeslots.lastIndexOf('name="start_timeslot_') + 'name="start_timeslot_'.length; 2964 timeslot_name_id_end_pos = new_timeslots.indexOf('"', timeslot_name_id_start_pos); 2965 new_timeslots = [new_timeslots.slice(0, timeslot_name_id_start_pos), item_id, new_timeslots.slice(timeslot_name_id_end_pos,new_timeslots.length)] 2966 new_timeslots = new_timeslots.join("") 2967 2968 timeslot_name_id_start_pos = new_timeslots.lastIndexOf('name="end_timeslot_') + 'name="end_timeslot_'.length; 2969 timeslot_name_id_end_pos = new_timeslots.indexOf('"', timeslot_name_id_start_pos); 2970 new_timeslots = [new_timeslots.slice(0, timeslot_name_id_start_pos), item_id, new_timeslots.slice(timeslot_name_id_end_pos,new_timeslots.length)] 2971 new_timeslots = new_timeslots.join("") 2972 2973 item.set("timeslots", new_timeslots); 2974 } 2975 2976 } 2977 /* Here we are checking if we are on an item page and if we are adding the main item. 2978 If this is not true, we do not want to continue. Bail here. */ 2979 if((!main_id || !item_id)){ 2980 return true; 2981 }else if (item_id != main_id){ 2982 /* we are adding an accessory, We want to forcibly add the main item first. */ 2983 /* IO-26864 */ 2984 jQuery("#bookNowBtn").click(); 2985 } 2986 let required_dropdown_values = jQuery(".io_acc_li").filter(function() { 2987 let required_ele = jQuery(this).find(".item_required"); 2988 let required = 0; 2989 if(required_ele[0]){ 2990 required = required_ele[0].outerText; 2991 } 2992 let dropdown_ele = jQuery(this).find(".item_accessorydd"); 2993 let dropdown = 0; 2994 if(dropdown_ele[0]){ 2995 dropdown = dropdown_ele[0].outerText; 2996 } 2997 return (required > 0 && dropdown == 1) 2998 }); 2999 var required_selected = true; 3000 required_dropdown_values.each(function() { 3001 required_value_id = jQuery(this).find(".item_rentalid")[0].outerText; 3002 required_value_id = required_value_id.split("_"); 3003 required_value_id = required_value_id[required_value_id.length-1]; 3004 3005 let selected = jQuery("[id^='io_acc_"+required_value_id+"']").filter(function() { 3006 return this["selected"]; 3007 }); 3008 3009 //IO-22431 - This wasnt catching if [0] was undefined 3010 if(jQuery(this).find(".io_acc_li_name")[0] != undefined){ 3011 required_value_name = jQuery(this).find(".io_acc_li_name")[0].outerText ? jQuery(this).find(".io_acc_li_name")[0].outerText : ""; 3012 } 3013 if(selected.length < jQuery(this).find(".item_required")[0].outerText){ 3014 if(item_id == main_id){ 3015 alert(required_value_name+" is a required field."); 3016 } 3017 required_selected = false;
3018 } 3019 3020 if(!required_selected){ 3021 return false; 3022 } 3023 return true; 3024 }); 3025 if(!required_selected){ 3026 return false; 3027 } 3028 3029 /* IO-14857 */ 3030 if(jQuery(".io_product_measurement_price").length > 0){ 3031 let units; 3032 if(jQuery(".io_product_infobox .item_qtytype").text() == "Area"){ 3033 units = "sq meters" 3034 if(country === "US") units = "sq feet" 3035 }else if(jQuery(".io_product_infobox .item_qtytype").text() == "Perimeter"){ 3036 units = "meters" 3037 if(country === "US") units = "feet" 3038 } 3039 item.set("units", units); 3040 item.set("quantity", jQuery(".io_measure_price_raw_measurement").text()); 3041 } 3042 } 3043 function cart_afterAdd(item) { 3044 /*loading animation*/ 3045 ioCartLoaderActivate(); 3046 setTimeout(function(){ if(io_cart_loading_active && io_cart_loading_count === 0){ io_cart_loading_active=false; ioCartShowOverlay(false);} }, 300); 3047 3048 /* Add required Accessories */ 3049 let required_accs = jQuery("[id^=io_acc_required_]").filter(function() { 3050 return parseInt(this["outerText"]) > 0 && this.parentElement.style['display'] != 'none'; 3051 }); 3052 required_accs.each(function(index) { 3053 simpleCart.parse_html_and_add(this, true); 3054 }); 3055 3056 3057 let selected_values = jQuery("[id^=io_acc_]").filter(function() { 3058 return this["selected"]; 3059 }); 3060 3061 selected_values.each(function() { 3062 let info = {}; 3063 let rid = jQuery(this).find(".item_rentalid")[0].outerText; 3064 let split_rid = rid.split("_"); 3065 if(split_rid.length == 3){ 3066 let parent_rid = split_rid[1]; 3067 let main_item_rid = split_rid[0]; 3068 info["acc_dd_parent_limit"] = jQuery("#io_acc_accessorylimit_"+main_item_rid+"_"+parent_rid)[0].outerText; 3069 }else{ 3070 info["acc_dd_parent_limit"] = "0"; 3071 } 3072 info["name"] = jQuery(this).find(".io_acc_li_name")[0].outerText 3073 info["qtyincrement"] = jQuery(this).find(".item_qtyincrement")[0].outerText 3074 info["quantity"] = jQuery(this).find(".item_required")[0].outerText > 0 ? jQuery(this).find(".item_required")[0].outerText : 1; 3075 info["rentalid"] = jQuery(this).find(".item_rentalid")[0].outerText 3076 info["linkqty"] = jQuery(this).find(".item_linkqty")[0].outerText 3077 info["pagename"] = io_pagename; 3078 if(jQuery(this).find(".io_acc_li_img_thumb")[0]){ 3079 info["image"] = jQuery(this).find(".io_acc_li_img_thumb")[0].src 3080 } 3081 let already_added = simpleCart.items().filter((item) => item.get("rentalid").startsWith(split_rid[0]+"_"+split_rid[1])); 3082 if(jQuery(this).find(".item_accessorydd")[0].outerText != 1 && 3083 (info["acc_dd_parent_limit"] == "0" || already_added.length < info["acc_dd_parent_limit"]) ){ 3084 simpleCart.add(info, true); 3085 } 3086 }); 3087 3088 checkAvailCartOnly(true); 3089 3090 let last_upsell_call_time = Date.now() - last_upsell_call; 3091 if(in_cart_upsell && last_upsell_call_time > 2000){ 3092 let rental_ids = ""; 3093 3094 /* Get the last element in the cart. This is the last item added. */ 3095 last_added = jQuery("[id^='cartItem_']").last(); 3096 if(last_added.length){ 3097 last_added_children = last_added.children(); 3098 for(let i = 0; i < last_added_children.length; ++i){ 3099 if(last_added_children[i].className == "item-rentalid") { 3100 rental_ids += last_added_children[i].innerText + "|"; 3101 } 3102 } 3103 } 3104 3105 if(rental_ids.length>0 && jQuery("#cartPopover").attr("class") == "cartIn"){ 3106 var times = getAvailTimes(); 3107 last_upsell_call = Date.now(); 3108 getUpsellsCall(times[0],times[1],times[2],rental_ids,updateCartUpsell); 3109 } 3110 else{ 3111 jQuery("#cart-carousel-container").hide(); 3112 } 3113 } 3114 3115 if(io_company_timeslots.length != 0 && io_cartdayselect == "single_day"){ 3116 filterTimeslotsByDay_itemTimeslots(); 3117 simpleCart.update(); 3118 } 3119 3120 if (jQuery(".cartInfo.open,.ioCart.open, .ioCart_link.open").length == 0) { 3121 setTimeout(function () { 3122 cartShow(); 3123 }, 100); 3124 } 3125 3126 if(simpleCart.items().length==0){
3127 jQuery(".simpleCart_checkout").hide() 3128 }else{ 3129 jQuery(".simpleCart_checkout").show(); 3130 } 3131 3132 if(simpleCart.items().length > 0){ 3133 let headerBookButton = jQuery("a[href$='io_quoteform/']"); 3134 headerBookButton.addClass("ioCart_link"); 3135 headerBookButton.attr("href", "javascript:;"); 3136 } 3137 3138 checkRestrictedDeliveries() 3139 3140 if(jQuery("#ioInfoHeader").length){ 3141 header_increment_step(); 3142 } 3143 } 3144 function cart_afterQtyChange(){ 3145 let last_checkAvail_call_time = Date.now() - last_checkAvail_call; 3146 if(last_checkAvail_call_time > 2000){ 3147 /*loading animation*/ 3148 ioCartLoaderActivate(); 3149 setTimeout(function(){ if(io_cart_loading_active && io_cart_loading_count === 0){ io_cart_loading_active=false; ioCartShowOverlay(false);} }, 300); 3150 last_checkAvail_call = Date.now(); 3151 checkAvailCart(); 3152 checkAvailCartTimeslots(); 3153 } 3154 } 3155 function cart_hideTimepickerWrapper(){ 3156 jQuery(".ui-timepicker-wrapper").hide(); 3157 } 3158 function cart_beforeRemove() { 3159 last_remove = Date.now(); 3160 } 3161 function cart_afterRemove(removed_item){ 3162 checkAvailCart(); 3163 last_upsell_call_time = Date.now() - last_upsell_call; 3164 if(in_cart_upsell && last_upsell_call_time > 2000){ 3165 rental_ids = getAllRentalIDsFromCart(); 3166 if(rental_ids.length>0 && jQuery("#cartPopover").attr("class") == "cartIn"){ 3167 var times = getAvailTimes(); 3168 last_upsell_call = Date.now(); 3169 getUpsellsCall(times[0],times[1],times[2],rental_ids,updateCartUpsell); 3170 } 3171 else{ 3172 jQuery("#cart-carousel-container").hide(); 3173 } 3174 } 3175 3176 /* IO-24060 */
3177 simpleCart.items().forEach(function (item, index) { 3178 let expression = '^' + removed_item.get('rentalid') + '(?:[_:]\\d+)*'; 3179 if(item.get("rentalid").match(expression)){ 3180 item.remove(); 3181 } 3182 }); 3183 3184 3185 checkAvailCartTimeslots(); 3186 checkRestrictedDeliveries(); 3187 if(simpleCart.items().length==0){ 3188 jQuery(".simpleCart_checkout").hide() 3189 }else{ 3190 jQuery(".simpleCart_checkout").show(); 3191 } 3192 3193 if(jQuery("#ioInfoHeader").length && simpleCart.items().length == 0){ 3194 jQuery("#io-step-3").removeClass("io-step-active"); 3195 jQuery("#io-step-2").addClass("io-step-active"); 3196 jQuery("#io-step-2").removeClass("io-step-done") 3197 } 3198 } 3199 function cart_afterLoad(){ 3200 var items_removed = false; 3201 simpleCart.items().forEach(function(item){ 3202 if(item.get("pagename") != io_pagename){ 3203 item.remove() 3204 items_removed = true; 3205 } 3206 }) 3207 if(items_removed){ 3208 alert("Some items in the cart are from a different location and have been removed."); 3209 } 3210 } 3211 /*</editor-fold>*/ 3212 3213 /*<editor-fold defaultstate="collapsed" desc="Date/Time Object/String Conversion Functions">*/ 3214 function getFormatteddate(date_obj){ 3215 if(dateFormat.substring(0,1)=='d'){ 3216 let month = date_obj.getMonth() + 1; 3217 formatteddate = date_obj.getDate()+'/'+month+'/'+date_obj.getFullYear(); 3218 }else{ 3219 let month = date_obj.getMonth() + 1; 3220 formatteddate = month+'/'+date_obj.getDate()+'/'+date_obj.getFullYear(); 3221 } 3222 return formatteddate; 3223 } 3224 3225 function getFormattedtime(date_obj){ 3226 var hour24 = false;
3227 var ampm = 'am'; 3228 var starttime = jQuery('[name=timeStart]').val(); 3229 if(starttime.length>0 && starttime.indexOf('m')==-1) hour24 = true; 3230 if(hour24){ //24 hour return 3231 return date_obj.getHours()+':'+pad(date_obj.getMinutes(),2); 3232 }else{ //12 hour return 3233 var hour = date_obj.getHours(); 3234 if(hour==12) ampm='pm'; 3235 if(hour==0) hour=12; 3236 if(hour>12){ 3237 hour-=12; 3238 ampm='pm'; 3239 } 3240 return hour+':'+pad(date_obj.getMinutes(),2)+' '+ampm; 3241 } 3242 } 3243 3244 function buildDateobjectstring(date,dateformat,time){ 3245 var ampm = 'am'; 3246 var hour24 = false; 3247 if(typeof date == "undefined") return; 3248 if(typeof dateformat == "undefined") return; 3249 var start_arr = date.split('/'); 3250 if(dateformat.substring(0,1)=='d'){ 3251 date = start_arr[2]+'/'+pad(start_arr[1],2)+'/'+pad(start_arr[0],2); 3252 }else{ 3253 date = start_arr[2]+'/'+pad(start_arr[0],2)+'/'+pad(start_arr[1],2); 3254 } 3255 if(time.length>0 && time.indexOf('m')==-1) hour24 = true; 3256 if(hour24){ 3257 try{ 3258 var time_arr = time.split(':'); 3259 var hour = parseInt(time_arr[0]); 3260 var min = pad(time_arr[1], 2); 3261 time = hour + ':' + min + ':00'; 3262 }catch(err){ 3263 time = ""; 3264 } 3265 }else { 3266 try { 3267 time = time.replace('am', "").replace(' ', ""); 3268 if (time.indexOf('pm') != -1) ampm = 'pm'; 3269 time = time.replace('pm', "").replace(' ', ""); 3270 var time_arr = time.split(':'); 3271 var hour = parseInt(time_arr[0]); 3272 var min = pad(time_arr[1], 2); 3273 if (ampm == 'pm') { 3274 if (hour < 12) hour += 12; 3275 } else if (ampm == 'am' && hour == 12) { 3276 hour -= 12; 3277 } 3278 hour = pad(hour, 2); 3279 time = hour + ':' + min + ':00'; 3280 } catch (err) { 3281 time = ""; 3282 } 3283 } 3284 return date+' '+time; 3285 } 3286 3287 function pad(num, size) { 3288 var s = num+""; 3289 while (s.length < size) s = "0" + s; 3290 return s; 3291 } 3292 function convertDateStringtoDateObject(date_str, time_str=null){ 3293 if(date_str){ 3294 split_date_str = date_str.split("/"); 3295 /* Parse start and end time. */ 3296 if(time_str){ 3297 /* Check and see if we are in 12 hour format, if so convert it to 24 hour format. */ 3298 split_time_str = convert12HourTo24Hour(time_str); 3299 }else{ 3300 /* If we do not have a time, then default to zeros */ 3301 split_time_str = [0, 0]; 3302 } 3303 /* Create date object based off our set date format. */ 3304 date_obj = buildDateObj(split_date_str, split_time_str); 3305 return date_obj; 3306 }else{ 3307 return new Date(); 3308 } 3309 } 3310 3311 function buildDateObj(split_date_str, split_time_str){ 3312 if (dateFormat == "d/m/yy"){ 3313 return new Date(split_date_str[2], (+split_date_str[1] - 1).toString(), split_date_str[0], 3314 split_time_str[0], split_time_str[1]); 3315 }else{ 3316 return new Date(split_date_str[2], (+split_date_str[0] - 1).toString(), split_date_str[1], 3317 split_time_str[0], split_time_str[1]); 3318 } 3319 } 3320 3321 function convert12HourTo24Hour(time_str){ 3322 /* This function returns an array containing hours and minutes of provided string in 24 hour format. */ 3323 /* This is primarily used for creating JS Date objects */ 3324 split_time = time_str.split(":"); 3325 3326 /* We are in 12 hour format if there is an "m" attached to minutes portion. */ 3327 if(split_time[1].toLowerCase().search("m") != -1) { 3328 let separated_minutes = split_time[1].split(" "); 3329 if(separated_minutes.length==1){ 3330 split_time[1] = split_time[1].replace("am"," am"); 3331 split_time[1] = split_time[1].replace("pm"," pm"); 3332 separated_minutes = split_time[1].split(" "); 3333 } 3334 let minutes = separated_minutes[0]; 3335 let modifier = separated_minutes[1]; 3336 split_time[1] = minutes; 3337 3338 /* First assume that if the hours are 12, then its midnight. */ 3339 if(split_time[0] == "12"){ 3340 split_time[0] = "00"; 3341 } 3342 /* Second if there is a "p" in the modifier, then add twelve to the hours. */ 3343 if(typeof modifier != "undefined"){ 3344 if(modifier.toLowerCase().search("p") != -1){ 3345 split_time[0] = (parseInt(split_time[0], 10) + 12); 3346 } 3347 } 3348 } 3349 return split_time; 3350 } 3351 /*</editor-fold>*/ 3352 3353 /*<editor-fold defaultstate="collapsed" desc="Cart Show and Hide">*/ 3354 function cartShow() { 3355 jQuery("#cartPopover").show(); 3356 jQuery("#cartPopover").removeClass("cartOut"); 3357 jQuery("#cartPopover").addClass("cartIn"); 3358 jQuery(".cartInfo,.ioCart,.ioCart_link").addClass("open"); 3359 if (/Mobi|Android/i.test(navigator.userAgent)) { 3360 document.body.style.overflow = "hidden"; 3361 } 3362 /* jQuery(this).one("click", cartHide); */ 3363 jQuery(".cartInfo").unbind("click").one("click", function(event){ 3364 event.stopPropagation(); 3365 event.stopImmediatePropagation(); 3366 cartHide(); 3367 }); 3368 jQuery(".ioCart, .ioCart_link").unbind("click").one("click", function(event){ 3369 event.stopPropagation(); 3370 event.stopImmediatePropagation(); 3371 cartHide(); 3372 }); 3373 jQuery(".cartIcon").removeClass("fa-shopping-cart").addClass("fa-close"); 3374 if(simpleCart.items().length==0){
3375 jQuery(".simpleCart_checkout").hide() 3376 }else{ 3377 jQuery(".simpleCart_checkout").show(); 3378 } 3379 3380 checkAvailCartOnly(); 3381 3382 last_upsell_call_time = Date.now() - last_upsell_call; 3383 if(in_cart_upsell && last_upsell_call_time > 2000){ 3384 rental_ids = getAllRentalIDsFromCart(); 3385 if(rental_ids.length>0 && jQuery("#cartPopover").attr("class") == "cartIn"){ 3386 var times = getAvailTimes(); 3387 last_upsell_call = Date.now(); 3388 getUpsellsCall(times[0],times[1],times[2],rental_ids,updateCartUpsell); 3389 } 3390 else{ 3391 jQuery("#cart-carousel-container").hide(); 3392 } 3393 } 3394 } 3395 3396 function cartHide() { 3397 jQuery("#cartPopover").removeClass("cartIn"); 3398 jQuery("#cartPopover").addClass("cartOut"); 3399 if (/Mobi|Android/i.test(navigator.userAgent)) { 3400 document.body.style.overflow = "auto"; 3401 } 3402 /* jQuery("#cartPopover").hide(); */ 3403 jQuery(".cartInfo,.ioCart, .ioCart_link").removeClass("open"); 3404 /* jQuery(this).one("click", cartShow); */ 3405 jQuery(".cartInfo").unbind("click").one("click", function(event){ 3406 event.stopPropagation(); 3407 event.stopImmediatePropagation(); 3408 cartShow(); 3409 }); 3410 jQuery(".ioCart, .ioCart_link").unbind("click").one("click", function(event){ 3411 event.stopPropagation(); 3412 event.stopImmediatePropagation(); 3413 cartShow(); 3414 }); 3415 jQuery(".cartIcon").removeClass("fa-close").addClass("fa-shopping-cart"); 3416 } 3417 /* 3418 function set_date_cookie(){ 3419 if(this.id.indexOf("start_") !== -1){ 3420 setCookie("dateStart", this.value, 14); 3421 } else if(this.id.indexOf("end_") !== -1){ 3422 setCookie("dateEnd", this.value, 14); 3423 } 3424 } 3425 */ 3426 jQuery(document).ready(function () {setTimeout(simpleCart.init, 3);}); 3427 /*</editor-fold>*/ 3428 3429 /*<editor-fold defaultstate="collapsed" desc="Check Avail All Call">*/ 3430 function checkAvailAll(){ 3431 checkAvailCart(); 3432 checkAvailCartTimeslots(); 3433 checkAvailFilter(); 3434 } 3435 /*</editor-fold>*/ 3436 3437 /*<editor-fold defaultstate="collapsed" desc="Check Avail - Page">*/ 3438 /* for items on page not in cart */ 3439 function checkAvailFilter() { 3440 let rental_names = ""; 3441 let rental_ids = ""; 3442 let batch_ids = []; 3443 let cart_rental_names = ""; 3444 let cart_rental_ids = ""; 3445 let item_id = ""; 3446 let main_id = ""; 3447 jQuery(".item_encoded").each(function(){ 3448 rental_names += this.innerText + "|"; 3449 }); 3450 jQuery(".io_product_infobox .item_rentalid").each(function(){ 3451 rental_ids += this.innerText + "|"; 3452 item_id = this.innerText; 3453 main_id = this.innerText; 3454 }); 3455 let batch_count = 0; 3456 let batch_index = 0; 3457 // If we have rental id string set, then we don't want to include availability checking for fpw items in header 3458 // IO-31498 3459 if(!rental_ids) { 3460 jQuery(".io_item2_list_inner .item_rentalid, .io_item2_listrent .item_rentalid").each(function () { 3461 /* 3462 if(rental_ids.indexOf(this.innerText+"|") == -1){ 3463 rental_ids += this.innerText + "|"; 3464 } 3465 */ 3466 if (batch_count < 9) { 3467 if (!batch_ids.length) batch_ids.push("") 3468 if (!rid_in_batch(this.innerText + "|", batch_ids).length) { 3469 batch_ids[batch_index] += this.innerText + "|"; 3470 batch_count++; 3471 } 3472 } else { 3473 if (!rid_in_batch(this.innerText + "|", batch_ids).length) { 3474 batch_ids[batch_index] += this.innerText + "|"; 3475 batch_index++; 3476 batch_count = 0; 3477 batch_ids.push(""); 3478 } 3479 } 3480 }); 3481 } 3482 simpleCart.each(function (item, x) { 3483 var cart_name = item.get("encoded"); 3484 if(cart_name==null){ 3485 cart_name = encodeURIComponent(item.get("name")); 3486 cart_name = encodeURIComponent(decodeURIComponent(cart_name).replace(/[\u2032\u2019]+/ig,"'")); 3487 } 3488 let quantity = item.get("quantity"); 3489 if(item.get("inputtype") == "Map"){ 3490 quantity = 1 3491 } 3492 cart_rental_names += cart_name + "-" + quantity + "|"; 3493 var cart_id = item.get("rentalid"); 3494 cart_rental_ids += cart_id + "-" + quantity + "|"; 3495 }); 3496 /* #14494 IO-13779 */ 3497 let delivery_methods_arr = []; 3498 var delivery_prices = []; 3499 if(io_delivery_prices){ 3500 if(Object.keys(io_delivery_prices["override"]).includes(item_id)){ 3501 delivery_prices = io_delivery_prices["override"][item_id] 3502 }else{ 3503 if(!item_is_in_overrride_group(main_id)){ 3504 delivery_prices = io_delivery_prices["default"] 3505 } 3506 } 3507 for(item in io_delivery_methods){ 3508 if(delivery_prices.includes(io_delivery_methods[item]["id"])){ 3509 delivery_methods_arr.push(item); 3510 } 3511 } 3512 } 3513
3514 let custom_prices_arr = []; 3515 if(io_custom_prices){ 3516 if(Object.keys(io_custom_prices["override"]).includes(item_id.replace(":", '_'))){ 3517 custom_prices_arr = io_custom_prices["override"][item_id.replace(":", '_')] 3518 }else{ 3519 if(!item_is_in_overrride_group(main_id)){ 3520 custom_prices_arr = io_custom_prices["default"] 3521 } 3522 } 3523 } 3524 3525 /* IO-13548 */ 3526 if(io_accessory_price == "on"){ 3527 let times = getAvailTimes(); 3528 let acc_rental_id_str = getAccIDforPrice(); 3529 let return_id = 0; 3530 if(acc_rental_id_str != ""){ 3531 checkAvailCall(times[0],times[1],times[2],rental_names,acc_rental_id_str,displayAccessoryPrices,0,[],[],return_id,0,null,1,"",1); 3532 } 3533 } 3534 3535 let times = getAvailTimes(); 3536 if(rental_names.length>0){ 3537 if(use_weekday_weekend && rental_ids && !item_is_in_overrride_group(main_id)){ 3538 let return_id = 0; 3539 let week_weekend = ""; 3540 if(rental_ids != ""){ 3541 return_id = 1; 3542 week_weekend = get_week_weekend_times(times, main_id); 3543 checkAvailCall(week_weekend["weekday"][0],week_weekend["weekday"][1],week_weekend["weekday"][2],rental_names,rental_ids,updatePageAvail_weekday,0,cart_rental_ids,cart_rental_names,return_id,1); 3544 checkAvailCall(week_weekend["weekend"][0],week_weekend["weekend"][1],week_weekend["weekend"][2],rental_names,rental_ids,updatePageAvail_weekend,0,cart_rental_ids,cart_rental_names,return_id,1); 3545 } 3546 } 3547 let return_id = 0; 3548 if(rental_ids != "" || batch_ids.length){ 3549 return_id = 1; 3550 } 3551 if(delivery_methods_arr && rental_ids){ 3552 delivery_methods_arr.forEach(function(delivery_method){ 3553 checkAvailCall(times[0],times[1],times[2],rental_names,rental_ids,updatePageAvail_delivery_method,0,cart_rental_ids,cart_rental_names,return_id,1,delivery_method); 3554 }); 3555 } 3556 if(custom_prices_arr && rental_ids){ 3557 custom_prices_arr.forEach(function(custom_price){ 3558 let start_date = times[0]; 3559 let start_time = times[1]; 3560 if(!start_date){ 3561 start_date = getFormatteddate(new Date()); 3562 } 3563 if(!start_time){ 3564 start_time = io_default_start_time; 3565 } 3566 checkAvailCall(start_date,start_time,custom_price['duration'],rental_names,rental_ids,updatePageAvail_custom_price,0,cart_rental_ids,cart_rental_names,return_id,1,"",1,custom_price['name']); 3567 }); 3568 } 3569 3570 if(batch_ids.length){ 3571 batch_ids.forEach(function(rids){ 3572 return checkAvailCall(times[0],times[1],times[2],"",rids,updatePageAvail,0,cart_rental_ids,cart_rental_names,return_id,1,null,1,"",1); 3573 }); 3574 }else{ 3575 return checkAvailCall(times[0],times[1],times[2],rental_names,rental_ids,updatePageAvail,0,cart_rental_ids,cart_rental_names,return_id,1,null,1); 3576 } 3577 } 3578 } 3579 3580 function item_is_in_overrride_group(item_id){ 3581 for(const group_id in io_prices['override_groups']){ 3582 for(const search_id in io_prices['override_groups'][group_id]){ 3583 if(search_id == item_id){ 3584 return true; 3585 } 3586 } 3587 } 3588 return false 3589 } 3590 3591 function get_week_weekend_times(times, rid){ 3592 /* Create a copy instead of reference.*/ 3593 let temp_times = JSON.parse(JSON.stringify(times)); 3594 let start_date = temp_times[0]; 3595 if(!start_date){ 3596 start_date = getFormatteddate(new Date()); 3597 temp_times[0] = start_date; 3598 } 3599 temp_times[1] = io_default_start_time 3600 var newDate1 = convertDateStringtoDateObject(start_date, io_default_start_time); 3601 var newDate2 = convertDateStringtoDateObject(start_date, io_default_end_time); 3602 let time_duration = ((newDate2 - newDate1) / 3600) / 1000; 3603 temp_times[2] = time_duration; 3604 let day = new Date(newDate1).getDay(); //IO-28150 - Other countries put the date dd/mm/yy so using the formatted newDate1 instead of start_date accounts for this 3605 let weekday_weekend = {}; 3606 weekday_weekend["rid"] = rid; 3607 if(io_weekendDefine == "friday-sunday"){ 3608 if(day == 5 || day == 6 || day == 0){ 3609 weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times)); 3610 temp_times[0] = getNextMonday(temp_times[0]); 3611 weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times)); 3612 }else if(day == 1 || day == 2 || day == 3 || day == 4){ 3613 weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times)); 3614 temp_times[0] = getNextSaturday(temp_times[0]); 3615 weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times)); 3616 } 3617 }else if(io_weekendDefine == "saturday-sunday") { 3618 if (day == 6 || day == 0) { 3619 weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times)); 3620 temp_times[0] = getNextMonday(temp_times[0]); 3621 weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times)); 3622 } else if (day == 1 || day == 2 || day == 3 || day == 4 || day == 5) { 3623 weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times)); 3624 temp_times[0] = getNextSaturday(temp_times[0]); 3625 weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times)); 3626 } 3627 }else if (io_weekendDefine == "friday-monday"){ 3628 if(day == 5 || day == 6 || day == 0 || day == 1){ 3629 weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times)); 3630 temp_times[0] = getNextTuesday(temp_times[0]); 3631 weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times)); 3632 }else if(day == 2 || day == 3 || day == 4){ 3633 weekday_weekend["weekday"] = JSON.parse(JSON.stringify(temp_times)); 3634 temp_times[0] = getNextSaturday(temp_times[0]); 3635 weekday_weekend["weekend"] = JSON.parse(JSON.stringify(temp_times)); 3636 } 3637 } 3638 return weekday_weekend; 3639 } 3640 3641 /* 3642 helper function found here: 3643 https://bobbyhadz.com/blog/javascript-get-date-of-next-monday#:~:text=To%20get%20the%20next%20Monday%2C%20we%3A&text=If%20the%20remainder%20is%20equal,month%20for%20the%20next%20Monday. 3644 */ 3645 function getNextMonday(date_str) { 3646 const date_obj = parseDate(date_str, dateFormat); 3647 3648 const nextMonday = new Date( 3649 date_obj.setDate( 3650 date_obj.getDate() + ((7 - date_obj.getDay() + 1) % 7 || 7), 3651 ), 3652 ); 3653 3654 return getFormatteddate(nextMonday); 3655 } 3656 3657 function getNextTuesday(date_str) { 3658 const date_obj = parseDate(date_str, dateFormat); 3659 3660 const nextMonday = new Date( 3661 date_obj.setDate( 3662 date_obj.getDate() + ((7 - date_obj.getDay() + 2) % 7 || 7), 3663 ), 3664 ); 3665 3666 return getFormatteddate(nextMonday); 3667 } 3668 3669 function parseDate(date_str, format) { 3670 var parts = date_str.split(/[/.-]/); 3671 var day, month, year; 3672 3673 if (format === "m/d/yy") {
3674 month = parseInt(parts[0]) - 1; 3675 day = parseInt(parts[1]); 3676 year = parseInt(parts[2]) + (parts[2].length === 2 ? 2000 : 0); 3677 } else if (format === "d/m/yy") { 3678 day = parseInt(parts[0]); 3679 month = parseInt(parts[1]) - 1; 3680 year = parseInt(parts[2]) + (parts[2].length === 2 ? 2000 : 0); 3681 } else if (format === "yy/m/d") { 3682 year = parseInt(parts[0]) + (parts[0].length === 2 ? 2000 : 0); 3683 month = parseInt(parts[1]) - 1; 3684 day = parseInt(parts[2]); 3685 } else { 3686 throw new Error("Unsupported date format"); 3687 } 3688 3689 return new Date(year, month, day); 3690 } 3691 3692 /* modified from function above */ 3693 function getNextSaturday(date_str) { 3694 const date_obj = parseDate(date_str, dateFormat); 3695 3696 const next_friday = new Date( 3697 date_obj.setDate( 3698 date_obj.getDate() + ((7 - date_obj.getDay() + 6) % 7 || 7), 3699 ), 3700 ); 3701 3702 return getFormatteddate(next_friday); 3703 } 3704 3705 function updatePageAvail(data){ 3706 let use_id = data["return_id"] 3707 delete data["return_id"]; 3708 if(use_id == 1){ 3709 updatePageAvail_itemIDs(data) 3710 }else{ 3711 updatePageAvail_itemNames(data); 3712 } 3713 } 3714 function updatePageAvail_weekday(data){ 3715 jQuery.each(data, function (rental_id, qty){ 3716 if (rental_id == "price") { 3717 var prices = qty; 3718 jQuery.each(prices, function (price_id, amt) { 3719 let cust_price = document.querySelector(".io_product_cust_price_weekday"); 3720 if(cust_price==undefined){ 3721 var first_price = document.querySelector(".io_product_price_box"); 3722 if(first_price != null){ 3723 cust_price = first_price.cloneNode(true); 3724 /* clear all classes */ 3725 cust_price.className = ""; 3726 cust_price.classList.add("io_product_price_box"); 3727 cust_price.classList.add("io_product_cust_price_weekday"); 3728 cust_price.style.display = "none"; 3729 first_price.before(cust_price); 3730 } 3731 } 3732 3733 main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text(); 3734 if(main_item_id == price_id && cust_price!=undefined){ 3735 if(typeof amt == "string") amt = Number(amt.replace(",","")); 3736 cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt); 3737 let times = getAvailTimes(); 3738 cust_price.querySelector("p:nth-child(2)").innerHTML = io_weekDayText; 3739 if(amt>0){ 3740 cust_price.style.display = "grid"; 3741 }else{ 3742 cust_price.style.display = "none"; 3743 } 3744 } 3745 }); 3746 } 3747 }); 3748 } 3749 function updatePageAvail_delivery_method(data){ 3750 var delivery_method = data["delivery_method"] 3751 jQuery.each(data, function (rental_id, qty){ 3752 if (rental_id == "price") { 3753 var prices = qty; 3754 jQuery.each(prices, function (price_id, amt) { 3755 let cust_price = document.querySelector(".io_product_cust_price_delivery_method"+io_delivery_methods[delivery_method]["id"]); 3756 let rid = jQuery(".io_product_container .item_rentalid").first().text(); 3757 if(cust_price==undefined && !io_delivery_methods[delivery_method]["restricted"].includes(rid)){ 3758 var first_price = document.querySelector(".io_product_price_box"); 3759 if(first_price != null){ 3760 cust_price = first_price.cloneNode(true); 3761 /* clear all classes */ 3762 cust_price.className = ""; 3763 cust_price.classList.add("io_product_price_box"); 3764 cust_price.classList.add("io_product_cust_price_delivery_method"+io_delivery_methods[delivery_method]["id"]); 3765 cust_price.style.display = "none"; 3766 first_price.before(cust_price); 3767 } 3768 } 3769 3770 main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text(); 3771 if(main_item_id == price_id && cust_price!=undefined){ 3772 if(typeof amt == "string") amt = Number(amt.replace(",","")); 3773 cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt); 3774 let times = getAvailTimes(); 3775 cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times, delivery_method); 3776 if(amt>0 && event_time_set()){ 3777 cust_price.style.display = "grid"; 3778 }else{ 3779 cust_price.style.display = "none"; 3780 } 3781 } 3782 }); 3783 } 3784 }); 3785 } 3786 function updatePageAvail_custom_price(data, custom_price_name){
3787 let custom_price_class_name = custom_price_name.replace(/[\s:./()!]/g, '_'); 3788 jQuery.each(data, function (rental_id, qty){ 3789 if (rental_id == "price") { 3790 var prices = qty; 3791 jQuery.each(prices, function (price_id, amt) { 3792 let cust_price = document.querySelector(".io_product_cust_price_"+custom_price_class_name); 3793 let rid = jQuery(".io_product_container .item_rentalid").first().text(); 3794 if(cust_price==undefined){ 3795 var first_price = document.querySelector(".io_product_price_box"); 3796 if(first_price != null){ 3797 cust_price = first_price.cloneNode(true); 3798 /* clear all classes */ 3799 cust_price.className = ""; 3800 cust_price.classList.add("io_product_price_box"); 3801 cust_price.classList.add("io_product_cust_price_"+custom_price_class_name); 3802 cust_price.style.display = "none"; 3803 first_price.before(cust_price); 3804 } 3805 } 3806 3807 main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text(); 3808 if(main_item_id == price_id && cust_price!=undefined){ 3809 if(typeof amt == "string") amt = Number(amt.replace(",","")); 3810 cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt); 3811 cust_price.querySelector("p:nth-child(2)").innerHTML = "for " + custom_price_name; 3812 if(amt>0){ 3813 cust_price.style.display = "grid"; 3814 }else{ 3815 cust_price.style.display = "none"; 3816 } 3817 } 3818 }); 3819 } 3820 }); 3821 } 3822 function updatePageAvail_weekend(data){ 3823 jQuery.each(data, function (rental_id, qty){ 3824 if (rental_id == "price") { 3825 var prices = qty; 3826 jQuery.each(prices, function (price_id, amt) { 3827 let cust_price = document.querySelector(".io_product_cust_price_weekend"); 3828 if(cust_price==undefined){ 3829 var first_price = document.querySelector(".io_product_price_box"); 3830 if(first_price != null){ 3831 cust_price = first_price.cloneNode(true); 3832 /* clear all classes */ 3833 cust_price.className = ""; 3834 cust_price.classList.add("io_product_price_box"); 3835 cust_price.classList.add("io_product_cust_price_weekend"); 3836 cust_price.style.display = "none"; 3837 first_price.before(cust_price); 3838 } 3839 } 3840 3841 main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text(); 3842 if(main_item_id == price_id && cust_price!=undefined){ 3843 if(typeof amt == "string") amt = Number(amt.replace(",","")); 3844 cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt); 3845 let times = getAvailTimes(); 3846 cust_price.querySelector("p:nth-child(2)").innerHTML = io_weekEndText; 3847 if(amt>0){ 3848 cust_price.style.display = "grid"; 3849 }else{ 3850 cust_price.style.display = "none"; 3851 } 3852 } 3853 }); 3854 } 3855 }); 3856 } 3857 function updatePageAvail_itemIDs(data){ 3858 jQuery.each(data, function (rental_id, qty){ 3859 if (rental_id == "price" && jQuery(".io_product_infobox .item_inputtype").text() != "Map") { 3860 var prices = qty; 3861 jQuery.each(prices, function (price_id, amt) { 3862 let cust_price = document.querySelector(".io_product_cust_price"); 3863 if(cust_price==undefined){ 3864 var first_price = document.querySelector(".io_product_price_box"); 3865 if(first_price != null){ 3866 cust_price = first_price.cloneNode(true); 3867 /* clear all classes */ 3868 cust_price.className = ""; 3869 cust_price.classList.add("io_product_price_box"); 3870 cust_price.classList.add("io_product_cust_price"); 3871 cust_price.style.display = "none"; 3872 first_price.before(cust_price); 3873 } 3874 } 3875 main_item_id = jQuery(".io_product_infobox .item_rentalid").first().text(); 3876 if(main_item_id == price_id && cust_price!=undefined){ 3877 if(typeof amt == "string") amt = Number(amt.replace(",","")); 3878 cust_price.querySelector("p:nth-child(1)").innerHTML=simpleCart.toCurrency(amt); 3879 let times = getAvailTimes(); 3880 cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times); 3881 if(amt>0 && (event_time_set() || io_always_display_live_price == "on")){ 3882 cust_price.style.display = "grid"; 3883 }else{ 3884 cust_price.style.display = "none"; 3885 } 3886 } 3887 }); 3888 } 3889 3890 if(qty<=0 && rental_id != "delivery_method"){ 3891 /* cat,all-item,widget */ 3892 if(io_checkavail=="warn"){ 3893 jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add").removeClass("item_add").addClass("item_add_off").trigger("classChange"); 3894 jQuery(".unavailable_message_"+rental_id.replace(":", "\\\:")).show(); 3895 }
3896 if(io_checkavail=="hide") jQuery(".add_cart_"+rental_id).parent().parent().parent().hide(); 3897 3898 /* product page */ 3899 if(jQuery(".io_product_container").length && io_checkavail!="off" && jQuery(".io_product_container .item_rentalid").first().text() === rental_id){ 3900 jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add").first().removeClass("item_add").addClass("item_add_off").trigger("classChange"); 3901 jQuery(".io_product_container .unavailable_message").show(); 3902 } 3903 }else if(qty>0){ 3904 if(io_checkavail=="warn"){ 3905 jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange"); 3906 jQuery(".unavailable_message_"+rental_id.replace(":", "\\\:")).hide(); 3907 } 3908 if(io_checkavail=="hide") jQuery(".add_cart_"+rental_id).parent().parent().parent().show(); 3909 3910 /* product page */ 3911 if(jQuery(".io_product_container").length && io_checkavail!="off" && jQuery(".io_product_container .item_rentalid").first().text() === rental_id){ 3912 jQuery(".add_cart_"+rental_id.replace(":", "\\\:")+" .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange"); 3913 jQuery(".io_product_container .unavailable_message").hide(); 3914 } 3915 } 3916 }); 3917 } 3918 function updatePageAvail_itemNames(data){ 3919 jQuery.each(data, function (rental_name, qty) { 3920 rental_name = rental_name.replace(/[\u2032\u2019]+/ig,"'"); 3921 var main_name_temp = ""; 3922 if(typeof main_name_orig != "undefined"){ 3923 main_name_temp = main_name_orig.replace(/[\u2032\u2019]+/ig,"'"); 3924 } 3925 rental_name_esc = rental_name.replace(/'/g, "\\\\'"); 3926 if (rental_name == "price") { 3927 var prices = qty; 3928 jQuery.each(prices, function (price_name, amt) { 3929 /* var prices = document.querySelector(".io_product_price_box:not(.io_product_cust_price)"); */ 3930 /* if(prices != null) prices.remove(); */ 3931 let cust_price = document.querySelector(".io_product_cust_price"); 3932 if(cust_price==undefined){ 3933 var first_price = document.querySelector(".io_product_price_box"); 3934 if(first_price != null){ 3935 cust_price = first_price.cloneNode(true); 3936 /* clear all classes */ 3937 cust_price.className = ""; 3938 cust_price.classList.add("io_product_price_box"); 3939 cust_price.classList.add("io_product_cust_price"); 3940 cust_price.style.display = "none"; 3941 first_price.before(cust_price); 3942 } 3943 } 3944 try{ 3945 var main_name = decodeURIComponent(jQuery(".io_product_container .item_encoded").first().html().replace(/[+]/gi, "%20")); 3946 }catch(e){main_name=""} 3947 var i = main_name.lastIndexOf(":"); 3948 let acc_name = ""; 3949 let rental_name = ""; 3950 var i = main_name.lastIndexOf(":"); 3951 if(i>0){ 3952 rental_name = main_name.substring(0, i); 3953 acc_name = main_name.substring(i+1); 3954 } 3955 if (acc_name.toUpperCase() == price_name.toUpperCase() && cust_price!=undefined){ 3956 var rental_id = document.querySelector(".item_rentalid").innerText; 3957 if(rental_id != null){ 3958 rid_arr = rental_id.split(":"); 3959 /* ignore the main id for this */ 3960 rental_id = rid_arr[rid_arr.length-1]; 3961 if(jQuery("#io_acc_overrideprice_"+rental_id).first().text()>0){ 3962 amt = prices[acc_name]; 3963 }else{ 3964 let item_price = Number(prices[rental_name].replace(",","")); 3965 amt = Number(amt.replace(",","")) + item_price; 3966 amt = simpleCart.toCurrency(amt, {symbol:""}) 3967 } 3968 } 3969 cust_price.querySelector("p:nth-child(1)").innerText="$"+amt; 3970 if(typeof amt == "string") amt = Number(amt.replace(",","")); 3971 let times = getAvailTimes(); 3972 cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times); 3973 if(amt>0 && (event_time_set() || io_always_display_live_price == "on")){ 3974 cust_price.style.display = "grid"; 3975 }else{ 3976 cust_price.style.display = "none"; 3977 } 3978 3979 }else if(!rental_name && !acc_name && cust_price!=undefined){ 3980 amt = prices[main_name]; 3981 cust_price.querySelector("p:nth-child(1)").innerText="$"+amt; 3982 if(typeof amt == "string") amt = Number(amt.replace(",","")); 3983 let times = getAvailTimes(); 3984 cust_price.querySelector("p:nth-child(2)").innerHTML = make_live_price_editable_time(times); 3985 if(amt>0 && (event_time_set() || io_always_display_live_price == "on")){ 3986 cust_price.style.display = "grid"; 3987 }else{ 3988 cust_price.style.display = "none"; 3989 } 3990 } 3991 3992 }); 3993 } 3994 3995 if(qty<=0){ 3996 /* cat,all-item,widget */ 3997 if(io_checkavail=="warn"){ 3998 jQuery("div[name='maindiv_"+rental_name_esc+"'] .item_add").removeClass("item_add").addClass("item_add_off").trigger("classChange"); 3999 jQuery("div[name='maindiv_"+rental_name_esc+"'] .unavailable_message").show(); 4000 }
4001 if(io_checkavail=="hide") jQuery("div[name='maindiv_"+rental_name_esc+"']").hide(); 4002 4003 /* product page */ 4004 if(jQuery(".io_product_container").length && io_checkavail!="off"){ 4005 if(main_name_temp==rental_name){ 4006 jQuery(".io_product_container .item_add").first().removeClass("item_add").addClass("item_add_off").trigger("classChange"); 4007 jQuery(".io_product_container .unavailable_message").show(); 4008 } 4009 } 4010 }else if(qty>0){ 4011 /* console.log("good"); */ 4012 if(io_checkavail=="warn"){ 4013 jQuery("div[name='maindiv_"+rental_name_esc+"'] .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange"); 4014 jQuery("div[name='maindiv_"+rental_name_esc+"'] .unavailable_message").hide(); 4015 } 4016 if(io_checkavail=="hide") jQuery("div[name='maindiv_"+rental_name_esc+"']").show(); 4017 4018 /* product page */ 4019 if(jQuery(".io_product_container").length && io_checkavail!="off"){ 4020 if(main_name_temp==rental_name){ 4021 jQuery(".io_product_container .item_add_off").removeClass("item_add_off").addClass("item_add").trigger("classChange"); 4022 jQuery(".io_product_container .unavailable_message").hide(); 4023 } 4024 } 4025 } 4026 }); 4027 } 4028 function displayAccessoryPrices(data) { 4029 if (data.price) { 4030 let acc_prices = data.price; 4031 for (const [key, value] of Object.entries(acc_prices)) { 4032 let new_key = key; 4033 if ((key.match(/_/g) || []).length > 1) { 4034 let split_key = key.split("_"); 4035 let second_to_last = split_key[split_key.length - 2]; 4036 let last = split_key[split_key.length - 1]; 4037 new_key = second_to_last + "_" + last; 4038 } 4039 if (io_hide_zero == 1 && value > 0) { 4040 let id_string = "#io_acc_desc_" + new_key; 4041 let formatted_price = simpleCart.toCurrency(value); 4042 if (jQuery("#io_acc_" + new_key + " .io_acc_price").length > 0) { 4043 jQuery("#io_acc_" + new_key + " .io_acc_price").html(formatted_price); 4044 } else { 4045 let price_display = '<span class="io_acc_price"> ' + formatted_price + ' </span>'; 4046 jQuery(id_string).after(price_display); 4047 } 4048 } else if (io_hide_zero == 0) { 4049 let id_string = "#io_acc_desc_" + new_key; 4050 let formatted_price = simpleCart.toCurrency(value); 4051 if (jQuery("#io_acc_" + new_key + " .io_acc_price").length > 0) { 4052 jQuery("#io_acc_" + new_key + " .io_acc_price").html(formatted_price); 4053 } else { 4054 let price_display = '<span class="io_acc_price"> ' + formatted_price + ' </span>'; 4055 jQuery(id_string).after(price_display); 4056 } 4057 } 4058 } 4059 } 4060 } 4061 function make_live_price_editable_time(times, delivery_method=null) { 4062 if(!delivery_method) delivery_method = getCookie("io_delivery_method"); 4063 let ele_text = ""; 4064 if(times[0]) ele_text = "on " + times[0] + " "; 4065 if(times[2] === 0) times[2] = 1; 4066 if(io_hidetimes!="on" && !isNaN(times[2])) ele_text += "for "+times[2]+" hours "; 4067 if(delivery_method) ele_text += "for " + delivery_method + ". "; 4068 ele_text += '<span style="cursor:pointer; color:blue; text-decoration:underline;" onclick=checkAvailDateClick()>edit</span>'; 4069 return ele_text; 4070 } 4071 function checkAvailDateClick(){ 4072 cartShow(); 4073 /* expand the date picker */ 4074 setTimeout(calSetDateRange,100); 4075 } 4076 function checkAvailPageOnly(){ 4077 checkAvailFilter(); 4078 if(addressCookiesSet() && io_distance_charge){ 4079 runDeliveryCall(true); 4080 } 4081 } 4082 function getAccIDforPrice(){ 4083 let accessory_arr = jQuery(".io_acc_li").toArray(); 4084 let acc_rental_id_str = ""; 4085 for(let current_accessory = 0; current_accessory < accessory_arr.length; current_accessory++){ 4086 let required_tag = jQuery(accessory_arr[current_accessory]).find(".item_required"); 4087 if(required_tag.length > 0){ 4088 if(required_tag[0].innerText == 0){ 4089 acc_rental_id_str += jQuery(accessory_arr[current_accessory]).find(".item_rentalid")[0].innerText +"|"; 4090 } 4091 } 4092 } 4093 return acc_rental_id_str; 4094 } 4095 function getUpsellIDforPrice(){ 4096 let upsell_arr = jQuery(".page-carousel-rid").toArray(); 4097 let upsell_rental_id_str = ""; 4098 for(let current_upsell = 0; current_upsell < upsell_arr.length; current_upsell++){ 4099 upsell_rental_id_str +=upsell_arr[current_upsell].innerText+"|"; 4100 } 4101 return upsell_rental_id_str; 4102 } 4103 function displayUpsellPrices(data){ 4104 if(data.price){ 4105 let upsell_prices = data.price; 4106 for (const [key, value] of Object.entries(upsell_prices)) { 4107 if(io_hide_zero == 1 && value > 0){ 4108 let id_string = "#rid"+ key; 4109 let formatted_price = simpleCart.toCurrency(value); 4110 let price_display ='<span class="page-carousel-price"> '+formatted_price+' </span>'; 4111 jQuery(id_string).after(price_display); 4112 }else if(io_hide_zero == 0){ 4113 let id_string = "#rid"+ key; 4114 let formatted_price = simpleCart.toCurrency(value); 4115 let price_display ='<span class="page-carousel-price"> '+formatted_price+' </span>'; 4116 jQuery(id_string).after(price_display); 4117 } 4118 } 4119 pageFlickityRefresh(); 4120 } 4121 } 4122 /*</editor-fold>*/ 4123 4124 /*<editor-fold defaultstate="collapsed" desc="Check Avail - Cart">*/ 4125 function checkAvailCartOnly(skip_timer=false){ 4126 checkAvailCart(); 4127 checkAvailCartTimeslots(); 4128 } 4129 4130 function checkAvailCartTimeslots(){ 4131 let rental_names = ""; 4132 let rental_ids = "";
4133 let cart_rental_names = ""; 4134 let cart_rental_ids = ""; 4135 let times = getAvailTimes(); 4136 let start_date = times[0]; 4137 let event_duration = times[2]; 4138 let end_date = start_date; 4139 var event_start_time = getCookie("io_timeStart"); 4140 simpleCart.each(function (item, x) { 4141 var timeslots_html = item.get('timeslots'); 4142 if(typeof timeslots_html == "undefined") return; 4143 if(timeslots_html.length == 0) return; 4144 var cart_name = item.get("encoded"); 4145 if(cart_name==null) { 4146 cart_name = encodeURIComponent(item.get("name")); 4147 cart_name = encodeURIComponent(decodeURIComponent(cart_name).replace(/[\u2032\u2019]+/ig,"'")); 4148 } 4149 rental_id = item.get("rentalid"); 4150 4151 var timeslot_name = getTimeslotName(timeslots_html); 4152 var timeslot_sel_range = jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val(); 4153 if(typeof timeslot_sel_range != "undefined"){ 4154 /* timeslots */ 4155 setTimeslotSelected(item, timeslot_name); 4156 }else{ 4157 /* timepickers */ 4158 setTimePicker(item, timeslot_name); 4159 let start_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "start_timeslot_")); 4160 let end_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "end_timeslot_")); 4161 timeslot_sel_range = start_timepicker[start_timepicker.length-1].value; 4162 timeslot_sel_range += " - " + end_timepicker[end_timepicker.length-1].value; 4163 } 4164 4165 var timeslot_sel_arr = ""; 4166 if(typeof timeslot_sel_range != "undefined"){ 4167 var [start_time, end_time] = break_timeslot_sel_range(timeslot_sel_range); 4168 if(start_time && end_time){ 4169 let newDate1 = convertDateStringtoDateObject(start_date, start_time); 4170 let newDate2 = convertDateStringtoDateObject(end_date, end_time); 4171 let time_duration = ((newDate2 - newDate1) / 3600) / 1000; 4172 let quantity = item.get("quantity"); 4173 if(item.get("inputtype") == "Map"){ 4174 quantity = 1 4175 } 4176 rental_names += cart_name + "-" + quantity+"|"; 4177 rental_ids += rental_id+"-"+quantity+"-"+start_time+"-"+time_duration+"|"; 4178 cart_rental_names = rental_names; 4179 cart_rental_ids = rental_ids; 4180 } 4181 } 4182 }); 4183 if(rental_ids || rental_names){ 4184 checkAvailCall(start_date,event_start_time,event_duration,rental_names,rental_ids,updateCartAvail,1,cart_rental_ids,cart_rental_names,1); 4185 } 4186 return true; 4187 } 4188 4189 function checkAvailCart(){ 4190 let rental_names = ""; 4191 let rental_ids = ""; 4192 let cart_rental_names = ""; 4193 let cart_rental_ids = ""; 4194 simpleCart.each(function (item, x) { 4195 if(typeof item.get('timeslots') != "undefined"){ 4196 if(item.get('timeslots').length > 0){ 4197 return; 4198 } 4199 } 4200 var cart_name = item.get("encoded"); 4201 if(cart_name==null){ 4202 cart_name = encodeURIComponent(item.get("name")); 4203 cart_name = encodeURIComponent(decodeURIComponent(cart_name).replace(/[\u2032\u2019]+/ig,"'")); 4204 } 4205 let quantity = item.get("quantity"); 4206 if(item.get("inputtype") == "Map"){ 4207 quantity = 1 4208 } 4209 rental_names += cart_name + "-" + quantity + "|"; 4210 cart_rental_names += cart_name + "-" + quantity + "|"; 4211 var cart_id = item.get("rentalid"); 4212 rental_ids += cart_id + "-" + quantity + "|"; 4213 cart_rental_ids += cart_id + "-" + quantity + "|"; 4214 }); 4215 var times = getAvailTimes(); 4216 let return_id = 0; 4217 if(rental_ids != ""){ 4218 return_id = 1; 4219 } 4220 if(rental_ids != "" || rental_names != ""){ 4221 return checkAvailCall(times[0],times[1],times[2],rental_names,rental_ids,updateCartAvail,1,cart_rental_ids,cart_rental_names,return_id); 4222 } 4223 return true; 4224 } 4225 function updateCartAvail(data){ 4226 let use_id = data["return_id"] 4227 delete data["return_id"]; 4228 if(use_id == 1){ 4229 updateCartAvail_itemIDs(data) 4230 }else{ 4231 updateCartAvail_itemNames(data); 4232 } 4233 console.log("cart update"); 4234 if(addressCookiesSet() && io_distance_charge){ 4235 runDeliveryCall(true); 4236 } 4237 /* simpleCart.trigger("update"); */
4238 simpleCart.update(); 4239 /* jQuery("#avail").html(output); */ 4240 } 4241 4242 function updateCartAvail_itemIDs(data){ 4243 jQuery.each(data, function (rental_id, qty){ 4244 simpleCart.each(function (item, x) { 4245 if(rental_id == item.get("rentalid")){ 4246 if(io_hideQuantityAvail == "off"){ 4247 if(qty>=9999 || item.get("inputtype") == "Map" || (item.get("giftcardvalue") && item.get("giftcardvalue").trim())){ 4248 item.set("availability", "available"); 4249 }else{ 4250 item.set("availability", qty + " available"); 4251 } 4252 }else if(io_hideQuantityAvail == "on"){ 4253 if(qty<=0 || qty < item.get("quantity")){ 4254 item.set("availability", "not available"); 4255 }else{ 4256 item.set("availability", "available"); 4257 } 4258 } 4259 var vendorid = item.get("vendorid"); 4260 if(vendorid && vendorid.trim()){ 4261 item.set("availability", "availability must be verified"); 4262 } 4263 } 4264 if (rental_id == "price") { 4265 var prices = qty; 4266 jQuery.each(prices, function (price_name, amt) { 4267 if(price_name == item.get("rentalid")){ 4268 if (typeof amt == "string" || amt instanceof String){ 4269 if(amt != "TBD"){ 4270 if(typeof amt == "string") amt = Number(amt.replace(",","")); 4271 } 4272 } 4273 item.set("price", amt); 4274 } 4275 }); 4276 } 4277 }); 4278 }); 4279 } 4280 4281 function updateCartAvail_itemNames(data){ 4282 jQuery.each(data, function (rental_name, qty) { 4283 rental_name = rental_name.replace(/[\u2032\u2019]+/ig,"'"); 4284 simpleCart.each(function (item, x) { 4285 try{ 4286 var cart_name = decodeURIComponent(item.get("encoded").replace(/[+]/gi, "%20")); 4287 }catch(e){cart_name=null} 4288 if(cart_name==null) cart_name = item.get("name") 4289 cart_name = cart_name.replace(/[\u2032\u2019]+/ig,"'"); 4290 var i = cart_name.lastIndexOf(":"); 4291 if(i>0 && cart_name.toUpperCase() != rental_name.toUpperCase() && rental_name!="price"){cart_name = cart_name.substring(i+1)} 4292 if (cart_name.toUpperCase() == rental_name.toUpperCase()) { 4293 if(qty>9999){ 4294 item.set("availability", "available"); 4295 }else{ 4296 item.set("availability", qty + " available"); 4297 } 4298 } 4299 if (rental_name == "price") { 4300 var prices = qty; 4301 jQuery.each(prices, function (price_name, amt) { 4302 price_name = price_name.replace(/[\u2032\u2019]+/ig,"'"); 4303 let acc_name = ""; 4304 let rental_name = ""; 4305 var i = cart_name.lastIndexOf(":"); 4306 if(i>0){ 4307 rental_name = cart_name.substring(0, i); 4308 acc_name = cart_name.substring(i+1); 4309 } 4310 if (acc_name === price_name) { 4311 var rental_id = item.get("rentalid"); 4312 if(rental_id != null){ 4313 rid_arr = rental_id.split(":"); 4314 /* ignore the main id for this */ 4315 rental_id = rid_arr[rid_arr.length-1]; 4316 if(jQuery("#io_acc_overrideprice_"+rental_id).first().text()>0){ 4317 amt = prices[acc_name]; 4318 }else{ 4319 let item_price = Number(prices[rental_name].replace(",","")); 4320 amt = Number(amt.replace(",","")) + item_price; 4321 item.set("price", amt); 4322 return; 4323 } 4324 } 4325 if(amt==null){ 4326 amt = "0"; 4327 } 4328 /* returned price is per unit */ 4329 if(typeof amt == "string") amt = Number(amt.replace(",","")); 4330 item.set("price", amt); 4331 }else if(!rental_name && !acc_name){ 4332 amt = Number(prices[cart_name].replace(",","")); 4333 item.set("price", amt); 4334 } 4335 }); 4336 } 4337 }); 4338 }); 4339 } 4340 /*</editor-fold>*/ 4341 4342 /*<editor-fold defaultstate="collapsed" desc="Upsell Carousels">*/ 4343 function updateCartUpsell(data){ 4344 let cart_carousel = jQuery(".cart-carousel"); 4345 viewport = jQuery(".cart-carousel .flickity-viewport"); 4346 if(viewport.length > 0){ 4347 cart_carousel.flickity("destroy"); 4348 } 4349 cart_carousel.empty(); 4350 data.forEach(function(upsell){ 4351 cell = createCartCarouselCell(upsell["image"], upsell["name"], upsell["page"]); 4352 cart_carousel.append(cell); 4353 }); 4354 makeCarousel(cart_carousel); 4355 jQuery("#cart-carousel-container").show(); 4356 setTimeout(cartFlickityRefresh, 500); 4357 } 4358 4359 function cartFlickityRefresh(){ 4360 jQuery(".cart-carousel").flickity("resize"); 4361 } 4362 4363 //IO-14031 4364 function isMobile() 4365 { 4366 // Modern detection 4367 if (navigator.userAgentData && navigator.userAgentData.mobile !== undefined) { 4368 return navigator.userAgentData.mobile; 4369 } 4370 4371 // Fallback for older browsers 4372 return /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent) || 4373 ('ontouchstart' in window && navigator.maxTouchPoints > 0); 4374 } 4375 4376 function makeCarousel(cart_carousel) 4377 { 4378 cart_carousel.flickity({ 4379 wrapAround: true, 4380 draggable: isMobile(), 4381 cellAlign: 'left', 4382 //autoPlay: 3000, 4383 groupCells: true, 4384 resize: true 4385 }); 4386 cart_carousel_set = true; 4387 } 4388 4389 function createCartCarouselCell(image, name, page){ 4390 cell = '<div class="io_cart_carousel_cell"> <a href='+page+' class="cart-carousel-link"> <img class="cart-carousel-image" src='+image+'> <p class="cart-carousel-name"> '+name+' </p> </a> </div>'; 4391 return cell; 4392 } 4393 /*</editor-fold>*/ 4394 4395 /*<editor-fold defaultstate="collapsed" desc="Ajax Calls">*/ 4396 function checkAvailCall(start_date,start_time,time_duration,rental_names,rental_ids,returnFunc,singleCart,cart_rental_ids,cart_rental_names,return_id,temp=0,delivery_method=null,price_only=0,custom_price_name="", skip_hidden_lead = 0) { 4397 /*
4398 IO-21459 If we have no duration set (event not set in cart), and we are doing the call for the page live 4399 price, and we have the setting on where we want to display this price even if the event date is not set: 4400 4401 We set the time_duration to 1 hour. This defaults the start date to January 1, 1970 with duration of 4402 1 hour in the lead meaning it will be available and we have the one hour price. 4403 */ 4404 if((isNaN(time_duration) || time_duration===0) && price_only==1 && io_always_display_live_price == "on"){ 4405 time_duration = 1; 4406 if(!start_date){ 4407 start_date = getFormatteddate(new Date()); 4408 } 4409 if(!start_time){ 4410 start_time = getFormattedtime(new Date()); 4411 } 4412 }else if((isNaN(time_duration) || time_duration===0) && price_only==0 && io_hidetimes === "on"){ 4413 /* IO-22689 if they have times hidden, and happen to have the same default start and end time, we still want to do the call. */ 4414 time_duration = 1; 4415 }else if(isNaN(time_duration) || time_duration===0){ 4416 return; 4417 } 4418 url = "https://rental.software/quotes/check_availability_v2.php?callback=?"; 4419 if(window.location.href.indexOf("localhost") > -1){ 4420 //url = "http://localhost/bugs/quotes/check_availability_v2.php?callback=?"; 4421 url = "http://localhost/io/bugs/quotes/check_availability_v2.php?callback=?"; 4422 //url = "http://localhost/jbug/trunk/quotes/check_availability_v2.php?callback=?"; 4423 } 4424 if(!delivery_method) delivery_method = getCookie("io_delivery_method"); 4425 let address_data = { 4426 "address": getCookie("io_address"), 4427 "state": getCookie("io_state"), 4428 "city": getCookie("io_city"), 4429 "zip": getCookie("io_zip") 4430 }; 4431 if(!ioHasMarketingConsent()){ 4432 address_data = {"address":"", "state":"", "city":"", "zip":""}; 4433 } 4434 url += 4435 "&name=" + encodeURIComponent("Good Times Inflatables") + 4436 "&startdate=" + start_date + 4437 "&starttime=" + start_time + 4438 "&duration=" + time_duration + 4439 "&street=" + encodeURIComponent(address_data["address"]) + 4440 "&city=" + encodeURIComponent(address_data["city"]) + 4441 "&state=" + encodeURIComponent(address_data["state"]) + 4442 "&zip=" + encodeURIComponent(address_data["zip"]) + 4443 "&single_cart=" + singleCart + 4444 "&usecushion=1" + 4445 "&include_price=1" + 4446 "&showlocations=0" + 4447 "&rental_names=" + rental_names + 4448 "&rental_ids=" + rental_ids + 4449 "&cart_rental_names=" + cart_rental_names + 4450 "&cart_rental_ids=" + cart_rental_ids + 4451 "&return_id=" + return_id + 4452 "&delivery_method=" + delivery_method + 4453 "&temp=" + temp + 4454 "&skip_hidden_lead="+ skip_hidden_lead; 4455 if (custom_price_name) 4456 { 4457 ioCartLoaderIncrement(); 4458 jQuery.getJSON(url, function (data) 4459 { 4460 try 4461 { 4462 returnFunc(data, custom_price_name); 4463 } 4464 finally 4465 { 4466 ioCartLoaderDecrement(); 4467 } 4468 }); 4469 } 4470 else 4471 { 4472 ioCartLoaderIncrement(); 4473 jQuery.getJSON(url, function (data) 4474 { 4475 try 4476 { 4477 returnFunc(data); 4478 } 4479 finally 4480 { 4481 ioCartLoaderDecrement(); 4482 } 4483 }); 4484 } 4485 } 4486 4487 function getUpsellsCall(start_date,start_time,time_duration,rental_ids,returnFunc) { 4488 if(rental_ids.replace(/[|]/g,"").length==0){return;} 4489 url = "https://rental.software/quotes/in_cart_upsell.php?callback=?"; 4490 if(window.location.href.indexOf("localhost") > -1){ 4491 //url = "http://localhost/bugs/quotes/in_cart_upsell.php?callback=?" 4492 url = "http://localhost/io/bugs/quotes/in_cart_upsell.php?callback=?" 4493 } 4494 url += 4495 "&name=" + encodeURIComponent("Good Times Inflatables") + 4496 "&startdate=" + start_date + 4497 "&starttime=" + start_time + 4498 "&duration=" + time_duration + 4499 "&usecushion=1" + 4500 "&include_price=1" + 4501 "&showlocations=0" + 4502 "&rental_ids=" + rental_ids; 4503 //IO-25557 4504 if(window.location.href.indexOf("dev.rental.software") > -1)//if it is a dev site, we need to send 4505 { 4506 let pattern = /(https:\/\/dev\.rental\.software\/[^\/]+\/)/; 4507 let matches = window.location.href.match(pattern); 4508 matches && matches.length > 0 ? url += "&site=" + matches[0]:0; 4509 } 4510 else 4511 { 4512 url += "&site=" + window.location.host; 4513 } 4514 jQuery.getJSON(url, returnFunc); 4515 } 4516 /*</editor-fold>*/ 4517 4518 /*<editor-fold defaultstate="collapsed" desc="Customer Geolocation Functions">*/ 4519 function setLocationInLocalStorage(city) 4520 {
4521 try 4522 { 4523 const location_data = 4524 { 4525 city: city, 4526 timestamp: Date.now() 4527 }; 4528 localStorage.setItem(storage_key, JSON.stringify(location_data)); 4529 return true; 4530 } 4531 catch (e) 4532 { 4533 console.warn('Failed to save location to localStorage:', e); 4534 return false; 4535 } 4536 } 4537 4538 function getLocationFromLocalStorage() 4539 { 4540 try 4541 { 4542 const location_data = localStorage.getItem(storage_key); 4543 if (location_data) 4544 { 4545 return JSON.parse(location_data); 4546 } 4547 4548 } 4549 catch (e) 4550 { 4551 console.warn('Failed to retrieve location from localStorage:', e); 4552 } 4553 return null; 4554 } 4555 4556 function displayLocation(city) 4557 { 4558 const location_element = jQuery('.io_geo_city'); 4559 const container_element = jQuery('#io_customer_geolocation'); 4560 4561 if (location_element.length && container_element.length) 4562 { 4563 location_element.text(`${city}`); 4564 container_element.show(); 4565 return true; 4566 } 4567 return false; 4568 } 4569 4570 function getCityFromIO(returnFunc) 4571 { 4572 var url = "https://rental.software/include/geolocation_handler.php?callback=?"; 4573 if(window.location.href.indexOf("localhost") > -1) 4574 { 4575 url = "http://localhost//features//include/geolocation_handler.php?callback=?"; 4576 } 4577 url += 4578 "&name=" + encodeURIComponent("Good Times Inflatables") + 4579 "&ip=" + encodeURIComponent(io_customer_ip); 4580 4581 jQuery.getJSON(url, returnFunc); 4582 } 4583 4584 function initializeGeolocation() 4585 { 4586 try 4587 { 4588 // Check local storage first 4589 const cached_location = getLocationFromLocalStorage(); 4590 if (cached_location && cached_location.city) 4591 { 4592 if (displayLocation(cached_location.city)) 4593 { 4594 return; 4595 } 4596 } 4597 4598 // If no cached location, call the handler to get location 4599 getCityFromIO(function(location_data) 4600 { 4601 if (location_data && location_data.city && !location_data.error) 4602 { 4603 // Display and store the location 4604 if (displayLocation(location_data.city)) 4605 { 4606 setLocationInLocalStorage(location_data.city); 4607 } 4608 } 4609 else 4610 { 4611 console.warn('Failed to get location:', location_data ? location_data.error : 'Unknown error'); 4612 } 4613 }); 4614 } 4615 catch (error) 4616 { 4617 console.error('Geolocation initialization failed:', error); 4618 } 4619 } 4620 /*</editor-fold>*/ 4621 4622 /*<editor-fold defaultstate="collapsed" desc="Loading Animation Helpers">*/ 4623 4624 /** 4625 * Toggles the visibility of the cart loading overlay. 4626 * 4627 * @param {boolean} show - A boolean value to determine whether to show or hide the overlay. 4628 * If true, the overlay becomes visible; if false, it is hidden. 4629 * @return {void} This function does not return a value. 4630 */ 4631 function ioCartShowOverlay(show) 4632 { 4633 try 4634 { 4635 var overlay = document.getElementById('ioCartLoadingOverlay'); 4636 if (!overlay) return; 4637 if (show) 4638 { 4639 overlay.style.display = 'flex'; 4640 overlay.setAttribute('aria-hidden', 'false'); 4641 } 4642 else 4643 { 4644 overlay.style.display = 'none'; 4645 overlay.setAttribute('aria-hidden', 'true'); 4646 } 4647 } 4648 catch (e) 4649 {} 4650 } 4651 4652 /** 4653 * Activates the cart loader by setting the loading state to active, initializing the loading count, 4654 * and displaying the overlay. Includes a fallback to deactivate the loader if no response is received 4655 * within a specified timeout period. 4656 * 4657 * @return {void} This method does not return a value. 4658 */ 4659 function ioCartLoaderActivate() 4660 { 4661 io_cart_loading_active = true; 4662 io_cart_loading_count = 0; 4663 ioCartShowOverlay(true); 4664 4665 //fallback in case the availability call doesn't come back 4666 if (io_cart_loading_fallback_timer) clearTimeout(io_cart_loading_fallback_timer); 4667 io_cart_loading_fallback_timer = setTimeout(function () { 4668 if (io_cart_loading_active) { 4669 io_cart_loading_active = false;
4670 io_cart_loading_count = 0; 4671 ioCartShowOverlay(false); 4672 } 4673 }, 15000); 4674 } 4675 4676 /** 4677 * Increments the count of active cart loading operations and ensures the cart overlay is displayed. 4678 * 4679 * This method increases the `io_cart_loading_count` if the `io_cart_loading_active` flag is set to true. 4680 * It also calls the `ioCartShowOverlay` function with a true value to show the overlay. 4681 * 4682 * @return {void} This function does not return any value. 4683 */ 4684 function ioCartLoaderIncrement() 4685 { 4686 if (io_cart_loading_active) 4687 { 4688 io_cart_loading_count++; 4689 ioCartShowOverlay(true); 4690 } 4691 } 4692 4693 /** 4694 * Decrements the `io_cart_loading_count` if `io_cart_loading_active` is true. 4695 * If the count reaches zero, it deactivates the loader, removes the overlay, 4696 * and clears the fallback timer 4697 */ 4698 function ioCartLoaderDecrement() 4699 { 4700 if (io_cart_loading_active) 4701 { 4702 io_cart_loading_count = Math.max(0, io_cart_loading_count - 1); 4703 4704 if (io_cart_loading_count === 0) 4705 { 4706 io_cart_loading_active = false; 4707 ioCartShowOverlay(false); 4708 4709 if (io_cart_loading_fallback_timer) 4710 { 4711 clearTimeout(io_cart_loading_fallback_timer); 4712 io_cart_loading_fallback_timer = null; 4713 } 4714 } 4715 } 4716 } 4717 4718 /*</editor-fold>*/</script>
4718 <div class="address_entry elementor-widget-text-editor"><table><tr><td> <label for="address" id="io_cdl_address_label" style="display: table-cell"> Street Address </label></td><td> <input id="io_cd_address" style="display: table-cell" name="address" type="text"></input></td></tr><tr><td> <label for="city" id="io_cdl_city_label" style="display: table-cell"> City </label></td><td> <input id="io_cd_city" style="display: table-cell" name="city" type="text"></input></td></tr><tr id="us-state-select"><td> <label for="state" id="io_cdl_state_label" style="display: table-cell"> State </label></td><td> <select name="state" id="io_cd_state" style="display: table-cell" class="input-mini"><option value=""></option><option value="AK">AK</option><option value="AL">AL</option><option value="AR">AR</option><option value="AZ">AZ</option><option value="CA">CA</option><option value="CO">CO</option><option value="CT">CT</option><option value="DC">DC</option><option value="DE">DE</option><option value="FL">FL</option><option value="GA">GA</option><option value="HI">HI</option><option value="IA">IA</option><option value="ID">ID</option><option value="IL">IL</option><option value="IN">IN</option><option value="KS">KS</option><option value="KY">KY</option><option value="LA">LA</option><option value="MA">MA</option><option value="MD">MD</option><option value="ME">ME</option><option value="MI">MI</option><option value="MN">MN</option><option value="MO">MO</option><option value="MS">MS</option><option value="MT">MT</option><option value="NC">NC</option><option value="ND">ND</option><option value="NE">NE</option><option value="NH">NH</option><option value="NJ">NJ</option><option value="NM">NM</option><option value="NV">NV</option><option value="NY">NY</option><option value="OH">OH</option><option value="OK">OK</option><option value="OR">OR</option><option value="PA">PA</option><option value="RI">RI</option><option value="SC">SC</option><option value="SD">SD</option><option value="TN">TN</option><option value="TX">TX</option><option value="UT">UT</option><option value="VA">VA</option><option value="VT">VT</option><option value="WA">WA</option><option value="WI">WI</option><option value="WV">WV</option><option value="WY">WY</option> </select></td></tr><tr><td> <label for="zip" id="io_cdl_zip_label" style="display: table-cell"> Zip Code </label></td><td> <input id="io_cd_zip" style="display: table-cell" name="zip" type="text"></input></td></tr></table> <a class="elementor-button elementor-size-sm io_button" 4719 id="address_entry_submit" 4720 href="javascript:;"> Save Address </a><div id="delivery_charge_info_box"><hr><h3 id="info_box_header"></h3><p id="info_box_information"></p> <a href="javascript:;" onClick="closeAddressEntry()" class="delivery_info_continue elementor-button elementor-size-sm io_button">Continue Shopping</a></div></div>
4720<script>/* for checking delivery */ 4721 function runDeliveryCall(cart_only = false){ 4722 let address_fields = jQuery("[id^='io_cd_']"); 4723 let address_data = { 4724 "address": getCookie("io_address"), 4725 "state": getCookie("io_state"), 4726 "city": getCookie("io_city"), 4727 "zip": getCookie("io_zip") 4728 }; 4729 4730 let times = getAvailTimes(); 4731 4732 let start_date = times[0]; 4733 let end_date = start_date; 4734 let start_time = times[1]; 4735 let duration = times[2]; 4736 4737 let rental_ids = ""; 4738 simpleCart.each(function (item, x) { 4739 if(typeof item.get('timeslots') != "undefined"){ 4740 if(item.get('timeslots').length > 0){ 4741 var timeslots_html = item.get('timeslots'); 4742 var rental_id = item.get('rentalid'); 4743 if(typeof timeslots_html == "undefined") return; 4744 if(timeslots_html.length == 0) return; 4745 4746 var timeslot_name = getTimeslotName(timeslots_html); 4747 var timeslot_sel_range = jQuery(".item-timeslots [name=\""+timeslot_name+"\"] option:selected").val(); 4748 if(typeof timeslot_sel_range != "undefined"){ 4749 /* timeslots */ 4750 setTimeslotSelected(item, timeslot_name); 4751 }else{ 4752 /* timepickers */ 4753 setTimePicker(item, timeslot_name);//todo? 4754 let start_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "start_timeslot_")); 4755 let end_timepicker = document.getElementsByName(timeslot_name.replace("io_timepicker_", "end_timeslot_")); 4756 timeslot_sel_range = start_timepicker[start_timepicker.length-1].value; 4757 timeslot_sel_range += " - " + end_timepicker[end_timepicker.length-1].value; 4758 } 4759 4760 var timeslot_sel_arr = ""; 4761 if(typeof timeslot_sel_range != "undefined"){ 4762 timeslot_sel_arr = timeslot_sel_range.split(" - "); 4763 var timeslot_start_time = timeslot_sel_arr[0].replace("am"," am").replace("pm"," pm").replace(" "," "); 4764 var timeslot_end_time = timeslot_sel_arr[1].replace("am"," am").replace("pm"," pm").replace(" "," "); 4765 if(timeslot_start_time && timeslot_end_time){ 4766 let newDate1 = convertDateStringtoDateObject(start_date, timeslot_start_time); 4767 let newDate2 = convertDateStringtoDateObject(end_date, timeslot_end_time); 4768 let timeslot_duration = ((newDate2 - newDate1) / 3600) / 1000; 4769 rental_ids += rental_id+"-"+item.get("quantity")+"-"+timeslot_start_time+"-"+timeslot_duration+"|"; 4770 } 4771 } 4772 } 4773 } 4774 else{ 4775 var cart_id = item.get("rentalid"); 4776 rental_ids += cart_id + "-" + item.get("quantity") + "|"; 4777 } 4778 }); 4779 4780 address_fields.each(function() { 4781 let field = this.id.split("_")[2]; 4782 value = this.value; 4783 if(!value && !address_data[field]){ 4784 jQuery(this).addClass("invalid_address_field") 4785 } 4786 else if(value){ 4787 jQuery(this).removeClass("invalid_address_field") 4788 address_data[field] = this.value; 4789 } 4790 }); 4791 if(jQuery(".invalid_address_field").length > 0){ 4792 return; 4793 } 4794 let delivery_method = "" 4795 if(io_default_delivery_method) 4796 { 4797 delivery_method = io_default_delivery_method; 4798 } 4799 else if(getCookie("io_delivery_method")) 4800 { 4801 delivery_method = getCookie("io_delivery_method"); 4802 } 4803 4804 4805 setCookie("io_address", address_data["address"], 14); 4806 setCookie("io_city", address_data["city"], 14); 4807 setCookie("io_state", address_data["state"], 14); 4808 setCookie("io_zip", address_data["zip"], 14); 4809 4810 cart_total = simpleCart.total(); 4811 if(cart_total === "TBD") cart_total = 0; 4812 url = "https://rental.software/quotes/get_delivery_info.php?callback=?"; 4813 if(window.location.href.indexOf("localhost") > -1){ 4814 //url = "http://localhost/bugs/quotes/get_delivery_info.php?callback=?"; 4815 url = "http://localhost/io/bugs/quotes/get_delivery_info.php?callback=?"; 4816 } 4817 url += 4818 "&name=" + encodeURIComponent("Good Times Inflatables") + 4819 "&rental_ids=" + rental_ids + 4820 "&street=" + encodeURIComponent(address_data["address"]) + 4821 "&city=" + encodeURIComponent(address_data["city"]) + 4822 "&state=" + encodeURIComponent(address_data["state"]) + 4823 "&zip=" + encodeURIComponent(address_data["zip"]) + 4824 "&startdate=" + start_date + 4825 "&starttime=" + start_time + 4826 "&duration=" + duration + 4827 "&delivery_method=" + encodeURIComponent(delivery_method) + 4828 "&total=" + cart_total + 4829 "&cart_only=" + cart_only; 4830 jQuery.getJSON(url, function(data){ 4831 if(data["delivery_restrict"] === 1){ 4832 data["charge"] = 0; 4833 }
4834 handleDeliveryInfo(data, cart_only); 4835 }); 4836 } 4837 4838 function handleDeliveryInfo(data, cart_only = false){ 4839 jQuery("#deliverSubtotalContainer").show(); 4840 jQuery("#checkDeliveryMessage").hide(); 4841 let info_box = jQuery("#delivery_charge_info_box"); 4842 if(data["delivery_restrict"] == 1){ 4843 jQuery("#info_box_header").text("Sorry..."); 4844 jQuery("#info_box_information").text(data["error"]) 4845 setDeliverySubtotal(data["charge"], true) 4846 } 4847 else{ 4848 setDeliverySubtotal(data["charge"]) 4849 jQuery("#info_box_header").text("Success!"); 4850 if(data["charge"] > 0){ 4851 jQuery("#info_box_information").html("We are able to deliver to your location with a " + simpleCart.toCurrency(data["charge"]) +" fee!"); 4852 } 4853 else{ 4854 jQuery("#info_box_information").html("We are able to deliver to your location with no charge!"); 4855 } 4856 } 4857 if(simpleCart.items().length == 0 && cart_only){ 4858 jQuery("#info_box_header").text("Items Required."); 4859 jQuery("#info_box_information").html("There needs to be items in your cart to check for delivery fees. But we will save the address information so you don't have to enter it again!") 4860 } 4861 info_box.show(); 4862 jQuery.fancybox.update(jQuery(".address_entry")); 4863 } 4864 function showAddressEntry(cart_only=false){ 4865 cartHide(); 4866 jQuery(".invalid_address_field").removeClass("invalid_address_field") 4867 jQuery("#delivery_charge_info_box").hide(); 4868 jQuery("#io_cd_address").val(getCookie("io_address")); 4869 jQuery("#io_cd_state").val(getCookie("io_state")); 4870 jQuery("#io_cd_city").val(getCookie("io_city")); 4871 jQuery("#io_cd_zip").val(getCookie("io_zip")); 4872 if(!cart_only){ 4873 jQuery("#address_entry_submit").on("click", null, function(){ runDeliveryCall(); }); 4874 } else{ 4875 jQuery("#address_entry_submit").on("click", null, function(){ runDeliveryCall(cart_only); }); 4876 } 4877 jQuery.fancybox.open(jQuery(".address_entry")); 4878 } 4879 4880 function closeAddressEntry(){ 4881 jQuery.fancybox.close(); 4882 } 4883 4884 function setDeliverySubtotal(amount, unavailable=false){ 4885 if(unavailable){ 4886 jQuery("#deliverySubtotal").html("Unavailable"); 4887 } else{ 4888 jQuery("#deliverySubtotal").html(simpleCart.toCurrency(amount)); 4889 } 4890 } 4891 4892 function addressCookiesSet(){ 4893 if(getCookie("address") && getCookie("state") && getCookie("city") && getCookie("zip")){ 4894 return true; 4895 } else{ 4896 return false 4897 } 4898 }</script>
vendor: 1 bytes, line 4898
4898
4899<script>let map; 4900 let geocoder; 4901 let item_id_map; 4902 let drawingManager; 4903 let drawingListener; 4904 4905 let polygons = new Array(); 4906 4907 let polyline_markers = new Array(); 4908 let polylines = new Array(); 4909 let previous_marker; 4910 current_polyline = undefined; 4911 let previous_map_height = ""; 4912 4913 function initMap() { 4914 map = new google.maps.Map(document.getElementById("map_container"), { 4915 center: { lat: -34.397, lng: 150.644 }, 4916 zoom: 8, 4917 mapTypeId: "hybrid", 4918 disableDefaultUI: true, 4919 tilt: 0 4920 }); 4921 drawingManager = new google.maps.drawing.DrawingManager({ 4922 drawingControl: true, 4923 drawingControlOptions: { 4924 position: google.maps.ControlPosition.TOP_CENTER, 4925 drawingModes: [ 4926 google.maps.drawing.OverlayType.POLYGON, 4927 ], 4928 } 4929 }); 4930 4931 geocoder = new google.maps.Geocoder(); 4932 } 4933 4934 function io_geocode(){ 4935 let prefix = "#io_mc_" 4936 let request = "" 4937 let address_value = ""; 4938 if(jQuery(prefix+"address").length) { 4939 address_value = jQuery(prefix+"address").val(); 4940 if(address_value) setCookie("address", jQuery("#io_mc_address").val(), 14); 4941 } 4942 let city_value = ""; 4943 if(jQuery(prefix+"city").length){ 4944 city_value = jQuery(prefix+"city").val(); 4945 if(city_value) setCookie("city", jQuery("#io_mc_city").val(), 14); 4946 } 4947 let state_value = ""; 4948 if(jQuery(prefix+"state").length){ 4949 state_value = jQuery(prefix+"state").val(); 4950 if(state_value) setCookie("state", jQuery("#io_mc_state").val(), 14); 4951 } 4952 let zip_value = ""; 4953 if(jQuery(prefix+"zip").length){ 4954 zip_value = jQuery(prefix+"zip").val(); 4955 if(zip_value) setCookie("zip", jQuery("#io_mc_zip").val(), 14); 4956 } 4957 4958 request = address_value + " " + city_value + " " + state_value + " " + zip_value; 4959 if(request){ 4960 geocoder.geocode({address:request}).then((result) => { 4961 const { results } = result; 4962 map.setCenter(results[0].geometry.location); 4963 map.setZoom(24); 4964 return results; 4965 }); 4966 4967 } 4968 4969 if(!addressProvided()) { 4970 jQuery("#io_map_address_entry").attr("open", "open"); 4971 }else{ 4972 jQuery("#io_map_address_entry").removeAttr("open"); 4973 } 4974 } 4975 4976 function openMap(element){ 4977 cartHide() 4978 io_map_clear() 4979 let unit = "meters" 4980 if(country === "US") unit = "feet" 4981 polygons = new Array(); 4982 polyline_marker_sets = new Array(); 4983 polylines = new Array(); 4984 previous_marker = undefined; 4985 current_polyline = undefined; 4986 4987 jQuery("#io_mc_address").val(getCookie("address")); 4988 jQuery("#io_mc_state").val(getCookie("state")); 4989 jQuery("#io_mc_city").val(getCookie("city")); 4990 jQuery("#io_mc_zip").val(getCookie("zip")); 4991 io_geocode(); 4992 4993 google.maps.event.removeListener(drawingListener); 4994 4995 if(element.id == "calcPriceOpenMap"){ 4996 item_id_map = jQuery(".io_product_infobox .item_rentalid").text(); 4997 if(jQuery(".io_product_infobox .item_qtytype").text() == "Area"){ 4998 setMapTools_Area(unit, true) 4999 }else if(jQuery(".io_product_infobox .item_qtytype").text() == "Perimeter"){ 5000 setMapTools_Perimeter(unit, true) 5001 } 5002 } 5003 else{ 5004 item_id_map = jQuery(element).parent().parent().find(".item-rentalid").text(); 5005 if(jQuery(element).parent().parent().find(".item-qtytype").text() == "Area"){ 5006 setMapTools_Area(unit) 5007 }else if(jQuery(element).parent().parent().find(".item-qtytype").text() == "Perimeter"){ 5008 setMapTools_Perimeter(unit) 5009 } 5010 } 5011 } 5012 5013 function addressProvided(){ 5014 if(jQuery("#io_mc_address").val() && jQuery("#io_mc_state").val() && 5015 jQuery("#io_mc_city").val() && jQuery("#io_mc_zip").val() ){ 5016 return true; 5017 } 5018 return false; 5019 } 5020 5021 function setMapTools_Area(unit, item_page=false){ 5022 jQuery.fancybox.open(jQuery(".map_fancybox")); 5023 drawingManager.setOptions({ 5024 drawingControlOptions: { 5025 drawingModes: [google.maps.drawing.OverlayType.POLYGON] 5026 }, 5027 drawingMode: google.maps.drawing.OverlayType.POLYGON, 5028 polygonOptions: { 5029 fillColor: "#0191fc", 5030 strokeColor: "#0113fc" 5031 }, 5032 }); 5033 let units = "meters" 5034 if(country === "US") units = "feet" 5035 5036 jQuery("#io_measurement_input_label").text("Approximate area in "+units+": "); 5037 jQuery("#io_map_manual_input").off("click"); 5038 jQuery("#io_map_manual_input").on("click", function(){manual_calc_price("Area", item_page)}); 5039 jQuery("#io_perimeter_options_container").hide(); 5040 jQuery("#io_map_new_line_container").hide(); 5041 jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area y
5041ou want to measure. <span id=\"io_map_additional_instructions\">You can draw multiple polygons to include multiple separate surfaces in the total area. Press Clear to remove all polygons and start again. Alternatively if you know the approximate area in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>") 5042 5043 drawingListener = google.maps.event.addListener(drawingManager, "polygoncomplete", function(polygon) { 5044 polygons.push(polygon); 5045 let convert_feet = 1; 5046 if(country === "US") convert_feet = 10.764; 5047 let approx_area = 0; 5048 polygons.forEach(function(polygon) { 5049 approx_area += google.maps.geometry.spherical.computeArea(polygon.getPath()) * convert_feet; 5050 }); 5051 calcprice_approx_area(Math.round(approx_area)); 5052 }); 5053 drawingManager.setMap(map); 5054 } 5055 5056 function setMapTools_Perimeter(unit, item_page=false){ 5057 jQuery.fancybox.open(jQuery(".map_fancybox")); 5058 drawingManager.setOptions({ 5059 drawingControlOptions: { 5060 drawingModes: [google.maps.drawing.OverlayType.MARKER] 5061 }, 5062 drawingMode: google.maps.drawing.OverlayType.MARKER 5063 }); 5064 let height = jQuery("#perimeter_height").val(); 5065 let units = ""; 5066 if(height){ 5067 units = "sq meters" 5068 if(country === "US") units = "sq feet" 5069 jQuery("#io_measurement_input_label").text("Approximate surface area in "+units+": "); 5070 jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate surface area in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>") 5071 5072 }else{ 5073 units = "meters" 5074 if(country === "US") units = "feet" 5075 jQuery("#io_measurement_input_label").text("Approximate perimeter in "+units+": "); 5076 jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate perimeter in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>") 5077 5078 } 5079 5080 jQuery("#io_map_manual_input").off("click"); 5081 jQuery("#io_map_manual_input").bind("click", function(){manual_calc_price("Perimeter", item_page)}); 5082 jQuery("#perimeter_height").bind("change", function(){change_perimeter_instructions()}); 5083 jQuery("#io_perimeter_options_container").show(); 5084 jQuery("#io_map_clear_container").show(); 5085 jQuery("#io_map_new_line_container").show(); 5086 5087 current_polyline = new google.maps.Polyline({ 5088 map: map, 5089 path: [], 5090 strokeColor: "#0113fc", 5091 strokeOpacity: 1.0, 5092 strokeWeight: 2 5093 }) 5094 drawingListener = google.maps.event.addListener(drawingManager, "markercomplete", function(marker) { 5095 polyline_markers.push(marker) 5096 marker.setVisible(false); 5097 current_polyline.getPath().push(marker.getPosition()) 5098 if(previous_marker){ 5099 let convert_feet = 1; 5100 if(country === "US") convert_feet = 3.281; 5101 let approx_perimeter = 0; 5102 polylines.forEach(function(polyline) { 5103 if(convert_feet > 1) convert_feet = 10.764 5104 approx_perimeter += google.maps.geometry.spherical.computeArea(polyline.getPath()) * convert_feet; 5105 }); 5106 approx_perimeter += google.maps.geometry.spherical.computeLength(current_polyline.getPath()) * convert_feet; 5107 calcprice_approx_perimeter(Math.round(approx_perimeter)); 5108 } 5109 previous_marker = marker; 5110 }); 5111 5112 jQuery("#perimeter_height_contianer").show(); 5113
5114 drawingManager.setMap(map); 5115 } 5116 5117 function change_perimeter_instructions(){ 5118 let height = jQuery("#perimeter_height").val(); 5119 if(height){ 5120 units = "sq meters" 5121 if(country === "US") units = "sq feet" 5122 jQuery("#io_measurement_input_label").text("Approximate surface area in "+units+": "); 5123 jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate surface area in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>") 5124 }else { 5125 units = "meters" 5126 if(country === "US") units = "feet" 5127 jQuery("#io_measurement_input_label").text("Approximate perimeter in "+units+": "); 5128 jQuery("#io_map_instructions").html("Use the map below to take measurements by clicking on each corner of the area you want to measure. <span id=\"io_map_additional_instructions\">You can add additional lines by clicking Add New Line button to include more structures into the total. Press Clear to remove all lines and start again. Alternatively if you know the approximate perimeter in "+units+" you can enter the measurement manually below. When finished press Done and the price of the item will be updated </span><i id=\"io_show_more_instructions\" onClick=\"show_more_instruct_click(this)\">(more)</i>") 5129 } 5130 } 5131 5132 function manual_calc_price(method, item_page){ 5133 let approx_measurement = parseInt(jQuery("#io_measurement_input").val()); 5134 let units = ""; 5135 if(approx_measurement){ 5136 if(method == "Area"){ 5137 units = "sq meters" 5138 if(country === "US") units = "sq feet" 5139 }else if(method == "Perimeter"){ 5140 let height = jQuery("#perimeter_height").val(); 5141 if(height){ 5142 units = "sq meters" 5143 if(country === "US") units = "sq feet" 5144 }else{ 5145 units = "meters" 5146 if(country === "US") units = "feet" 5147 } 5148 }
5149 simpleCart.items().forEach(function (item, index){ 5150 if(item.get("rentalid") === item_id_map){ 5151 item.set("units", units); 5152 item.set("quantity", approx_measurement); 5153 } 5154 }); 5155 5156 simpleCart.update(); 5157 5158 if(item_page || jQuery(".io_product_infobox .item_rentalid").text() == item_id_map) set_price_on_item_page(units, approx_measurement); 5159 if(!item_page) cartShow(); 5160 } 5161 jQuery.fancybox.close(); 5162 } 5163 5164 function calcprice_approx_area(approx_area){ 5165 jQuery("#io_measurement_input").val(approx_area); 5166 } 5167 5168 function calcprice_approx_perimeter(approx_perimeter){ 5169 let height = jQuery("#perimeter_height").val(); 5170 if(height && height > 0) approx_perimeter *= parseInt(height); 5171 5172 jQuery("#io_measurement_input").val(approx_perimeter); 5173 } 5174 5175 function set_price_on_item_page(units, measurement){ 5176 let measurement_price = document.querySelector(".io_product_measurement_price"); 5177 if(measurement_price==undefined){ 5178 var first_price = document.querySelector(".io_product_price_box"); 5179 if(first_price != null){ 5180 measurement_price = first_price.cloneNode(true); 5181 /* clear all classes */ 5182 measurement_price.className = ""; 5183 measurement_price.classList.add("io_product_price_box"); 5184 measurement_price.classList.add("io_product_measurement_price"); 5185 measurement_price.style.display = "grid"; 5186 /* Make a hidden data span for when adding to cart */ 5187 raw_measurement = document.createElement("span"); 5188 raw_measurement.classList.add("io_measure_price_raw_measurement"); 5189 raw_measurement.style.display = "none"; 5190 raw_measurement.textContent = measurement; 5191 measurement_price.appendChild(raw_measurement); 5192 first_price.before(measurement_price); 5193 } 5194 } 5195 var price_1h = Number(jQuery(".io_product_price_1h_"+jQuery(".io_product_infobox .item_rentalid").text()).text().replace(/[^0-9.-]+/g,"")); 5196 measurement_price.querySelector("p:nth-child(1)").innerHTML = simpleCart.toCurrency(price_1h*measurement); 5197 measurement_price.querySelector("p:nth-child(2)").innerHTML = "For approximately "+measurement+" "+units; 5198 } 5199 5200 function io_map_clear() { 5201 if(drawingManager.getDrawingMode() == "polygon"){ 5202 drawingManager.setDrawingMode("polygon"); 5203 } 5204 5205 if(polygons) polygons.forEach(function(polygon) { 5206 polygon.setMap(null); 5207 }); 5208 if(current_polyline) current_polyline.setMap(null); 5209 if(polylines) polylines.forEach(function(polyline) { 5210 polyline.setMap(null); 5211 }); 5212 if(polyline_markers) polyline_markers.forEach(function(marker) { 5213 marker.setMap(null); 5214 }); 5215 5216 current_polyline = new google.maps.Polyline({ 5217 map: map, 5218 path: [], 5219 strokeColor: "#0113fc", 5220 strokeOpacity: 1.0, 5221 strokeWeight: 2 5222 }); 5223 polygons = new Array(); 5224 polylines = new Array(); 5225 polyline_markers = new Array(); 5226 previous_marker = undefined; 5227 } 5228 5229 function io_map_new_line() { 5230 polylines.push(new google.maps.Polyline({ 5231 map: map, 5232 path: current_polyline.getPath(), 5233 strokeColor: "#0113fc", 5234 strokeOpacity: 1.0, 5235 strokeWeight: 2 5236 }) 5237 ); 5238 previous_marker = undefined; 5239 current_polyline.setMap(null); 5240 current_polyline = new google.maps.Polyline({ 5241 map: map, 5242 path: [], 5243 strokeColor: "#0113fc", 5244 strokeOpacity: 1.0, 5245 strokeWeight: 2 5246 }); 5247 } 5248 5249 function show_more_instruct_click(show_more_button) { 5250 if(show_more_button.textContent == "(more)") { 5251 show_more_button.textContent = "(hide)"; 5252 jQuery("#io_map_additional_instructions").show(); 5253 }else if(show_more_button.textContent == "(hide)") { 5254 show_more_button.textContent = "(more)"; 5255 jQuery("#io_map_additional_instructions").hide(); 5256 } 5257 } 5258 5259 function perimeter_height_changed(){ 5260 let current_map_height = jQuery("#perimeter_height").val(); 5261 if(current_map_height && current_map_height > 0){ 5262 if(jQuery("#io_measurement_input").val() && !previous_map_height){ 5263 let measurement = jQuery("#io_measurement_input").val(); 5264 jQuery("#io_measurement_input").val(measurement * current_map_height); 5265 }else if(jQuery("#io_measurement_input").val() && previous_map_height){ 5266 let measurement = jQuery("#io_measurement_input").val(); 5267 if(previous_map_height > 0){ 5268 measurement = measurement / previous_map_height; 5269 } 5270 jQuery("#io_measurement_input").val(measurement * current_map_height); 5271 } 5272 }else if (!current_map_height || current_map_height == 0){ 5273 if(jQuery("#io_measurement_input").val() && previous_map_height){ 5274 let measurement = jQuery("#io_measurement_input").val(); 5275 if(previous_map_height > 0){ 5276 measurement = measurement / previous_map_height; 5277 } 5278 jQuery("#io_measurement_input").val(measurement); 5279 } 5280 } 5281 previous_map_height = current_map_height; 5282 } 5283 5284 window.initMap = initMap;</script>
5284 <div class="map_fancybox"><div class="elementor-widget-text-editor"><div> <details id="io_map_address_entry"> <summary style = "cursor:pointer">Enter Address Information (edit)</summary><table style="margin-left: 10px"><tr><td> <label for="address" id="io_mcl_address_label" style="display: table-cell"> Street Address </label></td><td> <input id="io_mc_address" style="display: table-cell" name="address" type="text"></input></td></tr><tr><td> <label for="city" id="io_mcl_city_label" style="display: table-cell"> City </label></td><td> <input id="io_mc_city" style="display: table-cell" name="city" type="text"></input></td></tr><tr id="io_mc_us-state-select"><td> <label for="state" id="io_mcl_state_label" style="display: table-cell"> State </label></td><td> <select name="state" id="io_mc_state" style="display: table-cell" class="input-mini"><option value=""></option><option value="AK">AK</option><option value="AL">AL</option><option value="AR">AR</option><option value="AZ">AZ</option><option value="CA">CA</option><option value="CO">CO</option><option value="CT">CT</option><option value="DC">DC</option><option value="DE">DE</option><option value="FL">FL</option><option value="GA">GA</option><option value="HI">HI</option><option value="IA">IA</option><option value="ID">ID</option><option value="IL">IL</option><option value="IN">IN</option><option value="KS">KS</option><option value="KY">KY</option><option value="LA">LA</option><option value="MA">MA</option><option value="MD">MD</option><option value="ME">ME</option><option value="MI">MI</option><option value="MN">MN</option><option value="MO">MO</option><option value="MS">MS</option><option value="MT">MT</option><option value="NC">NC</option><option value="ND">ND</option><option value="NE">NE</option><option value="NH">NH</option><option value="NJ">NJ</option><option value="NM">NM</option><option value="NV">NV</option><option value="NY">NY</option><option value="OH">OH</option><option value="OK">OK</option><option value="OR">OR</option><option value="PA">PA</option><option value="RI">RI</option><option value="SC">SC</option><option value="SD">SD</option><option value="TN">TN</option><option value="TX">TX</option><option value="UT">UT</option><option value="VA">VA</option><option value="VT">VT</option><option value="WA">WA</option><option value="WI">WI</option><option value="WV">WV</option><option value="WY">WY</option> </select></td></tr><tr><td> <label for="zip" id="io_mcl_zip_label" style="display: table-cell"> Zip Code </label></td><td> <input id="io_mc_zip" style="display: table-cell" name="zip" type="text"></input></td></tr></table> <a class="elementor-button elementor-size-sm io_button" 5285 id="map_geocode_submit" 5286 onClick="io_geocode()" 5287 href="javascript:;"> Locate </a> </details><div id="perimeter_height_contianer"><p>If you are taking measurements for a structure such as a building or fence, please provide the height of the structure here. If height does not apply to the wash, for instance for a gutter wash, leave this field empty. <strong> Please note if you enter a value here after taking measurements, you will need to take measurements again. </strong></p> <label> Height of structure: </label> <input type="number" id="perimeter_height" onChange="perimeter_height_changed()"/></div><div><p id="io_map_instructions"></p></div><div id="io_measurement_input_container"> <label id="io_measurement_input_label"> </label> <input type="number" id="io_measurement_input"/> <a class="elementor-button elementor-size-sm io_button" 5288 id="io_map_manual_input" 5289 href="javascript:;"> Done </a></div><div style="display: inline-flex"><div id="io_map_clear_container"> <a class="elementor-button elementor-size-sm io_button" 5290 id="io_map_clear_btn" 5291 onClick="io_map_clear()" 5292 href="javascript:;"> Clear </a></div><div id="io_map_new_line_container" style="margin-left:5px"> <a class="elementor-button elementor-size-sm io_button" 5293 id="io_map_new_line_btn" 5294 onClick="io_map_new_line()" 5295 href="javascript:;"> Add New Line </a></div></div></div></div> <br><div id="map_container">
5295<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDEuvvqefKaUABPvydm00SV8Fr8tQeGVcw&libraries=drawing&callback=initMap" defer></script>
5295 </div></div>
5295<script>jQuery(".io_testimonials, #io_testimonials").each(function(){ 5296 io_get_reviews(this); 5297 }) 5298 setTimeout(function(){ 5299 jQuery(".io_testimonials .w3-ul li p").each(function(){ 5300 const container = jQuery(this).parent() 5301 const element = jQuery(this); 5302 5303 if (element[0].scrollHeight > container[0].clientHeight) { 5304 5305 jQuery(this).parent().parent().append(create_read_more()); 5306 } 5307 }); 5308 }, 500); 5309 5310 function create_read_more(){ 5311 let html = "<p class=\"io_review_readmore\" onClick=\"review_readmore_clicked(this)\">read more</p>" 5312 return html; 5313 } 5314 5315 function review_readmore_clicked(element){ 5316 let review_li = jQuery(element).parent().find("li:eq(3)"); 5317 new_height = jQuery(review_li).find("p").height() + 16; 5318 jQuery(review_li).height(new_height); 5319 jQuery(element).hide(); 5320 } 5321 5322 function io_get_reviews(element){ 5323 let io_un = "watsonanthony96"; 5324 let io_loc = "0"; 5325 let io_url1 = 'https://rental.software/testimonials_iframe.php?user='; 5326 if (location.hostname === "localhost"){ 5327 io_url1 = 'http://localhost/io/bugs/testimonials_iframe.php?user='; 5328 //io_url1 = 'http://localhost/jbug/trunk/testimonials_iframe.php?user='; 5329 } 5330 let io_url2 = '&location_id='; 5331 let io_url3 = '&width=100%&number_of_reviews=10&show_average_rating=1&show_stars=1&show_date=&show_reviewer_name=1&orderby=time&iframe=0'; 5332 let io_url_c = io_url1 + io_un + io_url2 + io_loc + io_url3; 5333 fetch(io_url_c, { 5334 method: 'get' 5335 }).then( 5336 function(response){ 5337 return response.json(); 5338 } 5339 ).then(function(data) { 5340 5341 5342 5343 //let element = document.getElementById("io_testimonials"); 5344 //DOM-built on purpose: literal markup in this inline script lands in the raw page 5345 //source and SEO crawlers read it as page content (IO-37932). 5346 element.textContent = ""; 5347 let review_cnt=0; 5348 let rating_sum = 0; 5349 data.forEach((user) => { 5350 const { name, review, rating, time } = user; 5351 rating_sum += Number(rating); 5352 review_cnt++; 5353 let review_div = document.createElement("div"); 5354 let review_list = document.createElement("ul"); 5355 review_list.className = "w3-ul"; 5356 let name_li = document.createElement("li"); 5357 name_li.textContent = name; 5358 let rating_li = document.createElement("li"); 5359 rating_li.textContent = rating + " "; 5360 let date_li = document.createElement("li"); 5361 date_li.textContent = time; 5362 let review_li = document.createElement("li"); 5363 let review_p = document.createElement("p"); 5364 review_p.textContent = review; 5365 review_li.appendChild(review_p); 5366 let img_star = Math.round(parseFloat(rating)); 5367 let star_img = document.createElement("img"); 5368 star_img.className = "review_img"; 5369 star_img.src = "https://rental.software/images/" + img_star + "star.png"; 5370 rating_li.appendChild(star_img); 5371 review_list.appendChild(name_li); 5372 review_list.appendChild(rating_li); 5373 review_list.appendChild(date_li); 5374 review_list.appendChild(review_li); 5375 review_div.appendChild(review_list); 5376 element.appendChild(review_div); 5377 }); 5378 let avg = (parseFloat(rating_sum)/parseFloat(review_cnt)).toFixed(1); 5379 let avg_img = Math.round(avg); 5380 let head = document.createElement("div"); 5381 let head_h2 = document.createElement("h2"); 5382 head_h2.textContent = "Avg Rating: " + avg; 5383 let head_img = document.createElement("img"); 5384 head_img.className = "review_avg_img"; 5385 head_img.src = "https://rental.software/images/" + avg_img + "star.png"; 5386 head.appendChild(head_h2); 5387 head.appendChild(head_img); 5388 element.prepend(head); 5389 }).catch(function(err) { 5390 console.log(err); 5391 }); 5392}</script>
5392 <style type="text/css">.searchio-live-search-results { 5393 opacity: 0; 5394 transition: opacity .25s ease-in-out; 5395 -moz-transition: opacity .25s ease-in-out; 5396 -webkit-transition: opacity .25s ease-in-out; 5397 height: 0; 5398 overflow: hidden; 5399 z-index: 9999995; /* Exceed searchIO Modal Search Form overlay. */ 5400 position: absolute; 5401 display: none; 5402 } 5403 5404 .searchio-live-search-results-showing { 5405 display: block; 5406 opacity: 1; 5407 height: auto; 5408 overflow: auto; 5409 } 5410 5411 .searchio-live-search-no-results { 5412 padding: 3em 2em 0; 5413 text-align: center; 5414 } 5415 5416 .searchio-live-search-no-min-chars:after { 5417 content: "Continue typing"; 5418 display: block; 5419 text-align: center; 5420 padding: 2em 2em 0; 5421 }</style>
5421<script>var _searchIO_LIVE_AJAX_SEARCH_BLOCKS = true; 5422 var _searchIO_LIVE_AJAX_SEARCH_ENGINE = 'default'; 5423 var _searchIO_LIVE_AJAX_SEARCH_CONFIG = 'default';</script>
5423
5423<script>( () => { 5424 const lazyloadRunObserver = () => { 5425 const lazyloadBackgrounds = document.querySelectorAll( `.e-con.e-parent:not(.e-lazyloaded)` ); 5426 const lazyloadBackgroundObserver = new IntersectionObserver( ( entries ) => { 5427 entries.forEach( ( entry ) => { 5428 if ( entry.isIntersecting ) { 5429 let lazyloadBackground = entry.target; 5430 if( lazyloadBackground ) { 5431 lazyloadBackground.classList.add( 'e-lazyloaded' ); 5432 } 5433 lazyloadBackgroundObserver.unobserve( entry.target ); 5434 } 5435 }); 5436 }, { rootMargin: '200px 0px 200px 0px' } ); 5437 lazyloadBackgrounds.forEach( ( lazyloadBackground ) => { 5438 lazyloadBackgroundObserver.observe( lazyloadBackground ); 5439 } ); 5440 }; 5441 const events = [ 5442 'DOMContentLoaded', 5443 'elementor/lazyload/observe', 5444 ]; 5445 events.forEach( ( event ) => { 5446 document.addEventListener( event, lazyloadRunObserver ); 5447 } ); 5448 } )();</script>
5448
5448<script id="jquery-ui-core-js-before">jQuery.uiBackCompat = true; 5449//# sourceURL=jquery-ui-core-js-before</script>
5449
5449<script id="jquery-ui-datepicker-js-after">jQuery(function(jQuery){jQuery.datepicker.setDefaults({"closeText":"Close","currentText":"Today","monthNames":["January","February","March","April","May","June","July","August","September","October","November","December"],"monthNamesShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"nextText":"Next","prevText":"Previous","dayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dayNamesShort":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"dayNamesMin":["S","M","T","W","T","F","S"],"dateFormat":"MM d, yy","firstDay":1,"isRTL":false});}); 5450//# sourceURL=jquery-ui-datepicker-js-after</script>
5450
5450<script id="slick-carousel-js-js" src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js?ver=1.8.1"></script>
5450
5450<script id="elementor-frontend-js-before">var elementorFrontendConfig = {"environmentMode":{"edit":false,"wpPreview":false,"isScriptDebug":false},"i18n":{"shareOnFacebook":"Share on Facebook","shareOnX":"Share on X","pinIt":"Pin it","download":"Download","downloadImage":"Download image","fullscreen":"Fullscreen","zoom":"Zoom","share":"Share","playVideo":"Play Video","previous":"Previous","next":"Next","close":"Close","a11yCarouselPrevSlideMessage":"Previous slide","a11yCarouselNextSlideMessage":"Next slide","a11yCarouselFirstSlideMessage":"This is the first slide","a11yCarouselLastSlideMessage":"This is the last slide","a11yCarouselPaginationBulletMessage":"Go to slide"},"is_rtl":false,"breakpoints":{"xs":0,"sm":480,"md":768,"lg":1025,"xl":1440,"xxl":1600},"responsive":{"breakpoints":{"mobile":{"label":"Mobile Portrait","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobile Landscape","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Portrait","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Landscape","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Widescreen","value":2400,"default_value":2400,"direction":"min","is_enabled":false}},"hasCustomBreakpoints":false},"version":"4.3.4","is_static":false,"experimentalFeatures":{"additional_custom_breakpoints":true,"theme_builder_v2":true,"import-export-customization":true,"e_pro_atomic_form":true,"e_pro_collection_loop":true},"urls":{"assets":"https:\/\/goodtimesnj.com\/wp-content\/plugins\/elementor\/assets\/","ajaxurl":"https:\/\/goodtimesnj.com\/wp-admin\/admin-ajax.php","uploadUrl":"https:\/\/goodtimesnj.com\/wp-content\/uploads"},"nonces":{"floatingButtonsClickTracking":"f1906d774d","atomicFormsSendForm":"4bb18e0f80"},"swiperClass":"swiper","settings":{"page":[],"editorPreferences":[]},"kit":{"body_background_background":"classic","active_breakpoints":["viewport_mobile","viewport_tablet"],"lightbox_enable_counter":"yes","lightbox_enable_fullscreen":"yes","lightbox_enable_zoom":"yes","lightbox_enable_share":"yes","lightbox_title_src":"title","lightbox_description_src":"description"},"post":{"id":3288,"title":"Contact%20Us%20-%20Good%20Times%20Inflatables","excerpt":"","featuredImage":false}}; 5451//# sourceURL=elementor-frontend-js-before</script>
5451
5451<script id="swp-live-search-client-js-extra">var searchio_live_search_params = []; 5452searchio_live_search_params = {"ajaxurl":"https:\/\/goodtimesnj.com\/wp-admin\/admin-ajax.php","origin_id":3288,"config":{"default":{"engine":"default","input":{"delay":300,"min_chars":3},"results":{"position":"bottom","width":"auto","offset":{"x":0,"y":5}},"spinner":{"lines":12,"length":8,"width":3,"radius":8,"scale":1,"corners":1,"color":"#424242","fadeColor":"transparent","speed":1,"rotate":0,"animation":"searchio-spinner-line-fade-quick","direction":1,"zIndex":2000000000,"className":"spinner","top":"50%","left":"50%","shadow":"0 0 1px transparent","position":"absolute"}}},"msg_no_config_found":"No valid searchIO Live Search configuration found!","aria_instructions":"When autocomplete results are available use up and down arrows to review and enter to go to the desired page. Touch device users, explore by touch or with swipe gestures.","io_search_results_same_width":"1","io_search_results_width":"400","io_search_results_align":"right"};; 5453//# sourceURL=swp-live-search-client-js-extra</script>
vendor: 131 bytes, line 5453
5453 <script id="elementor-recaptcha_v3-api-js" src="https://www.google.com/recaptcha/api.js?render=explicit&ver=4.3.1"></script>
5453<script id="wp-hooks-js" src="https://goodtimesnj.com/wp-includes/js/dist/hooks.min.js?ver=f0f188028580e8dc1255"></script>
5453
5453<script id="wp-i18n-js" src="https://goodtimesnj.com/wp-includes/js/dist/i18n.min.js?ver=1dfe7db3940c23ea9216"></script>
5453
5453<script id="wp-i18n-js-after">wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } ); 5454//# sourceURL=wp-i18n-js-after</script>
5454
5454<script id="elementor-pro-frontend-js-before">var ElementorProFrontendConfig = {"ajaxurl":"https:\/\/goodtimesnj.com\/wp-admin\/admin-ajax.php","nonce":"a152ef9983","urls":{"assets":"https:\/\/goodtimesnj.com\/wp-content\/plugins\/elementor-pro\/assets\/","rest":"https:\/\/goodtimesnj.com\/wp-json\/"},"settings":{"lazy_load_background_images":true},"popup":{"hasPopUps":true},"shareButtonsNetworks":{"facebook":{"title":"Facebook","has_counter":true},"twitter":{"title":"Twitter"},"linkedin":{"title":"LinkedIn","has_counter":true},"pinterest":{"title":"Pinterest","has_counter":true},"reddit":{"title":"Reddit","has_counter":true},"vk":{"title":"VK","has_counter":true},"odnoklassniki":{"title":"OK","has_counter":true},"tumblr":{"title":"Tumblr"},"digg":{"title":"Digg"},"skype":{"title":"Skype"},"stumbleupon":{"title":"StumbleUpon","has_counter":true},"mix":{"title":"Mix"},"telegram":{"title":"Telegram"},"pocket":{"title":"Pocket","has_counter":true},"xing":{"title":"XING","has_counter":true},"whatsapp":{"title":"WhatsApp"},"email":{"title":"Email"},"print":{"title":"Print"},"x-twitter":{"title":"X"},"threads":{"title":"Threads"}},"facebook_sdk":{"lang":"en_US","app_id":""},"lottie":{"defaultAnimationUrl":"https:\/\/goodtimesnj.com\/wp-content\/plugins\/elementor-pro\/modules\/lottie\/assets\/animations\/default.json"}}; 5455//# sourceURL=elementor-pro-frontend-js-before</script>
5455
5455<script defer src="https://goodtimesnj.com/wp-content/cache/autoptimize/js/autoptimize_f1567e2c9752901a4b0911d67b046d36.js"></script>
5455</body></html> 5456<!-- Cached by WP-Optimize (gzip) - https://teamupdraft.com/wp-optimize/ - Last modified: October 6, 2026 1:12 pm (UTC:0) -->
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.