> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Blocking Off Time in the Wix Bookings Calendar ## Article: Blocking Off Time in the Wix Bookings Calendar ## Article Link: https://dev.wix.com/docs/develop-websites/articles/code-tutorials/wix-bookings/blocking-off-time-in-the-wix-bookings-calendar.md ## Article Content: # Velo: Blocking Off Time in the Wix Bookings Calendar The Wix Bookings backend module lets you manage bookings resources using Velo APIs. When managing staff resource schedules, a common use case is setting up the times that staff are available, and the times that they're not. What if you want to block off some time in the middle of the work day when your staff resource is not available ? You can do this by using the `createSession()` function to create "blocked time".  To set up blocked time, you need to create a session of type `"EVENT"` with a tag value of `"Blocked"`. The session can be a [single session or a recurring session](https://www.wix.com/velo/reference/wix-bookings-backend/sessions/introduction#wix-bookings-backend_sessions_introduction_recurrence). In the first example, we'll create a function that takes a resource ID and creates a single blocked time session on the resource's schedule. We'll also see how to create a dropdown element containing all of your resources. Once we have that working, in the second example, we'll add some functionality to make recurring blocked time sessions. Let's assume you already have some staff members defined. If you don't, take a look at [Creating Bookings Resources using Velo](https://dev.wix.com/docs/develop-websites/articles/code-tutorials/wix-bookings/creating-bookings-resources-using-velo.md), or create some using the dashboard [Staff](https://www.wix.com/my-account/site-selector/?buttonText=Select%20Site&title=Select%20a%20Site&autoSelectOnSingleSite=true&actionUrl=https:%2F%2Fwww.wix.com%2Fdashboard%2F%7B%7BmetaSiteId%7D%7D%2Fbookings/staff) page.
Before we go on, you need to install the Bookings app. If you haven't installed it yet, here's how to do it. 1. Select the Add Apps icon in the editor.
2. Type "Bookings" in the search field and select the Wix Bookings App. 3. Click "Add to Site."
### Setting up our site page
Create a page with the elements shown above. Put the **Recurrence Rule** text and **inRecurrenceRule** input element inside the container box **box1**. In the Properties and Events panel for **box1**, select **Collapsed** under **Default Values**. Set the **default text** as shown above for the **From**, **To**, and **Recurrence Rule** input elements. >**Timestamps and Recurrence Rules.** > Make sure that the format of the timestamps and recurrence rule are correct. To reduce complexity, we are not going to validate them in this tutorial. > > Timestamp example: `2021-06-15T13:00:00.000-05:00`  > > Recurrence Rule example: `FREQ=WEEKLY;INTERVAL=1;BYDAY=MO;UNTIL=20220101T000000Z`. #### Query Resources to Load the Dropdown Element. We'll load the dropdown element with a list of resources, display the resource name and use the resource ID as the value. Create a backend file called `blockedSessions.web.js`. This file will hold all of our backend code for this tutorial.   First import the `Permissions` enum and `webMethod` function from `wix-web-module`, and then import the `resources` and `sessions` APIs from the `wix-bookings-backend` module. ```javascript import { Permissions, webMethod } from 'wix-web-module'; import { resources, sessions } from "wix-bookings-backend"; ``` Create a function called `getResourceList()` that returns an array of all resources. The code will look like this: ```javascript import { Permissions, webMethod } from 'wix-web-module'; import { resources, sessions } from 'wix-bookings-backend'; export const getResourceList = webMethod(Permissions.Anyone, async () => { try { const results = await resources.queryResourceCatalog().find(); return results.items; } catch (error) { return error; } }); ``` Now in your page code, create the `loadResourceDropdown()` function to load the dropdown element. Call the `loadResourceDropdown()` function from the `onReady` code block so the dropdown is loaded when the page is displayed.  Don't forget to import `getResourceList` from the APIs from the `blockedSessions` backend file.  Add the following code to your page to load the  `ddResource` dropdown with resource names and their schedule IDs: * Call `getResourceList()` to get a list of all of your resources.  * Use the  `map` function to build the `resourceSchedules` array from the resource name and scheduleId for each resource in the `resourceCatalog` array. * Set the `options` property of the dropdown element to the array of resource names and schedule IDs. ```javascript import { getResourceList, createSingleBlockedSession } from 'backend/blockedSessions.web' $w.onReady(function () { loadResourceDropdown(); }); export async function loadResourceDropdown() { let resourceCatalog = await getResourceList(); const resourceSchedules = resourceCatalog.map(resource1 => { let resourceEntry = { label: resource1.resource.name, value: resource1.resource.scheduleIds[0] }; return resourceEntry; }); $w('#ddResource').options = resourceSchedules; } ``` Now create an `onClick` function for the button that will gather the information we need, and call the function to create the blocking sessions. ```javascript export async function btnCreateSession_click(event) { let fromDateTime = $w('#inFrom').value; let toDateTime = $w('#inTo').value; let scheduleID = $w('#ddResource').value; try { const session = await createSingleBlockedSession(scheduleID, fromDateTime, toDateTime); console.log("Session", session); } catch (err) { console.error("Session creation failed.", err); } } ``` ### Create A Single Blocked Time Now we can create our blocking session. Create a function in the `blockedSessions.web.js` backend code file called `createSingleBlockedSession()`. ```javascript export const createSingleBlockedSession = webMethod(Permissions.Anyone, async (resourceScheduleId, startDate, endDate) => { try { const sessionInfo = { scheduleId: resourceScheduleId, start: { timestamp: new Date(startDate), }, end: { timestamp: new Date(endDate), }, type: "EVENT", tags: ["Blocked"], }; const options = { suppressAuth: true }; return sessions.createSession(sessionInfo, options); } catch (error) { console.error(error); // Handle the error } }); ``` #### Understanding the code. **Line 4:** Create the `sessionInfo` object using the date from the function's parameters. **Lines 12,13:** Set the session `type` to "`EVENT`" and the `tag` to "`Blocked`". **Line 16:** If you want any user to be able to create a blocked time session, set the `suppressAuth` option to `true`. **Line 17:** Call `createSession()` to create the blocked time session and return the session details to the calling function. This returns to the page code that called the `createSingleBlockedSession()` function, and the created session is displayed in the console. The returned session looks like this: ```json { "_id": "2mmoW0vwKcSFyxtOfCdMeoE8hsC05dc6rdVucf52tUuT6FFcAWCPTKHipQaFL7nOW9qlB9c6Fjm00bZxYfABQpF6kQSpWw6TqFx7", "scheduleId": "278012f1-674e-4a2b-93d2-29f8894ee732", "scheduleOwnerId": "3cdb6d0f-be29-450b-a2e0-184975d95cb3", "start": { "timestamp": "Tue Jun 15 2021 23:00:00 GMT+0300 (Israel Daylight Time)" }, "end": { "timestamp": "Wed Jun 16 2021 00:00:00 GMT+0300 (Israel Daylight Time)" }, "status": "CONFIRMED", "tags": [ "Blocked" ], "type": "EVENT", "notes": "" } ``` ### Recurring Blocked Times Now that we've seen single blocked times working, let's take it up a level and create a series of blocked times using recurrence rules. Recurrence rules specify when and how often an event repeats. A session that repeats every second week on a Monday until January 7, 2022 at 8 AM, is specified using the following recurrence rule:`"FREQ=WEEKLY;INTERVAL=2;BYDAY=MO;UNTIL=20220107T080000Z"` #### Page Code When we defined our page, we set the container box to `collapsed`. Expand the box based on the checkbox `cbRecurrence` using the following code: ```javascript export function cbRecurring_click(event) { if ($w('#cbRecurring').checked === true) { $w('#box1').expand(); } else { $w('#box1').collapse(); } } ``` Now that we see the recurrence rule, we can use it to create recurring sessions. Update the button's `onClick`  function with the code below, to add processing for recurring sessions. If the `cbRecurring` checkbox is checked, call  `createRecurringBlockedSession()`, passing the recurrence rule. Otherwise, call `createSingleBlockedSession().` ```javascript export async function btnCreateSession_click(event) { let fromDateTime = $w('#inFrom').value; let toDateTime = $w('#inTo').value; let scheduleID = $w('#ddResource').value; let recurrenceRule = $w('#inRecurrenceRule').value; console.log(scheduleID, fromDateTime, toDateTime); let session = ""; try { if ($w('#cbRecurring').checked) { session = await createRecurringBlockedSession(scheduleID, fromDateTime, toDateTime, recurrenceRule); } else { session = await createSingleBlockedSession(scheduleID, fromDateTime, toDateTime); } console.log("Session", session); } catch (err) { console.error("Session creation failed.", err); } } ``` #### Create A Recurring Blocked Time Session Now we can create our recurring blocking session. Create a function in the `blockedSessions.web.js` backend code file called `createRecurringBlockedSession().` In your page code, add `createRecurringBlockedSession` to your `import` statement. >**Note:** > You must use the `localDateTime` objects for `start` and `end` when defining a recurring session. For single sessions you can use the `timestamp` properties. > Remember that `localDateTime` uses the business's timezone . ```javascript export const createRecurringBlockedSession = webMethod(Permissions.Anyone, async (resourceScheduleId, startDate, endDate, recurrenceRule) => { try { //Create the recurring session object, breaking the start and end dates into their components. const sessionInfo = { scheduleId: resourceScheduleId, start: { localDateTime: { year: startDate.substr(0, 4), monthOfYear: startDate.substr(5, 2), dayOfMonth: startDate.substr(8, 2), hourOfDay: startDate.substr(11, 2), minutesOfHour: startDate.substr(14, 2), }, }, end: { localDateTime: { year: endDate.substr(0, 4), monthOfYear: endDate.substr(5, 2), dayOfMonth: endDate.substr(8, 2), hourOfDay: endDate.substr(11, 2), minutesOfHour: endDate.substr(14, 2), }, }, // Set the session type to "EVENT" and add "Blocked" to the tags array. type: "EVENT", tags: ["Blocked"], recurrence: recurrenceRule, }; //Set the option to suppress permissions checking. const options = { suppressAuth: true }; return sessions.createSession(sessionInfo, options); } catch (error) { console.error(error); // Handle the error } }); ``` #### Understanding The Code **Line 5:** Create the sessionInfo object. You have to break the dates into their components for the `localDateTime` objects. You cannot use the `timestamp` properties for recurring sessions. **Line 26:** Set the session `type` to `"EVENT"`. **LIne 27:** Add `"Blocked"` to the `tags` array. **Line 32:** If you want any user to be able to create a blocked time session, set the `suppressAuth` option to `true`. **Line 33:** Call `createSession()` using the `sessionInfo` and `options` objects, and return the promise to the calling function on the site page. You'll get a session object displayed on the console, similar to the one below. ```json { "_id": "ce6e440d1ef941c08f0e317d75fe5cbc-885c479078d145f992b2bad2a2b5f151", "notes": "", "recurrence": "FREQ=WEEKLY;INTERVAL=1;BYDAY=TU;UNTIL=20220101T000000Z", "scheduleId": "ce6e440d-1ef9-41c0-8f0e-317d75fe5cbc", "scheduleOwnerId": "3df00036-ac5a-4f8b-bf0d-4f77b1795b1d", "start": { "localDateTime": { "year": 2021, "monthOfYear": 7, "dayOfMonth": 1, "hourOfDay": 9, "minutesOfHour": 0 } }, "end": { "localDateTime": { "year": 2021, "monthOfYear": 7, "dayOfMonth": 1, "hourOfDay": 10, "minutesOfHour": 0 } }, "status": "UNDEFINED", "tags": [ "Blocked" ], "type": "EVENT" } ``` ### Check that it Worked. In addition to the returned session object, you can also check your [calendar](https://www.wix.com/my-account/site-selector/?buttonText=Select%20Site&title=Select%20a%20Site&autoSelectOnSingleSite=true&actionUrl=https:%2F%2Fwww.wix.com%2Fdashboard%2F%7B%7BmetaSiteId%7D%7D%2Fbookings/scheduler/owner/calendar) to confirm that the blocked time appears for your resource at the time that you specified.
### All the Code Below is all of the code used in the tutorial in one place. #### Page Code ```javascript import { getResourceList, createSingleBlockedSession ,createRecurringBlockedSession} from 'backend/blockedSessions.web' $w.onReady(function () { loadResourceDropdown(); }); export async function loadResourceDropdown() { let resourceCatalog = await getResourceList() const resourceSchedules = resourceCatalog.map(resource1 => { let resourceEntry = { label: resource1.resource.name, value: resource1.resource.scheduleIds[0] } return resourceEntry }) $w('#ddResource').options = resourceSchedules; } export async function btnCreateSession_click(event) { let fromDateTime = $w('#inFrom').value; let toDateTime = $w('#inTo').value; let scheduleID = $w('#ddResource').value; let recurrenceRule = $w('#inRecurrenceRule').value; console.log(scheduleID, fromDateTime, toDateTime); let session = ""; try { if ($w('#cbRecurring').checked) { session = await createRecurringBlockedSession(scheduleID, fromDateTime, toDateTime, recurrenceRule); } else { session = await createSingleBlockedSession(scheduleID, fromDateTime, toDateTime); } console.log("Session", session); } catch (err) { console.error("Session creation failed.", err); } } export function cbRecurring_click(event) { if ($w('#cbRecurring').checked === true) { $w('#box1').expand() } else { $w('#box1').collapse() } } ``` #### blockedSessions.web.js ```javascript import { Permissions, webMethod } from "wix-web-module"; import { resources, sessions } from "wix-bookings-backend"; export const getResourceList = webMethod(Permissions.Anyone, async () => { try { const results = await resources.queryResourceCatalog().find(); return results.items; } catch (error) { throw error; } }); export const createSingleBlockedSession = webMethod(Permissions.Anyone, async (resourceScheduleId, startDate, endDate) => { const sessionInfo = { scheduleId: resourceScheduleId, start: { timestamp: new Date(startDate), }, end: { timestamp: new Date(endDate), }, type: "EVENT", tags: ["Blocked"], }; const options = { suppressAuth: true }; try { return await sessions.createSession(sessionInfo, options); } catch (error) { throw error; } }); export const createRecurringBlockedSession = webMethod(Permissions.Anyone, async (resourceScheduleId, startDate, endDate, recurrenceRule) => { //Create the recurring session object, breaking the start and end dates into their components. const sessionInfo = { scheduleId: resourceScheduleId, start: { localDateTime: { year: startDate.substr(0, 4), monthOfYear: startDate.substr(5, 2), dayOfMonth: startDate.substr(8, 2), hourOfDay: startDate.substr(11, 2), minutesOfHour: startDate.substr(14, 2), }, }, end: { localDateTime: { year: endDate.substr(0, 4), monthOfYear: endDate.substr(5, 2), dayOfMonth: endDate.substr(8, 2), hourOfDay: endDate.substr(11, 2), minutesOfHour: endDate.substr(14, 2), }, }, // Set the session type to "EVENT" and add "Blocked" to the tags array. type: "EVENT", tags: ["Blocked"], recurrence: recurrenceRule, }; //Set the option to suppress permissions checking. const options = { suppressAuth: true }; try { return await sessions.createSession(sessionInfo, options); } catch (error) { throw error; } }); ```