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