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