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