CINXE.COM
Space Availability - Main Library - LibCal - North Dakota State University
<!DOCTYPE html> <html lang="en"> <head> <!-- iid: 5679 --> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://static-assets-us.libcal.com/bootstrap_13/bootstrap3.min.css" rel="stylesheet"> <link href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> <link href="https://static-assets-us.libcal.com/css_739/LibCal_public.min.css" rel="stylesheet"> <link href="https://static-assets-us.libcal.com/css_739/print.min.css" rel="stylesheet" media="print"> <script src="https://static-assets-us.libcal.com/jquery_16/jquery.min.js"></script> <script src="https://static-assets-us.libcal.com/bootstrap_13/bootstrap3.min.js"></script> <script src="https://static-assets-us.libcal.com/js_739/LibCal_public.min.js"></script> <script> springSpace.dateFormat = "dddd, MMMM D, YYYY"; springSpace.dateShortFormat = "ddd MMM Do YYYY"; springSpace.timeFormat = "h:mma"; springSpace.timezone = 'America/Chicago'; springSpace.currency = "USD"; springSpace.currencySymbol = "$"; springSpace.language = 'en'; // en springSpace.locale = 'en-US'; // en-US springSpace.phpTimeFormat = 'g:ia'; springSpace.bootstrapAsset = 'https://static-assets-us.libcal.com/bootstrap_13/bootstrap3_16.min.css'; springSpace.publicCssAsset = 'https://static-assets-us.libcal.com/css_739/LibCal_public.min.css'; springSpace.adminCssAsset = 'https://static-assets-us.libcal.com/css_739/LibCal_admin.min.css'; </script> <title> Space Availability - Main Library - LibCal - North Dakota State University </title> <style> #s-lc-public-banner { padding: 0; margin: 0; } .s-lc-public-footer { margin: 0; } </style> <link rel="stylesheet" href="https://static-assets-us.libcal.com/fullcalendar_14/fullcalendar.min.css"/> <style> .s-lc-eq-avail, .label-eq-avail, .s-lc-eq-period-available { background: #14951F none !important; border-color: #14951F !important; } .s-lc-eq-avail:hover, .s-lc-eq-period-available:hover { background: #095212 none !important; border-color: #095212 !important; } .s-lc-eq-pending, .label-eq-pending, .s-lc-eq-period-pending { background: #F59F16 none !important; border-color: #F59F16 !important; } .s-lc-eq-checkout, .s-lc-eq-r-unavailable, .s-lc-eq-r-padding, .label-eq-unavailable, .s-lc-eq-period-booked { background: #C91908 none !important; border-color: #C91908 !important; } </style> <style> @media (max-width: 768px) { .fc-timeline .fc-cell-text { font-size: 12px !important; } } </style> <style> a { color: #0A5640; } .btn-info, .btn-info.active, .btn-info:active, .btn-info:focus, .btn-info:hover { background-color: #0A5640; border-color: #0A5640; } .nav-pills > li.active > button, .nav-pills > li.active > button:focus, .nav-pills > li.active > button:hover { background-color: #0A5640; color: #fff; } .nav .s-lg-index-nav-btn > button { color: #0A5640; } #s-lg-tabs-container .nav-tabs > li > a, #s-lg-tabs-container .nav-tabs > li > button, #s-lg-tabs-container .nav-pills > li > a, #s-lg-tabs-container .nav-pills > li > button { background-color: #0A5640; } #s-lg-tabs-container .nav-tabs > .active > a, #s-lg-tabs-container .nav-tabs > .active > button, #s-lg-tabs-container .nav-pills > .active > a, #s-lg-tabs-container .nav-pills > .active > button { background-color: #198754; } navfooter { background: #404041; background: #0A5640; min-height: 35px; border-top: 2px solid #CFCFD0; border-bottom: 15px solid #fdd018; } .navfooter ul { margin: 0 auto; list-style-type: none; padding-left: 20%; } .navfooter li { float: left; } .navfooter li a { display: block; padding-top: 25px; padding-right: 30px; padding-bottom: 25px; padding-left: 70px; color: white; background-color: #0A5640; } .footergroup { background: #0A3927; color: #fff; font-size: 14px; padding-left: 20%; padding-top: 5%; } .footergroup p { font-size: 14px; } </style> <!--Start of Zopim Live Chat Script--> <script type="text/javascript"> window.$zopim||(function(d,s){var z=$zopim=function(c){z._.push(c)},$=z.s= d.createElement(s),e=d.getElementsByTagName(s)[0];z.set=function(o){z.set. _.push(o)};z._=[];z.set._=[];$.async=!0;$.setAttribute("charset","utf-8"); $.src="//v2.zopim.com/?128ORu0Sf1auf1oWhE10Gx4uWDG4H8qP";z.t=+new Date;$. type="text/javascript";e.parentNode.insertBefore($,e)})(document,"script"); </script> <!--End of Zopim Live Chat Script--> </head> <body id="equip_" class="s-lc-public s-lc-public-page-5"> <a class="s-lc-skiplink alert-info" href="/r/accessible?lid=14617&gid=30464"> Alternate page for screen reader Users </a> <a id="s-lc-public-skiplink" class="s-lc-skiplink alert-info" href="#s-lc-public-title-area">Skip to Main Content</a> <div class="container"> <div id="s-lc-public-banner" class="row s-lc-public-banner" role="banner"> <a href="https://library.ndsu.edu"> <img alt="North Dakota State University LibCal" class="img-responsive" id="s-lc-public-banner-img" src="//d68g328n4ug0e.cloudfront.net/data/headers/5679/NDSU.logo.typebox.gif" /> <span class="sr-only">North Dakota State University LibCal</span> </a> </div> <div id="s-lc-public-bc" class="row"> <div class="col-md-12"> <nav aria-label="Breadcrumb"> <ol class="breadcrumb"> <li><a href="https://library.ndsu.edu">North Dakota State University</a></li> <li class="s-lc-desktop-only"><a href="https://ndsu.libcal.com">LibCal</a></li> <li class="active s-lc-desktop-only"> Space Availability - Main Library </li> </ol> </nav> </div> </div> <noscript> <div class="alert alert-danger" id="noscript">Your browser has javascript disabled. Without javascript some functions will not work.</div> </noscript> <div id="s-lc-public-title-area"> </div> <main> <div id="s-lc-public-main" class="s-lc-public-main"> <div id="s-lc-public-page-content" class="row"> <div id="col1" class="col-md-12 center" > <div id="s-lc-eq-navform" class="s-lc-spaces-setup-info"> <h1 class="sr-only"> Space Availability - Main Library </h1> <form class="form-inline" role="search" autocomplete="off"> <input type="hidden" name="page" id="page" value="1"> <input type="hidden" name="type" id="type" value="2"> <div class="form-group form-group-sm"> <label class="hidden-sm" for="lid">Location</label> <select class="form-control" name="lid" id="lid"> <option value="14617" selected="selected">Main Library</option> <option value="15236" >Business Learning Center (BLC)</option> <option value="15390" >Bismarck Nursing</option> <option value="0"> View All Locations </option> </select> </div> <div class="form-group form-group-sm"> <label class="hidden-sm" for="gid">Category</label> <select class="form-control" name="gid" id="gid"> <option value="30464" selected="selected">Single Study Rooms</option> <option value="32352" >Group Study Rooms</option> <option value="32379" >Other Spaces</option> <option value="41317" >Relaxation Room</option> <option value="0" >Show All</option> </select> </div> <div class="form-group form-group-sm"> <label class="hidden-sm" for="capacity"> Capacity </label> <select class="form-control" name="capacity" id="capacity"> <option value="0"> All Spaces (not seats) </option> <option value="1"> Space For 1-4 people </option> </select> </div> </form> </div> <div id="s-lc-group-description" role="region" aria-label="description" class="s-lc-resource-description s-lc-spaces-setup-info"> <p>Study rooms that accommodate a single individual for study</p> </div> <div id="s-lc-window-limit-warning" class="alert alert-info margin-top-med margin-bottom-none" role="alert" style="display: none;"> You have reached the end of the bookable window. No availability will be shown past this point. </div> <div id="time_grid_cont" role="grid" class="s-lc-spaces-time-grid s-lc-spaces-setup-info"> <div id="eq-time-grid"> </div> <div id="s-lc-time-grid-pagination" class="s-lc-time-grid-pagination"> </div> <div class="s-lc-time-grid-legend" id="eq-time-grid-legend"> <span class="label-eq-cont" data-toggle="tooltip" data-placement="top" title="Slot is available, click to book!"><span class="label label-eq-avail"> </span> Available</span> <span class="label-eq-cont" data-toggle="tooltip" data-placement="top" title="Your pending booking."><span class="label label-eq-pending"> </span> Your Booking</span> <span class="label-eq-cont" data-toggle="tooltip" data-placement="top" title="This slot is unavailable for starting a new booking. Bookings may occasionally extend into this slot."><span class="label label-eq-unavailable"> </span> Unavailable/Padding</span> </div> </div> <div id="s-lc-eq-form-box" class="s-lc-spaces-setup-info" style="display: none;" role="region" aria-label="booking form" aria-live="polite"> <form id="s-lc-eq-form-times" class="form-horizontal" method="post"> <fieldset> <div id="s-lc-eq-bwell" class="well" tabindex="0"> </div> <div id="s-lc-eq-bform-inner" class="col-sm-offset-5"> <button class="btn btn-primary" name="submit_times" id="submit_times">Submit Times</button> <button class="btn btn-default" name="eq_cart" id="eq_cart"><i class="fa fa-shopping-cart fa-lg" aria-hidden="true"></i> Add Equipment</button> </div> </fieldset> </form> </div> <div id="s-lc-eq-form" style="clear:both; display: none;" role="region" aria-live="polite" aria-label="Booking details"></div> <div id="s-lc-eq-errors" class="alert alert-danger" style="display: none;" role="region" aria-live="polite" aria-label="Error encountered"></div> <div id="s-lc-eq-success" style="display: none;" role="region" aria-live="polite" aria-labelledby="s-lc-eq-success-title"> </div> </div> </div> </div> </main> <footer id="s-lc-public-footer" class="row s-lc-public-footer"> <div id="s-lc-public-footer-brand"> <span title="libcal-us-4">Powered by</span> <a href="https://www.springshare.com">Springshare</a>. </div> <div id="s-lc-public-footer-rights"> All rights reserved. </div> <div id="s-lc-footer-support-link"> <a href="mailto:patrick.graybill@ndsu.edu">Report a tech support issue.</a> </div> <div id="s-lc-public-footer-print-link"> View this page in a format suitable for <a href="/r/accessible?lid=14617&gid=30464"> screen-readers and keyboard-only users </a> </div> <div id="s-lc-public-footer-admin-links" role="navigation" aria-label="Admin Footer"> <a id="s-lc-sign-in" href="https://ndsu.libapps.com/libapps/login.php?site_id=22475&target=">Login to LibApps</a> </div> <div class="s-lc-public-footer-actions"> <div id="s-lc-language"> <select id="s-lc-language-selector" aria-label="Select Language"> <option value="ca" >català</option> <option value="cy" >Cymraeg</option> <option value="en" selected>English</option> <option value="es" >español</option> <option value="fr" >français</option> <option value="ga" >Irish</option> <option value="ja" >日本語 Nihongo</option> <option value="nl" >Nederlands</option> <option value="sl" >slovenski jezik</option> <option value="vi" >Tiếng Việt</option> <option value="zh" >中文 Zhōngwén</option> </select> </div> </div> </footer> <!-- Global site tag (gtag.js) - Google Analytics --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-R92X7VX3SJ"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-R92X7VX3SJ'); </script> </div> <div id="s-lc-public-cust-footer"><div class="navfooter"> <ul> <li><a href="https://www.ndsu.edu/alphaindex/buildings" title="Alphabetical Building List">Campus Map</a></li> <li><a href="https://www.ndsu.edu/employment/" title="Employment opportunities at NDSU">Employment</a></li> <li><a href="https://www.ndsu.edu/equity/">Equity</a></li> <li><a href="https://www.ndsu.edu/onlineservices/">Online Services</a></li> <li><a href="https://www.ndsu.edu/directory/">Phone/Email Directory</a></li> <li><a href="https://www.ndsu.edu/registrar/" title="Office of the Registrar">Registration And Records</a></li> </ul> </div> <div class="footergroup"> <footer class="row"> <div id="footer-first" class="large-4 columns"> <div> <p><a href="https://ndsu.edu/" rel="nofollow" target="_blank"><img src="https://library.ndsu.edu/themes/librarymain/images/NDSU.png" width="110" /></a></p> <p><strong>North Dakota State University</strong><br /> Libraries<br /> 1201 Albrecht Boulevard<br /> Dept #2080 PO Box 6050<br /> Fargo, ND 58108-6050</p> <p>Circulation: (701) 231-8888<br /> Reference: (701) 231-8886<br /> Administration: (701) 231-8753<br /> Germans from Russia Heritage Collection: (701) 231-6596<br /> NDSU Archives: (701) 231-8914<br /> Email: <a href="mailto:ndsu.dean.libraries@ndsu.edu" style="color:#ffffff;text-decoration:underline;">ndsu.dean.libraries@ndsu.edu</a></p> </div> </div> <p><a href="/news-events"><img alt="Events and News" src="https://library.ndsu.edu/themes/librarymain/images/ICONcalendar.png" /></a> <a href="https://www.facebook.com/pages/Fargo-ND/North-Dakota-State-University-Libraries/226004834788" target="_blank"><img alt="NDSU Libraries Facebook" src="https://library.ndsu.edu/themes/librarymain/images/ICONfacebook.png" /></a> <a href="https://www.instagram.com/ndsulibrary/?hl=en" target="_blank"><img alt="NDSU Libraries Instagram" src="https://library.ndsu.edu/themes/librarymain/images/ICONinstagram.png" /></a> <a href="https://twitter.com/NDSULibraries" target="_blank"><img alt="NDSU Libraries Twitter" src="https://library.ndsu.edu/themes/librarymain/images/ICONtwitter.png" /></a> <a href="https://www.youtube.com/user/NDSUlibrary?feature=mhee" target="_blank"><img alt="NDSU Libraries YouTube" src="https://library.ndsu.edu/themes/librarymain/images/ICONyoutube.png" /></a> <a href="https://library.ndsu.edu/search-find/research/resources/government-information" target="_blank"><img alt="NDSU is a Federal Depository for Government Documents" src="https://library.ndsu.edu/themes/librarymain/images/ICONgovtdoc.png" /></a></p> </footer> </div> </div> <script defer src="https://static-assets-us.libcal.com/fullcalendar_14/fullcalendar.min.js"></script> <script defer src="https://static-assets-us.libcal.com/js_739/datepicker.min.js"></script> <link rel="stylesheet" href="https://static-assets-us.libcal.com/css_739/datepicker.min.css"/> <script> var springyFullCalendar = { commonOptions: { schedulerLicenseKey: '0391239527-fcs-1659132663', now: '2025\u002D03\u002D31\u002016\u003A01', nowIndicator: true, scrollTime: '15\u003A00\u003A00', lazyFetching: false, locale: springSpace.language, themeSystem: 'bootstrap', eventTextColor: '#222', eventDisplay: 'block', moreLinkClick: 'day', bootstrapFontAwesome: { goToDate: 'fa-calendar', goToNextAvailable: 'fa-fast-forward', refresh: 'fa-refresh', }, navLinks: true, // https://fullcalendar.io/docs/navLinks resourceOrder: false, // https://fullcalendar.io/docs/resourceOrder stickyHeaderDates: false, // https://fullcalendar.io/docs/stickyHeaderDates && https://github.com/springshare/LibCal/issues/11801 dayCellContent: function (info) { // regardless of language, show the day as a number with no extra characters return info.date.getDate(); }, }, timelineOptions: { height: 'auto', refetchResourcesOnNavigate: false, eventOverlap: false, displayEventTime: false, slotDuration: '00\u003A30', titleFormat: springSpace.dateFormat, views: { timelineSingleDay: { type: 'resourceTimeline', buttonText: 'Day\u0020View', duration: {days: 1}, slotLabelFormat: springSpace.timeFormat, }, timelineHourlyShort: { type: 'resourceTimeline', duration: {days: 3}, slotLabelFormat: [springSpace.dateFormat, springSpace.timeFormat], }, timelineHourlyLong: { type: 'resourceTimeline', duration: {days: 7}, slotLabelFormat: [springSpace.dateFormat, springSpace.timeFormat], }, timelineDailyLong: { type: 'resourceTimeline', slotDuration: '24:00', duration: {days: 28}, slotLabelFormat: ['dd D'], nowIndicator: false }, resourceTimeGridWeek: { buttonText: 'Week\u0020View', slotLabelFormat: springSpace.timeFormat, } }, }, publicTexts: { allDay: 'All\u0020Day', available: 'Available', dayGridMonth: 'Month', dayGridWeek: 'Agenda', goToDate: 'Go\u0020To\u0020Date', goToNextAvailable: 'Next\u0020Available', next: 'Next', prev: 'Previous', timeGridDay: 'Day', timeGridWeek: 'Week', today: 'Today', unavailable: 'Unavailable\/Padding', yourBooking: 'Your\u0020Booking', listWeek: 'Week\u0020List', }, adminTexts: { goToDate: 'Go\u0020To\u0020Date', refresh: 'Refresh', prev: 'Previous', next: 'Next', today: 'Today', week: 'Week', month: 'Month', day: 'Day', dayGridWeek: 'Agenda', allDay: 'All\u0020Day', atLocation: '\u0025title\u0025\u0020at\u0020\u0025location\u0025', }, dateTimeFormats: { monthViewTitle: 'MMMM YYYY', }, }; // placeholder for dynamic content boxes with a full calendar var calendarList = {}; function reRenderCalendarList() { for (var calId in calendarList) { calendarList[calId].render(); } } </script> <script defer src="https://static-assets-us.libcal.com/js_739/direct/full-calendar-common.min.js"></script> <script> var springLang = { eq_js_until_det: 'until...', eq_js_rem_pending: 'Remove\u0020Pending\u0020Booking', eq_js_cart_tt: 'Create\u0020a\u0020shopping\u0020cart\u0020with\u0020these\u0020space\u0020bookings,\u0020and\u0020go\u0020to\u0020equipment\u0020booking\u0020page\u0020to\u0020add\u0020more\u0020items\u0020to\u0020the\u0020cart.', eq_js_isRequired: 'is\u0020required\u0021', }; </script> <script defer src="https://static-assets-us.libcal.com/js_739/direct/public/equipment/common.min.js"></script> <script defer src="https://static-assets-us.libcal.com/js_739/direct/public/equipment/spaces.min.js"></script> <script defer src="https://static-assets-us.libcal.com/js_739/direct/public/equipment/session.min.js"></script> <script> var pendingRoomBookings = []; var pendingBookingNextId = 1; var pendingBookingsBlowAwayCart = false; function addError(msg, id) { jQuery(".s-lc-eq-" + id).addClass("has-error").find(".form-control").attr("aria-invalid", true); jQuery(".s-lc-eq-" + id).find(".s-lc-eq-flab").append('<div class="error-message">' + msg + "</div>"); jQuery("#" + id).focus(); return false; } function removeErrors() { jQuery(".s-lc-eq-q").removeClass("has-error").find(".error-message").remove(); } function agreeToTermsAndConditions() { jQuery("#bform-terms-container").hide(); jQuery("#bform-form-container").show(); scrollAndFocusOnElement('#s-lc-bform-help'); return false; } function toggleSubmitButton() { var isTermsAgreedTo = jQuery(this).is(':checked'); jQuery('#btn-form-submit').prop('disabled', !isTermsAgreedTo); } function customFormValidation() { // exists to be overwritten by the specific group validation function } function preFormValidationAndPayload() { removeErrors(); jQuery("#s-lc-eq-errors").hide(); if (!isVisibleFieldsValid()) { return false; } if (!customFormValidation()) { return false; } pageBusyBegin("#btn-form-submit"); var formElement = '#s-lc-eq-bform'; var bookings = preparePendingBookingsPayload(); var bookingsPayload = JSON.stringify(bookings); springyCommon.appendHiddenInput('bookings', bookingsPayload, formElement); springyCommon.appendHiddenInput('returnUrl', springySpaces.getReturnUrl(), formElement); springyCommon.appendHiddenInput('pickupHolds', jQuery('#s-lc-pickup-holds').val(), formElement); springyCommon.appendHiddenInput('method', springyPage.bookingMethod, formElement); return true; } function bookingSuccessCallback(data) { pageBusyEnd("#btn-form-submit"); if (data.error) { jQuery("#s-lc-eq-errors").html(data.error).show(); return; } jQuery('#s-lc-eq-form, .s-lc-spaces-setup-info').hide(); jQuery('#s-lc-eq-success').html(data.html).show().focus(); springySession.clear(); return; } function bookingErrorCallback(xhr) { pageBusyEnd("#btn-form-submit"); var errorMessage = ajaxErrorGetText(xhr); jQuery('#s-lc-eq-errors').html(errorMessage).show().focus(); } function submitPendingTimes() { var payload = { patron: springySpaces.patron, patronHash: springySpaces.patronHash, returnUrl: springySpaces.getReturnUrl(), bookings: preparePendingBookingsPayload(), method: springyPage.bookingMethod, }; pageBusyBegin("#submit_times"); jQuery.ajax({ type: 'post', url: '/ajax/space/times', data: payload, dataType: 'json', }) .always(function () { pageBusyEnd("#submit_times"); }) .done(function(data) { if (data.redirect) { // redirect to libauth checkout page window.location = data.redirect; return; } // hide a bunch of stuff jQuery('.s-lc-spaces-setup-info').hide(); // setup booking form + terms html jQuery("#s-lc-eq-form").html(data.html).show(); // scroll to the top of the page window.scrollTo(0, 0); }) .fail(ajaxErrorHandler); return false; } function makeCartAndGoToEquipPage() { // we only allow user to do this if all the room bookings start at the same time if (pendingRoomBookings.length > 1) { var startTime = pendingRoomBookings[0].start; for (var i = 1; i < pendingRoomBookings.length; i++) { var bookingInfo = pendingRoomBookings[i]; if (!bookingInfo.start.isSame(startTime)) { errorAlert('You can only create an Equipment Cart if all your room bookings begin at the same time.'); return false; } } } var payload = { blowAwayCart: pendingBookingsBlowAwayCart, returnUrl: springySpaces.getReturnUrl(), bookings: preparePendingBookingsPayload(), method: springyPage.bookingMethod, }; workingAlert(); jQuery.ajax({ type: 'post', url: "/ajax/space/createcart", data: payload, dataType: 'json', }) .always(function (data) { stopAlert(); }) .done(function(data) { if (data.success) { // redirect to new page window.location = data.redirect; } else if (data.hasItems) { errorAlert("Cart already has items in it. If you click the shopping cart again, the existing items in the cart will be replaced by the selected rooms."); pendingBookingsBlowAwayCart = true; } else { errorAlert(data.error); } }) .fail(ajaxErrorHandler); return false; } function changeBookingTimes() { // show the old form box + availability grid jQuery('.s-lc-spaces-setup-info').show(); // hide the terms + booking form jQuery('#s-lc-eq-form, #s-lc-eq-errors').hide(); return false; } function getSpaceResourceContent(info) { var html = ''; var resourceData = info.resource.extendedProps; var resourceId = springyPage.isSeatBooking ? resourceData.seatId : resourceData.eid; var title = escapeHtml(info.fieldValue); if (resourceData.hasInfo) { html += '<a href="#" class="s-lc-item-more-info" data-eid="' + resourceId + '"' + ' aria-label="Click\u0020for\u0020more\u0020info\u0020about ' + title + '">' + '<span class="s-lc-info-label">Info</span>' + '</a>'; } var additionalClasses = ''; var additionalIcons = ''; var filterIds = resourceData.filterIds || []; for (var i = 0; i < filterIds.length; i++) { var filterId = filterIds[i]; if (filterId in springyPage.searchFilters) { var filter = springyPage.searchFilters[filterId]; additionalClasses += ' s-lc-filter-' + filterId; additionalIcons += ' <i class="fa ' + filter.icon + ' fa-lg" aria-hidden="true"></i>'; } } var resourceLabel = '<span class="fc-cell-text' + additionalClasses + '">' + title + additionalIcons + '</span>'; if (resourceData.url !== undefined) { html += '<a href="' + resourceData.url + '">' + resourceLabel + '</a>'; } else { html += resourceLabel; } return { html: html, }; } jQuery(function () { springyPublic.registerClearBackForwardCache(); jQuery('#lid').on('change', goToPageForLocation); jQuery('#gid').on('change', goToPageForGroup); jQuery('#eq_cart').on('click', makeCartAndGoToEquipPage); jQuery('#s-lc-eq-form-times').on('submit', submitPendingTimes); }); </script> <script src="https://static-assets-us.libcal.com/js_739/direct/pagination.min.js"></script> <script src="https://static-assets-us.libcal.com/js_739/direct/public/equipment/spaces-standard.min.js"></script> <script> var springyPage = { wantAlternatingBackground: true, timelineOptions: { resourceAreaWidth: '33%', }, locationId: 14617, groupId: 30464, itemId: -1, isSeatBooking: 0, seatId: 0, zoneId: 0, searchFilters: {"3503":{"id":3503,"icon":"fa-wheelchair-alt","name":"Accessible Seat\/Space"},"3504":{"id":3504,"icon":"fa-plug","name":"Power Available"}}, filterIds: [], isDailyBookings: 0, resourceRows: 11, resourceColumnLabel: 'Space', viewMode: 'timelineHourlyShort', returnUrl: '', capacitySeatValue: -1, pageIndex: 0, pageSize: 18, bookingMethod: 11, }; var resources = []; var resourceNameIdMap = []; resources.push({ id: "eid_170637", title: "118B (Capacity 1)", url: "/space/170637", eid: 170637, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/rm_118B.jpg", filterIds: [3503,3504], }); resourceNameIdMap["eid_170637"] = "118B"; resources.push({ id: "eid_117304", title: "219 (Capacity 1)", url: "/space/117304", eid: 117304, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR219.jpg", filterIds: [3504], }); resourceNameIdMap["eid_117304"] = "219"; resources.push({ id: "eid_128094", title: "221 (Capacity 1)", url: "/space/128094", eid: 128094, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR221.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128094"] = "221"; resources.push({ id: "eid_128095", title: "225A (Capacity 1)", url: "/space/128095", eid: 128095, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225A.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128095"] = "225A"; resources.push({ id: "eid_128096", title: "225B (Capacity 1)", url: "/space/128096", eid: 128096, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225B.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128096"] = "225B"; resources.push({ id: "eid_128097", title: "225C (Capacity 1)", url: "/space/128097", eid: 128097, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225C.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128097"] = "225C"; resources.push({ id: "eid_128098", title: "225D (Capacity 1)", url: "/space/128098", eid: 128098, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225D.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128098"] = "225D"; resources.push({ id: "eid_128099", title: "225E (Capacity 1)", url: "/space/128099", eid: 128099, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225E.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128099"] = "225E"; resources.push({ id: "eid_128101", title: "225G (Capacity 1)", url: "/space/128101", eid: 128101, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225G.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128101"] = "225G"; resources.push({ id: "eid_128103", title: "225H (Capacity 1)", url: "/space/128103", eid: 128103, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225H.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128103"] = "225H"; resources.push({ id: "eid_128104", title: "225J (Capacity 1)", url: "/space/128104", eid: 128104, gid: 30464, lid: 14617, grouping: "Single\u0020Study\u0020Rooms", gtype: 2, gBookingSelectableTime: false, capacity: 1, hasInfo: true, thumbnail: "https://libapps.s3.amazonaws.com/customers/8942/images/SR225J.jpg", filterIds: [3504], }); resourceNameIdMap["eid_128104"] = "225J"; var paginatedResources = springyPagination.createPaginatedResources(resources, springyPage.pageSize); var capacityRangesMap = {}; capacityRangesMap[0] = { min: 0, max: 9223372036854775807 }; capacityRangesMap[1] = { min: 0, max: 4 }; capacityRangesMap[2] = { min: 5, max: 8 }; capacityRangesMap[3] = { min: 9, max: 12 }; capacityRangesMap[4] = { min: 13, max: 9223372036854775807 }; var resourceSettings = createResourceSettings(1); springyPage.resourceCount = resources.length; </script> <script> var pendingBookingsLimitIssues = null; var dateFormatStartTimeDict = "MMDDHHmm"; var dateFormatDayOfYear = "YYYY-MM-DD"; var issueTypeAdditionalText = { "duration": " minutes", "frequency": " bookings", }; var frequencyDisplayStrings = { "d": " per\u0020day", "w": " per\u0020week", "m": " per\u0020month", "y": " per\u0020year", "t": " at\u0020a\u0020time", }; function pendingRoomBookingsAreNowEmpty() { jQuery("#s-lc-eq-form-box").hide(); } function renderPendingRoomBookings() { // ensure all tooltips are hidden jQuery(".tooltip").hide(); if (pendingRoomBookings.length == 0) { pendingRoomBookingsAreNowEmpty(); return; } // refresh the shown cart items // format the room data as html var html = '<div>'; var startDateTimeFormat = springyPage.isDailyBookings ? springSpace.dateFormat : springSpace.getDateTimeFormat(); var endDateTimeFormat = springyPage.isDailyBookings ? springSpace.dateFormat : springSpace.getShortDateTimeFormat(); var totalCost = 0; for (var i = 0; i < pendingRoomBookings.length; i++) { var bookingInfo = pendingRoomBookings[i]; var bookingCost = bookingInfo.cost; var resourceId = bookingInfo.seat_id > 0 ? bookingInfo.seat_id : bookingInfo.eid; var resourceName = resourceNameIdMap['eid_' + resourceId]; html += '<div class="form-group s-lc-pending-booking" id="pending_booking_' + bookingInfo.id + '">'; html += ' <label class="col-md-5 control-label" for="bookingend_' + bookingInfo.id + '"><strong>' + resourceName + '</strong>: ' + bookingInfo.start.format(startDateTimeFormat) + ' ' + springLang.eq_js_until_det + '</label>'; html += ' <div class="col-md-3">'; html += ' <div class="input-group">'; html += ' <select id="bookingend_' + bookingInfo.id + '" name="bookingend_' + bookingInfo.id + '" data-booking="' + bookingInfo.id + '" class="form-control input-sm b-end-date">'; for (var selectionIndex = 0; selectionIndex < bookingInfo.options.length; selectionIndex++) { var selected = bookingInfo.optionSelected == selectionIndex ? 'selected="selected"' : ''; var value = bookingInfo.options[selectionIndex]; var name = moment(value).format(endDateTimeFormat); var checksum = bookingInfo.optionChecksums[selectionIndex]; html += '<option value="' + value + '" ' + selected + ' data-crc="' + checksum + '">' + name + '</option>'; } html += ' </select>'; html += ' <div class="input-group-btn">'; html += ' <button type="button" class="btn btn-default btn-sm" onclick="return removePendingBooking(' + bookingInfo.id + ',' + bookingInfo.lid + ');"><i class="fa fa-trash-o" aria-hidden="true"></i><span class="sr-only">' + springLang.eq_js_rem_pending + '</span></button>'; html += ' </div>'; html += ' </div>'; html += ' </div>'; if (bookingCost > 0) { var costDisplay = springSpace.formatCurrency(bookingCost); var costPreview = "\u007Bamount\u007D".replace("\u007Bamount\u007D", costDisplay).replace("\u007Brate\u007D", ""); html += '<label class="col-md-3 control-label s-lc-billing-cost-single">' + costPreview + '</label>'; } html += ' </div>'; html += ' </div>'; html += '</div>'; totalCost += bookingCost; } var bookingDurationOkay = true; if (pendingBookingsLimitIssues) { bookingDurationOkay = false; pendingBookingsLimitIssues.forEach(function(issueDetails) { var limitDisplay = issueDetails.allowed + issueTypeAdditionalText[issueDetails.type] + frequencyDisplayStrings[issueDetails.frequency]; var usedDisplay = issueDetails.used + issueTypeAdditionalText[issueDetails.type]; var issueDisplay = 'Sorry,\u0020you\u0020can\u0020only\u0020reserve\u0020\u007BlimitAmount\u007D,\u0020and\u0020you\u0020currently\u0020have\u0020\u007BusedAmount\u007D.\u0020Please\u0020adjust\u0020your\u0020booking.'.replace('{limitAmount}', limitDisplay).replace('{usedAmount}', usedDisplay); var issueHtml = '<strong>' + issueDetails.group + '</strong>: ' + issueDisplay; html += '\ <div class="form-group">\ <div class="col-md-offset-1 col-md-10">\ <div class="alert alert-warning">' + issueHtml + '</div>\ </div>\ </div>'; }); } if (totalCost > 0) { html += '\ <div class="form-group s-lc-pending-booking">\ <label class="col-md-5 control-label">Total\u0020cost\u0020for\u0020this\u0020reservation\u003A</label>\ <label class="col-md-5 control-label s-lc-billing-cost-total">' + springSpace.formatCurrency(totalCost) + '</label>\ </div>'; } html += '</div>'; // show the booking form box which contains the booking well, the terms + conditions and the booking form jQuery("#s-lc-eq-form-box").show(); // put the item in the displayed cart + set the window focus to the cart var roomCart = jQuery("#s-lc-eq-bwell"); roomCart.empty(); roomCart.html(html); roomCart.focus(); // disable the add equipment and form submission buttons until the times are okay jQuery("#submit_times, #eq_cart").prop('disabled', !bookingDurationOkay); // setup delete icon tooltips accessibleIcons(); // make the tooltip for the cart icon jQuery("#eq_cart").tooltip({ title: springLang.eq_js_cart_tt, html: true, container: "body" }); jQuery('.b-end-date').on('change', function() { var changedBooking = jQuery(this); updatePendingBookingDuration(changedBooking); }); } function preparePendingBookingsPayload() { var payload = []; for (var i = 0; i < pendingRoomBookings.length; i++) { var bookingInfo = pendingRoomBookings[i]; payload.push({ id: bookingInfo.id, eid: bookingInfo.eid, seat_id: bookingInfo.seat_id, gid: bookingInfo.gid, lid: bookingInfo.lid, start: bookingInfo.start.format(springSpace.phpDateTimeFormat), end: bookingInfo.end.format(springSpace.phpDateTimeFormat), checksum: bookingInfo.checksum, }); } return payload; } function updatePendingBookingsFromData(bookings) { pendingRoomBookings = []; for (var i = 0; i < bookings.length; i++) { var booking = bookings[i]; pendingRoomBookings.push({ id: booking.id, eid: booking.eid, seat_id: booking.seat_id, gid: booking.gid, lid: booking.lid, cost: booking.cost, checksum: booking.checksum, name: booking.name, start: moment(booking.start), end: moment(booking.end), options: booking.options, optionSelected: booking.optionSelected, optionChecksums: booking.optionChecksums, }); } } function pendingRoomBookingsUpdateListAndAvailability(payload, fcInstance) { // if we are adding rooms, we might need to hide the previous booking success message jQuery("#s-lc-eq-success").hide(); workingAlert(); // find out booking information jQuery.ajax({ type: "post", url: "/spaces/availability/booking/add", data: payload, dataType: "json", }) .always(stopAlert) .done(function(data) { if (data.error) { if (data.isRefreshRequired) { fcInstance.refetchEvents(); } return errorAlert(data.error); } // success! the entire pending bookings array can be re-created now pendingBookingsLimitIssues = data.limitIssues; updatePendingBookingsFromData(data.bookings); // this request might have came back with updated grid data // if it did not - refresh the whole grid if (data.gridUpdateData) { updateGridEventsForItem(data.gridUpdateData, fcInstance); } else if (fcInstance) { fcInstance.refetchEvents(); } renderPendingRoomBookings(); }) .fail(ajaxErrorHandler); return false; } function createStartTimeToClassMap(gridData) { var startTimeToClassMap = {}; gridData.forEach(function(gridElement) { var startMoment = moment(gridElement.start); startTimeToClassMap[startMoment.format(dateFormatStartTimeDict)] = [gridElement.className]; }); return startTimeToClassMap; } function updateGridEventsForItem(gridUpdateData, fcInstance) { var changedItemId = gridUpdateData.itemId; var changedRangeStart = moment(gridUpdateData.dateStart, springSpace.phpDateTimeFormat); var changedRangeEnd = moment(gridUpdateData.dateEnd, springSpace.phpDateTimeFormat); var startTimeToClassMap = createStartTimeToClassMap(gridUpdateData.gridData); fcInstance.batchRendering(function() { fcInstance.getEvents().forEach(function (clientEvent) { if (clientEvent.extendedProps.itemId !== changedItemId) { return; } var clientEventStart = moment(clientEvent.start); // if this event is before the day of events that was changed - forget it // and we only want to process events that start before the changed range "end" if (clientEventStart.isBefore(changedRangeStart) || !clientEventStart.isBefore(changedRangeEnd)) { return; } var startKey = clientEventStart.format(dateFormatStartTimeDict); if (startKey in startTimeToClassMap) { // this slot is unavailable clientEvent.setProp('classNames', startTimeToClassMap[startKey]); clientEvent.setExtendedProp('status', 1); } else { // this slot is available clientEvent.setProp('classNames', ["s-lc-eq-avail"]); clientEvent.setExtendedProp('status', 0); } }); }); } function timeGridClickedOnAvailableRoom(calEvent, fcInstance) { var resource = calEvent.getResources()[0]; var resourceData = resource.extendedProps; var timeslotData = calEvent.extendedProps; var view = fcInstance.view; var payload = { add: { eid: resourceData.eid, seat_id: resourceData.seatId, gid: resourceData.gid, lid: resourceData.lid, start: moment(calEvent.start).format(springSpace.phpDateTimeFormat), checksum: timeslotData.checksum, }, lid: 14617, gid: 30464, start: moment(view.activeStart).format(dateFormatDayOfYear), end: moment(view.activeEnd).format(dateFormatDayOfYear), bookings: preparePendingBookingsPayload(), } return pendingRoomBookingsUpdateListAndAvailability(payload, fcInstance); } function updatePendingBookingDuration(changedBooking) { var fcInstance = getCurrentTimelineInstance(14617); var view = fcInstance.view; var selectedElement = changedBooking.find(':selected'); var payload = { update: { id: changedBooking.data('booking'), checksum: selectedElement.data('crc'), end: changedBooking.val() }, lid: 14617, gid: 30464, start: moment(view.activeStart).format(dateFormatDayOfYear), end: moment(view.activeEnd).format(dateFormatDayOfYear), bookings: preparePendingBookingsPayload(), } return pendingRoomBookingsUpdateListAndAvailability(payload, fcInstance); } function removePendingBooking(pendingId, locationId) { var timeline = getCurrentTimelineInstance(locationId); var view = timeline.view; var payload = { removeId: pendingId, lid: 14617, gid: 30464, start: moment(view.activeStart).format(dateFormatDayOfYear), end: moment(view.activeEnd).format(dateFormatDayOfYear), bookings: preparePendingBookingsPayload(), } return pendingRoomBookingsUpdateListAndAvailability(payload, timeline); } function formatEventsForFullCalendar(events) { events.forEach(function(eventData) { eventData.resourceId = "eid_" + eventData.itemId; if (eventData.className) { // this slot is unavailable eventData.status = 1; eventData.classNames = [eventData.className]; } else { // this slot is available eventData.classNames = ["s-lc-eq-avail"]; eventData.status = 0; } }); return events; } function timeGridRoomFetchEventsForTimePeriod(start, end, callback, lid, gid, eid) { var data = { lid: lid, gid: gid, eid: eid, seat: springyPage.isSeatBooking, seatId: springyPage.seatId, zone: springyPage.zoneId, filters: springyPage.filterIds, start: moment(start).format(dateFormatDayOfYear), end: moment(end).format(dateFormatDayOfYear), bookings: preparePendingBookingsPayload(), pageIndex: springyPage.pageIndex, pageSize: springyPage.pageSize, }; var url = '/spaces/availability/grid'; if (typeof springyPage.autoCreateBookingDate === 'string') { url = '/spaces/availability/grid/pre-create' data.autoCreateBookingDate = springyPage.autoCreateBookingDate; springyPage.autoCreateBookingDate = null; } springyCommon.closeAllPopups(); jQuery.ajax({ type: 'post', url: url, data: data, dataType: 'json', }) .done(function(data) { callback(formatEventsForFullCalendar(data.slots)); // sometimes on an initial view of the availability grid we auto-create a booking // (currently this is only possible via maps) if (data.isPreCreatedBooking) { updatePendingBookingsFromData(data.bookings); renderPendingRoomBookings(); } var isAtEndOfWindowLimit = data.windowEnd === true; jQuery('#s-lc-window-limit-warning').toggle(isAtEndOfWindowLimit); jQuery('.fc-next-button').prop('disabled', isAtEndOfWindowLimit); var selectorPrefix = ''; var isNextAvailableButtonWanted = (document.querySelector(selectorPrefix + '.s-lc-eq-avail') === null); jQuery(selectorPrefix + '.fc-goToNextAvailable-button').toggle(isNextAvailableButtonWanted); }) .fail(function(xhr) { // let fullcalendar know that the request has completed with no results callback([]); // and display the error to the user ajaxErrorHandler(xhr); }); } </script> </body> </html>