Every booking widget variant available in the Tourism Whistler design system, with live interactive demos, usage code, and full data attribute reference. All widgets POST to the live funnel at whistler.com/cart/.
require.js + all.min.<date>.jsmain.<date>.cssLitepicker range calendar_TWWIDGET.init() on DOM ready<div class="tw-widget"></div> anywhere in the page. _TWWIDGET.init() runs on $(document).ready() and replaces each element with the full widget HTML, then wires up date pickers, type-change logic, and search submission.
/cart/ funnel URL with all parameters appended..tw-widget.hero, .az, and .home widgets are hidden; a .mobile-placeholder is injected into .article with expand/collapse behaviour.dataLayer on every search. The digitalData global must be initialized before widget.js loads.Build a widget with the options below and render it for real — the same script that runs on the site. Search actually goes to the funnel. The URL updates as you go, so you can share a link that opens with these settings.
The standard sidebar widget. Shows Arrive/Depart dates + Adults + Children. Searches /cart/lodging-search/.
<!-- Minimal: lodging is the default type --> <div class="tw-widget"></div> <!-- Explicit with options --> <div class="tw-widget" data-type="lodging" data-adult="2" data-child="0" data-title="Book Your Stay"></div>
/cart/lodging-search/?arrivaldate=MM/DD/YYYY&departuredate=MM/DD/YYYY&adultcount=N&childcount=NShows an activity sub-category dropdown when data-list is present. Searches /cart/activity-search/.
<!-- With sub-category list --> <div class="tw-widget" data-type="activities" data-list></div> <!-- Pre-select a specific activity category --> <div class="tw-widget" data-type="activities" data-list data-productcategoryid="172"></div> <!-- 172 = Hiking -->
/cart/activity-search/?arrivaldate=...&productcategoryid=N"172|188".Replaces Adults/Children with a Players dropdown (1–4). Searches /cart/golf-search/.
<div class="tw-widget" data-type="golf" data-player="2"></div>
/cart/golf-search/?arrivaldate=...&quantity=NAdding data-simple hides the Depart date — useful for day-use products like lift tickets. Searches /cart/lift-search/.
<div class="tw-widget" data-type="lifts" data-simple></div> <!-- data-simple works on any type --> <div class="tw-widget" data-type="activities" data-simple data-list></div>
/cart/lift-search/?arrivaldate=...transfers, activities, rentals, lessons.
Shows Bus / Limousine / Scheduled Air sub-category. Searches /cart/transport-search/.
<div class="tw-widget" data-type="transfers" data-list></div>
/cart/transport-search/?arrivaldate=...&productcategoryid=N
Bike and ski/snowboard rentals. Searches /cart/rental-search/.
<div class="tw-widget" data-type="rentals" data-list></div>
Ski, snowboard, and bike lessons by age group. Searches /cart/lesson-search/.
<div class="tw-widget" data-type="lessons" data-list></div>
Using data-type="all" shows the full type dropdown. Changing the type updates the button label, shows/hides sub-selectors dynamically.
<div class="tw-widget" data-type="all" data-list></div>
data-title injects a heading above the widget fields. The footer variant also adds a phone number fallback.
<div class="tw-widget" data-type="lodging" data-title="Book Your Whistler Stay"></div> <!-- Footer variant adds phone fallback --> <div class="tw-widget foot" data-type="lodging" data-title="Plan Your Trip"></div> <!-- Custom phone number --> <div class="tw-widget" data-phone data-phone-num="1.800.944.7853"></div>
<h3> inside the widget bar.Dates can be pre-filled as a specific date or as +N days from today. The button label can be overridden.
<!-- +3 days arrival, +7 days departure --> <div class="tw-widget" data-type="lodging" data-arrival="3" data-departure="7" data-btn="Find a Room"></div> <!-- Specific date --> <div class="tw-widget" data-arrival="12/20/2025" data-departure="12/27/2025"></div> <!-- Constrain date range --> <div class="tw-widget" data-min="0" data-max="90"></div>
M/D/YYYY format, or a number (+N days from today)."0,6" disables weekends.The inline class creates a 100%-wide horizontal booking bar. Used within page content — typically on activity or accommodation landing pages.
<div class="tw-widget inline" data-type="lodging" data-title="Search Lodging"></div> <!-- Activities inline --> <div class="tw-widget inline" data-type="activities" data-list data-title="Book an Activity"></div>
Shows phone numbers only — no date picker, no search button. Used in the header bar when a booking funnel isn't appropriate. Hidden at ≤840px.
<!-- Default: shows 1.800.944.7853 --> <div class="tw-widget phone"></div> <!-- Custom phone numbers --> <div class="tw-widget phone" data-title="Reservations" data-phone-num="1.800.944.7853" data-phone-num-2="1.604.932.0606"></div>
data-title..article with expand/collapse toggle — ensure a <div class="article"> exists on the page.
An <a class="tw-widget-link"> reveals a booking widget on first click. The widget is injected after the link, keeping the page clean until needed.
Click a button below — the widget appears inline on first click.
<!-- Sidebar widget on click --> <a href="#" class="tw-widget-link button button--turquoise" data-type="lodging" data-galabel="Hero CTA"> Search Lodging </a> <!-- Inline (full-width) widget on click --> <a href="#" class="tw-widget-link inline button button--blue" data-type="activities" data-list> Book an Activity </a>
data-* attributes — type, title, adult, child, dates, etc.inline to the <a> to inject a full-width bar instead of a sidebar widget.dataLayer as custom_widget_type on search.
Add to the .tw-widget element to hide specific selectors.
<!-- Hide adults and children selectors --> <div class="tw-widget hide--adult hide--child" data-type="lodging"></div> <!-- Hide players (for non-golf where player is irrelevant) --> <div class="tw-widget hide--player" data-type="activities"></div>
These variants are page-context specific and require surrounding layout elements. Do not instantiate them standalone.
<div class="hero hero--text"> <div class="hero__overlay"> <div class="tw-widget hero" data-type="lodging" data-title="Plan Your Trip"></div> </div> <img class="header-image" src="..." alt="..."> </div> <!-- JS auto-creates a .mobile-placeholder in .article for ≤840px -->
<div class="hero"> <div class="tw-widget home" data-type="lodging" data-title="Plan Your Trip"></div> <img class="header-image" src="..." alt="..."> </div> <!-- Renders as 920px-wide absolute bar pinned to bottom of hero --> <!-- Also needs: .article exists, .openMobile for expand/collapse -->
<div class="tw-widget widget--rewards"> <!-- Inner HTML is preserved and wrapped in widget chrome --> <p>Join Whistler Rewards and earn points on every stay.</p> <input type="email" placeholder="Your email"> <input type="submit" value="Join Now"> </div>
<div class="tw-widget custom" data-title="Special Offer"> <!-- Any HTML — gets wrapped in widget-new / tw-widget-headbar --> <p>Free $100 Activity Voucher with 3+ night stay.</p> <a href="/deals/" class="button button--yellow">View Deals</a> </div> <!-- Also needs: .article exists on page -->
| Attribute | Values | Effect | Applies to |
|---|---|---|---|
| data-type | lodging lifts transfers activities rentals golf lessons all vacation |
Pre-selects booking type, sets search URL, shows/hides selectors | All widgets |
| data-title | Any string | Adds <h3> heading inside widget bar |
All widgets |
| data-list | Present (any value or empty) | Shows sub-category dropdown for activities/transfers/rentals/lessons | Standard, hero, az, home, inline |
| data-adult | 1–9 | Pre-selects adult count | Standard, hero, az, home, inline |
| data-child | 0–9 | Pre-selects children count | Standard, hero, az, home, inline |
| data-player | 1–4 | Pre-selects players count (golf) | Standard, hero, az, home, inline |
| data-simple | Present (any value or empty) | Hides Depart date — single-date mode | All widgets |
| data-arrival | M/D/YYYY or +N days |
Pre-fills Arrive date picker | All widgets |
| data-departure | M/D/YYYY or +N days |
Pre-fills Depart date picker | All widgets |
| data-min | M/D/YYYY or +N days |
Minimum selectable date on both pickers | All widgets |
| data-max | M/D/YYYY or +N days |
Maximum selectable date on both pickers | All widgets |
| data-disable | Comma-separated day numbers 0–6 |
Disables specific days of week (0=Sun, 6=Sat) | All widgets |
| data-btn | Any string | Overrides the search button label | All widgets |
| data-phone | Present (any value or empty) | Shows "or call 1.800.944.7853" below search button | Standard, inline |
| data-phone-num | Formatted number e.g. 1.800.944.7853 |
Overrides primary phone number text + href | Standard, phone widget |
| data-phone-num-2 | Formatted number | Overrides international number text + href | Standard, phone widget |
| data-style | CSS string e.g. background:#e42b5d |
Applies inline CSS to widget bar element | All widgets |
| data-url | Domain string e.g. www.whistler.com |
Overrides the base domain for the search URL | All widgets |
| data-productcategoryid | Pipe-separated IDs e.g. 172|188 |
Pre-selects and appends product category to funnel URL | All widgets |
| data-galabel | Any string | Pushed to dataLayer as custom_widget_type on search |
All widgets, tw-widget-link |
| data-salesid | Inntopia sales ID | Appended to funnel URL as &salesid=N |
All widgets |
| data-packageid | Package ID | Appended to funnel URL | All widgets |
| data-supplierid | Supplier ID | Appended to funnel URL | All widgets |
| data-locationid | Location ID | Appended to funnel URL | All widgets |
| data-productid | Product ID | Appended to funnel URL | All widgets |
| data-preferred | Any | Appended to funnel URL as &preferred=... |
All widgets |
| data-sortcode | Any | Appended to funnel URL | All widgets |
| data-group | Any | Appended to funnel URL | All widgets |
| data-type | Funnel URL | Key params |
|---|---|---|
| lodging | /cart/lodging-search/ | arrivaldate, departuredate, adultcount, childcount |
| lifts | /cart/lift-search/ | arrivaldate |
| transfers | /cart/transport-search/ | arrivaldate, departuredate, productcategoryid |
| activities | /cart/activity-search/ | arrivaldate, departuredate, productcategoryid |
| rentals | /cart/rental-search/ | arrivaldate, departuredate, productcategoryid |
| golf | /cart/golf-search/ | arrivaldate, departuredate, quantity (players) |
| lessons | /cart/lesson-search/ | arrivaldate, departuredate, productcategoryid |
| vacation | /vrbo/search/ | arrivaldate, departuredate, adultcount (max 6) |
| all | Reads type dropdown on submit | Dynamic based on selected type |
| Class | Width | Visible at mobile? | Notes |
|---|---|---|---|
| .tw-widget | 310px | Yes | Default sidebar widget |
| .tw-widget.hero | 340px panel | No (hidden ≤840px) | Inside .hero__overlay, blue-teal gradient bg |
| .tw-widget.az | Side panel | No (hidden ≤840px) | A-Z accommodation listing, appends mobile widget |
| .tw-widget.home | 920px horizontal | No (hidden ≤840px) | Absolute bar at hero bottom, auto-creates mobile widget |
| .tw-widget.inline | 100% | Yes | Full-width horizontal bar, blue-teal gradient |
| .tw-widget.tile | 100% | Stacks below image | Pinned to bottom of .tile, triggered via tw-widget-link |
| .tw-widget.phone | Full-width bar | No (hidden ≤840px) | Phone numbers only, no date picker |
| .tw-widget.widget--rewards | 330px | Yes | Email capture, preserves inner HTML |
| .tw-widget.custom | Full-width bar | Yes (mobile-placeholder) | Wraps any inner HTML in widget chrome |
| .tw-widget.foot | — | — | Footer strip — adds "or call" phone fallback to title area |
| .tw-widget.hide--adult | — | — | Hides adults dropdown (modifier, combine with any) |
| .tw-widget.hide--child | — | — | Hides children dropdown (modifier) |
| .tw-widget.hide--player | — | — | Hides players dropdown (modifier) |
| .tw-widget-bar-mobile | 100% | Only (hidden >916px) | Auto-generated by JS, not manually placed |
These IDs are used with data-productcategoryid when data-type="activities". Pipe-separate for multiple: data-productcategoryid="172|188".
10112112212312412512612712913914014114214314414515115215316016116216316416516716816917017217317417517617717818418518618718819619819920020620720810071008100910101011101210131015101610181028104110481079108010831100111011131164116511661167117511761178119211931195119612121251125212531268127112721335