HAPI Sample - Scheduler - Sample Code for Multiple Slot Selection

Check out the sample code from our live page for booking rooms.


CSS

    <link href="/plugins/slick/slick.css" rel="stylesheet" />
    <link href="/plugins/slick/slick-theme.css" rel="stylesheet" />
    <style>
        @media(max-width: 480px) {
            .ui-update .max-scheduler-width {
                max-width: 100px;
                overflow: hidden;
            }
        }

        .ui-update .th_time {
            font-size: 10px;
        }

        .ui-update .bookedBlock {
            width: 60px;
            overflow: hidden;
            font-size: 9px;
            max-height: 24px;
            height: 24px;
            padding: 0px;
        }

        .ui-update .timeSlot.notavailable, .ui-update .timeSlot.notavailable:hover {
            background-color: #888888;
            cursor: not-allowed;
        }

        ::-webkit-scrollbar-thumb {
            background-color: rgba(0,0,0,.24);
        }

        ::-webkit-scrollbar {
            -webkit-appearance: inherit;
            width: 8px;
        }

        .ui-update .wrapper {
            padding-top: 1em;
            padding-bottom: 1em;
        }

        .ui-update .portal-bg {
            background-color: #FFF;
        }

        .ui-update .days,
        .ui-update .timeTableWrapper {
            position: relative;
            width: 100%;
            height: 100%;
            display: inline-block;
        }

        .ui-update .input_inline {
            display: inline-block;
            width: auto;
        }

        .ui-update .input_inline {
            width: 40%;
        }

        #timeSelect .txt {
            margin: 0 8px;
        }

        #timeSelect h5,
        #locationSelect h5 {
            display: block;
        }

        .ui-update .days table {
            border-collapse: separate;
            border-spacing: 0.5em;
        }

        .ui-update .days td {
            background-color: #fff;
            padding: 8px;
            cursor: pointer;
            padding: 0.5em 1em;
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
        }

            .ui-update .days td * {
                display: block;
                text-align: center;
            }

            .ui-update .days td.selected {
                box-shadow: 0 0 5px #77A331;
                z-index: 5;
            }

                .ui-update .days td.selected .hdg,
                .ui-update .days td.selected .hdg_1,
                .ui-update .days td.selected .hdg_6,
                .ui-update .days td.selected .txt,
                .ui-update .days td.selected .txt_minuscule {
                    color: #77A331;
                }

        .ui-update .times,
        .ui-update .bookSlot {
            display: none;
        }

        .ui-update .timeTableWrapper table {
            float: left;
        }

        .ui-update th {
            padding: 5px;
            height: 35px;
        }

        .ui-update td {
            padding: 5px;
            margin: 0;
            white-space: nowrap;
        }

        .ui-update .timeTableWrapper .right,
        .ui-update .days .scheduleDaysWrapper {
            overflow: auto;
        }

        .ui-update th {
            text-align: center;
        }

        .ui-update .headCol th,
        .ui-update .headCol td {
            padding-right: 10px;
        }

        .ui-update .headCol tr {
            height: 35px;
            border-right: 1px solid #f0f0f0;
            border-bottom: 1px solid #f0f0f0;
        }

        .ui-update .timeSlot {
            text-align: center;
            border: 1px solid #EEEEEE;
            cursor: pointer;
            transition: 150ms all ease-in-out;
            -webkit-touch-callout: none;
            -webkit-user-select: none;
            -khtml-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            white-space: nowrap;
            min-width: 75px;
            height: 35px;
        }

            .ui-update .timeSlot:hover {
                background-color: #fbfbfb;
            }

        .ui-update .booked {
            background-color: #FEEEEB;
            border-color: #FEEEEB;
            cursor: not-allowed;
        }

            .ui-update .booked:hover {
                background-color: #FEEEEB;
                border-color: #FEEEEB;
                cursor: not-allowed;
            }

        .ui-update .blocked {
            background-color: #eefeeb;
            border-color: #eefeeb;
            cursor: not-allowed;
        }

            .ui-update .blocked:hover {
                background-color: #eefeeb;
                border-color: #eefeeb;
                cursor: not-allowed;
            }

        .ui-update .times table .selected {
            background-color: #c2d631;
            border-color: #c2d631;
        }

            .ui-update .times table .selected:hover {
                background-color: #c2d631;
            }
    </style>

HTML
(please note this is currently in ASP.NET but you can replace all with HAPI)

            <section class="component">
                <div class="component-content">

                    <div class="split split_alignBtm split_collapseOnMobile">
                        <h2 class="hdg hdg_4">Make a Reservation <%if scheduleItems.Count = 1 %>for <%=scheduleItems.Item(0).schedule_item %><%end if %></h2>
                        <!--#include file="/include/includeLoginUpdate.aspx"-->
                    </div>
                    <%if scheduleItems.Count = 1 Then %>
                    <%=scheduleItems(0).schedule_item_description %>
                    <% End if %>
                </div>
            </section>
            <section class="component">
                <div class="component-content">
                    <div class="box mix-box_outlined">
                        <div class="box-bd box-bd_inflated vr vr_x28">
                            <asp:PlaceHolder runat="server" ID="pnlSlots" Visible="false">
                                <h2 class="hdg hdg_6 mix-hdg_dark vr-override_x6">Select a Date</h2>
                                <ul id="dateSlider" class="scheduleDays">
                                    <% Dim availSlots As Integer = 0 %>
                                    <% for i As Integer = 0 To DateDiff(DateInterval.Day, from_date, to_date) %>
                                    <% availSlots = slots.FindAll(Function(x) x.slot_start >= Convert.ToDateTime(String.Format("{0:d}", from_date.AddDays(i)) & " 12:00 AM") And x.slot_end <= Convert.ToDateTime(String.Format("{0:d}", from_date.AddDays(i)) & " 11:59 PM") And x.isAvailable).Count %>
                                    <li id="<%=String.Format("{0:MMddyyyy}", from_date.AddDays(i)) %>" data-fulldate="<%=String.Format("{0:MMMM dd yyyy}", from_date.AddDays(i)) %>">
                                        <button class="cardBtn">
                                            <span class="cardBtn-bd">
                                                <span class="cardBtn-txt cardBtn-txt_label">
                                                    <span><%=from_date.AddDays(i).ToString("dddd") %></span><br />
                                                    <span><%=MonthName(Month(from_date.AddDays(i))) %></span>
                                                    <span><%=Year(from_date.AddDays(i)) %></span>
                                                </span>
                                                <span class="cardBtn-txt cardBtn-txt_digit"><%=Day(from_date.AddDays(i)) %></span>
                                            </span>
                                            <span class="cardBtn-ft cardBtn-ft_alignRight">
                                                <span class="cardBtn-txt">
                                                    <span data-pv-element="total_slots"><%=IIf(availSlots = 0, "No", availSlots) %></span> spot<%=People_Vine___Portal.functions.returnPlural(availSlots) %> available
                                                </span>
                                            </span>
                                        </button>
                                    </li>
                                    <% next %>
                                </ul>
                                <div class="times vr vr_x8">
                                    <!-- Populate each day of slots, using the data-for to populate the day so that when you click on a day above, it opens the correct slots-->
                                    <h2 class="hdg hdg_6 mix-hdg_dark vr-override_x3">Make Selection: <em id="selectDate"></em></h2>
                                    <div id="timeTable">
                                    </div>
                                    <% for i As Integer = 0 To DateDiff(DateInterval.Day, from_date, to_date) %>
                                    <% curDate = from_date.AddDays(i) %>
                                    <div data-for="<%=String.Format("{0:MMddyyyy}", curDate) %>" class="slotList" style="display: none;">
                                        <!-- Populates date MMMMddyyyy-->

                                        <div class="timeTableWrapper">
                                            <div class="headCol">
                                                <table>
                                                    <thead>
                                                        <th class="txt mix-txt_bold">Reserving</th>
                                                    </thead>
                                                    <tbody>
                                                        <!-- Each room gets populated as a separated row to allow the "scroll over" effect-->
                                                        <% For each si As People_Vine___Portal.api.scheduler.wi_schedule_item In scheduleItems %>
                                                        <tr>
                                                            <td class="txt mix-txt_bold max-scheduler-width">
                                                                <%=si.schedule_item %>
                                                                <%--<% If si.category_no > 0 Then %>
                                                                <br /><span class="label label-info"><%=si.category_name %></span>
                                                                <% end if %>--%>
                                                            </td>
                                                        </tr>
                                                        <% next %>
                                                    </tbody>
                                                </table>
                                            </div>
                                            <div class="right">
                                                <table>
                                                    <thead>
                                                        <!-- All times in the series get populated here as headers-->
                                                        <% tempEarliestTime = earliestTime %>
                                                        <% While tempEarliestTime < latestTime %>
                                                        <th class="th_time" id="<%=String.Format("{0:t}", tempEarliestTime) %>"><%=String.Format("{0:t}", tempEarliestTime) %></th>
                                                        <% tempEarliestTime = tempEarliestTime.AddMinutes(incrementMinutes) %>
                                                        <% end while %>
                                                    </thead>
                                                    <tbody>
                                                        <!-- Each room gets it's own row, and if booked, add class 'booked' to it-->
                                                        <!-- Start date can be in any format becauase it is not rendered on the page-->
                                                        <!-- startTime & endTime need to be in hh:mm because they get updated to the page -->
                                                        <% For each sc As People_Vine___Portal.api.scheduler.wi_schedule_item In scheduleItems %>
                                                        <tr data-room="<%=sc.schedule_item %>">
                                                            <!-- Need to loop through all slots and then if exists put block -->
                                                            <% tempEarliestTime = earliestTime %>
                                                            <% While tempEarliestTime < latestTime %>
                                                            <% curDate = Convert.ToDateTime(String.Format("{0:d}", curDate) & " " & String.Format("{0:t}", tempEarliestTime)) %>
                                                            <% slot = slots.Find(Function(x) x.slot_start >= curDate And x.slot_end <= curDate.AddMinutes(sc.block_duration) And x.schedule_item_no = sc.schedule_item_no) %>
                                                            <% if slot Is Nothing Then %>
                                                            <td class="timeSlot notavailable booked">&nbsp;</td>
                                                            <% else %>
                                                            <td data-fee="<%=slot.slot_fee %>" data-room="<%=sc.schedule_item %>" data-starttime="<%=String.Format("{0:t}", slot.slot_start) %>" data-endtime="<%=String.Format("{0:t}", slot.slot_end) %>" data-startdate="<%=String.Format("{0:d}", slot.slot_start) %>" data-duration="<%=sc.block_duration %>" data-roomno="<%=sc.schedule_item_no %>" data-slotno="<%=slot.schedule_slot_no %>" class="timeSlot <%=IIf(slot.isAvailable, IIf(sc.canBook, "", "blocked"), "booked") %>" <%=IIf(Not slot.isAvailable And sc.canBook And sc.visibility <> "public", "title=""" & slot.customer.company_name & " (" & slot.customer.first_name & ")""", "") %>>
                                                                <% If Not slot.isAvailable And sc.canBook And sc.visibility <> "public" And slot.customer.customer_no > 0 Then %>
                                                                <div class="bookedBlock">
                                                                    <%=slot.customer.company_name %><br />
                                                                    <%=slot.customer.first_name %>&nbsp; <%=IIf(slot.customer.last_name.Length > 1, Left(slot.customer.last_name, 1), "") %>
                                                                </div>
                                                                <% else %>
                                                                <% if slot.slot_fee > 0 Then %>
                                                                <%=String.Format("{0:c}", slot.slot_fee) %>
                                                                <% else %>
                                                                        &nbsp;
                                                                    <% end if %>
                                                                <% end if %>
                                                            </td>
                                                            <% end if %>
                                                            <% tempEarliestTime = tempEarliestTime.AddMinutes(incrementMinutes) %>
                                                            <% end while %>
                                                        </tr>
                                                        <% next %>
                                                    </tbody>
                                                </table>
                                            </div>
                                        </div>
                                    </div>
                                    <% Next %>
                                </div>
                                <div class="bookSlot" id="bookSlot">
                                    <h1 class="hdg hdg_5">Confirm Selection:</h1>
                                    <h2 class="hdg hdg_6 mix-hdg_dark vr-override_x3"><em><span id="dateSelection">January 1st, 2016</span> <span id="roomName">Example Room</span> <span id="roomStartTime">12:00PM</span> – <span id="roomEndTime">12:30PM</span></em> <span id="roomCost">$0.00</span></h2>
                                    <ul class="split split_alignBtm split_collapseOnMobile split_basisRight">
                                        <li>
                                            <span class="txt txt_feature">Please confirm the date, time and item you are booking is accurate.  On the next step, you will be taken to confirm your reservation.</span>
                                        </li>
                                        <li>
                                            <a href="/reservation" class="btn btn_hasIcon" id="bookNowBtn" onclick="myApp.showPleaseWait();">Continue<svg class="icon"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/media/svg/defs.svg#icon_caretRightHeavy"></use></svg>
                                            </a>
                                        </li>
                                    </ul>
                                </div>
                            </asp:PlaceHolder>
                            <asp:PlaceHolder runat="server" ID="pnlNoSlots" Visible="false">
                                <h2 class="hdg hdg_4">Sorry, we don't currently have any availability at this time.</h2>
                            </asp:PlaceHolder>
                        </div>
                    </div>
                </div>
            </section>
            <section class="component component_loose">
                <div class="component-content">
                    <div class="box mix-box_outlined">
                        <div class="box-bd box-bd_inflated">
                            <div class="split split_basisRight split_collapseOnMobile">
                                <h3 class="hdg hdg_6 mix-hdg_brandCallout">When booking, keep in mind these restrictions:</h3>
                                <div>
                                    <%if scheduleItems.Count = 1 Then %>
                                    <% if scheduleItems(0).time_between > 0 Or scheduleItems(0).max_blocks > 0 Then %>
                                    <ul class="blocks blocks_4to3to2to1 blocks_equalHeight">
                                        <% if scheduleItems(0).time_between > 0 Then %>
                                        <li>
                                            <a class="cardBtn">
                                                <span class="cardBtn-bd">
                                                    <span class="cardBtn-txt cardBtn-txt_label">Time Between<br />
                                                        Reservations
                                                    </span>
                                                    <span class="cardBtn-txt cardBtn-txt_digit"><%=IIf(scheduleItems(0).time_between > 1440, scheduleItems(0).time_between / 1440, IIf(scheduleItems(0).time_between > 60, scheduleItems(0).time_between / 60, scheduleItems(0).time_between)) %></span> <small><%=IIf(scheduleItems(0).time_between > 1440, "days", IIf(scheduleItems(0).time_between > 60, "hours", "minutes")) %></small>
                                                </span>
                                            </a>
                                        </li>
                                        <% End if %>
                                        <% If scheduleItems(0).max_blocks > 0 Then %>
                                        <li>
                                            <a class="cardBtn">
                                                <span class="cardBtn-bd">
                                                    <span class="cardBtn-txt cardBtn-txt_label">Max Slots<br />
                                                        Per Booking
                                                    </span>
                                                    <span class="cardBtn-txt cardBtn-txt_digit"><%=scheduleItems(0).max_blocks %></span>
                                                    <small><%=IIf(scheduleItems(0).block_duration > 1440, scheduleItems(0).block_duration / 1440, IIf(scheduleItems(0).block_duration > 60, scheduleItems(0).block_duration / 60, scheduleItems(0).block_duration)) %> minutes each</small>
                                                </span>
                                            </a>
                                        </li>
                                        <% end if %>
                                    </ul>
                                    <% else %>

                                    <% End if %>
                                    <% else %>
                                    <ul class="blocks blocks_4to3to2to1 blocks_equalHeight">
                                        <% If maxSlots > 0 Then %>
                                        <li>
                                            <a class="cardBtn">
                                                <span class="cardBtn-bd">
                                                    <span class="cardBtn-txt cardBtn-txt_label">Max Slots<br />
                                                        Per Booking
                                                    </span>
                                                    <span class="cardBtn-txt cardBtn-txt_digit"><%=maxSlots %></span>
                                                    <small><%=IIf(incrementMinutes > 1440, incrementMinutes / 1440, IIf(incrementMinutes > 60, incrementMinutes / 60, incrementMinutes)) %> minutes each</small>
                                                </span>
                                            </a>
                                        </li>
                                        <% end if %>
                                    </ul>
                                    <% End if %>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </section>
            <section class="component component_loose">
                <div class="component-content">

                    <div class="box mix-box_outlined">
                        <div class="box-bd box-bd_inflated vr">
                            <h2 class="hdg hdg_6 mix-hdg_dark vr-override_x6">Filter</h2>
                            <ul class="gridList">
                                <li class="gridList-item gridList-item_7of16 gridList-item_tight" style="<%=iif(request("type") = "calendar", "display:none;", "")%>">
                                    <ul class="gridList-item-subGroup">
                                        <li>
                                            <span class="fieldset">
                                                <label class="fieldset-label fieldset-label_isHidden" for="<%=sfrom_date.ClientID %>">start date</label>
                                                <span class="fieldset-input">
                                                    <asp:TextBox runat="server" ID="sfrom_date" placeholder="MM/DD/YYYY" CssClass="js-datepicker" />
                                                </span>
                                            </span>
                                        </li>
                                        <li>
                                            <span class="fieldset">
                                                <label class="fieldset-label fieldset-label_isHidden" for="<%=sto_date.ClientID %>">end date</label>
                                                <span class="fieldset-input">
                                                    <asp:TextBox runat="server" ID="sto_date" placeholder="MM/DD/YYYY" CssClass="js-datepicker" />
                                                </span>
                                            </span>
                                        </li>
                                    </ul>
                                </li>
                                <li class="gridList-item gridList-item_7of16 gridList-item_tight">
                                    <span class="fieldset">
                                        <label class="fieldset-label" for="<%=schedule_item_no.ClientID %>">or filter</label>
                                        <span class="fieldset-input">
                                            <asp:DropDownList runat="server" ID="schedule_item_no" />
                                        </span>
                                    </span>
                                </li>
                                <li class="gridList-item gridList-item_2of16 gridList-item_tight">
                                    <span class="fieldset">
                                        <label class="fieldset-label">&nbsp;</label>
                                        <asp:Button runat="server" ID="btnsub" Text="Apply" CssClass="btn mix-btn_stretch" OnClick="btnsub_Click" OnClientClick="myApp.showPleaseWait();" />

                                    </span>
                                </li>
                                <li class="gridList-item" style="<%=iif(request("type") = "calendar", "display:none;", "")%>">
                                    <asp:RadioButtonList runat="server" ID="filterDate" CssClass="hList tick tick_bubble" RepeatLayout="UnorderedList" AutoPostBack="true" OnSelectedIndexChanged="filterDate_SelectedIndexChanged">
                                        <asp:ListItem Value="today">Today</asp:ListItem>
                                        <asp:ListItem Value="tomorrow">Tomorrow</asp:ListItem>
                                        <asp:ListItem Value="this week">This Week</asp:ListItem>
                                        <asp:ListItem Value="next week">Next Week</asp:ListItem>
                                    </asp:RadioButtonList>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
            </section>

Javascript

    <script>window.jQuery || document.write('<script src="/assets/jQuery/default/jquery.min.js">\x3C/script>')</script>
    <script src="/scripts/vendor/fullcalendar/moment.min.js"></script>
    <script src="/plugins/slick/slick.min.js"></script>
    <script src="/scripts/components/schedulerMulti.js"></script>
    <script>
        //JS init for slider (init is for reference only - page is not loading Slick Slider plugin: http://kenwheeler.github.io/slick/)
        var MAX_SLOTS = 10 //make dynamic based on available schedulers;
        var loadSlick = function () {
            var selector = '#dateSlider';
            var config = {
                centerPadding: '60px',
                slidesToShow: 7,
                arrows: true,
                infinite: false,
                responsive: [
                    {
                        breakpoint: 979,
                        settings: {
                            slidesToShow: 7
                        }
                    },
                    {
                        breakpoint: 767,
                        settings: {
                            slidesToShow: 3
                        }
                    },
                    {
                        breakpoint: 480,
                        settings: {
                            slidesToShow: 1
                        }
                    }
                ]
            };
            $(selector).slick(config);
        };

        $(document).ready(function () {
            //new DatepickerHelper('.js-datepicker', { setDate: new Date(), minDate: new Date(1900, 1, 1) });
            var Sch = scheduler(MAX_SLOTS);
            Sch.init();
            loadSlick();

            $("#sfrom_date").datepicker({
                defaultDate: "+1d",
                changeMonth: false,
                numberOfMonths: 3,
                minDate: "+0d",
                maxDate: "+360d",
                onClose: function (selectedDate) {
                    $("#sto_date.ClientID").datepicker("option", "minDate", selectedDate);
                }
            });
            $("#sto_date").datepicker({
                defaultDate: "+3d",
                changeMonth: false,
                numberOfMonths: 3,
                minDate: "+1d",
                maxDate: "+360d",
                onClose: function (selectedDate) {
                    $("#sfrom_date").datepicker("option", "maxDate", selectedDate);
                }
            });
        });
    </script>

Additional Help Tutorials

Find more ways to grow on PeopleVine.

Configure Salto to Work with Peoplevine Check-In

Follow these steps to configure your Salto to auto Check-In members when they use a Salto keycard.

Posted January 12, 2024

Detailed Member Statements & Billing

Unveiling Peoplevine's Member Statements & Billing feature: a comprehensive tool ensuring utmost transparency, simplicity, and efficiency in every financial transaction for both members and operators.

Posted September 28, 2023

New and Improved Timeline View

Dive into Peoplevine's My Schedule Timeline View: a feature designed to bring unmatched convenience and clarity to members' and guests' schedules, centralizing everything from dining to events.

Posted September 28, 2023

Spa & Wellness Booking with Book4Time Integration

Experience the perfect synergy of Peoplevine and Book4Time: a collaboration that transforms spa and wellness bookings, merging front-end engagement with backend efficiency.

Posted September 28, 2023

Going Global

Discover how PeopleVine's "Global Network" solution is set to revolutionize the hospitality industry by unifying brand experiences across multiple properties, whether globally or within a local region, offering members a seamless digital experience and granting operators unparalleled insights.

Posted September 28, 2023

Override the Guest Pass E-mail with Template

You can replace the e-mail sent to a guest when a guest pass is issued while retaining the necessary links to ensure they can activate it.

Posted September 27, 2023

Transaction Reporting has an Upgrade

We updated the Transaction Reporting screen to provide you with the data necessary to provide a glimpse at your revenue and the necessary data to audit your financials.

Posted September 7, 2023

You Can Set the Time to Process Authorizations

When a charge is processed through your POS, the charge may be Authorized until we capture the tip or at the end of day to handle refunds or changes. In this case, you can now set the time as to when we will process your authorizations.

Posted August 28, 2023

Adding Your Alliants Integration

Follow these steps to connect Peoplevine with your Alliants account for messaging.

Posted August 28, 2023

Setup Your Membership Tiers Based on Age

You can enable your membership tier to be for members between certain ages, when they past that age, they will automatically migrate to the next age tier.

Posted August 22, 2023

Follow these steps to update your Twilio settings to ensure delivery

This article will overview how to setup your brand and campaigns for broader/better delivery.

Posted August 10, 2023

Select Which Transaction Types You Want to Sync with Quickbooks

You're able to select which types of transaction items you want to sync to Quickbooks.

Posted June 14, 2023

Configure your Member Portal to Show Spa and Wellness

Once your Spa and Wellness feature is enabled, you need to configure the following to display on your member portal.

Posted June 14, 2023

Setup a Temporary ID for Hotel Guests

You can allow hotel guests to act as a member during their time at your property by leveraging these settings.

Posted May 23, 2023

© Peoplevine 2024. Powered by PeopleVine. Terms of use | Privacy & cookies