Not long ago, you learned how to make the DHTMLX Scheduler and Booking components work smoothly on the frontend. Now, it is time to share with you instructions on key points required for integrating these components on the backend, namely, data conversion.
Conversion Algorithm of Scheduler Events to Booking Events
In our demo, the integration between these DHTMLX components takes place on the server side. We will go through the data conversion algorithm that allows various types of Scheduler events to be converted into corresponding Booking events (slots). In this blog post, we’ll show how to generate time slots in the booking system from doctors’ schedules using JSON data.
Before we start exploring the peculiarities of converting scheduler events into Booking events used in our demo, you should get acquainted with the key parameters in both widgets that play an important role in the conversion process of different event types.
For Scheduler events, you’ll need to know parameters such as duration (start_time, end_time) as well as extra properties related to recurring series. As for Booking, you’ll need to get acquainted with id, slotSize, SlotGap, and slots parameters, which are clearly explained in this section of the Booking API.
NOTE: In our scenario, each scheduler event has the doctor_id property that corresponds to the ID of the booking event and points to the ID of a specific doctor in the system.
In this blog post, samples for demonstrating the conversion process span from 2025-05-08 to 2027-05-08.
Conversion of Regular Events
A regular (single) event is a basic type of event in DHTMLX Scheduler that occurs once, but may last from one to several days. Let us consider how to convert both variations of regular events into Booking events:
- Regular One-Day Event
If you need to create a regular one-day event, it is necessary to convert the Scheduler’s start_date and end_date parameters to from, to, and dates parameters of Booking events as shown below:
Scheduler event:
"doctor_id": 1,
"start_date": "2025-05-08 02:00:00",
"end_date": "2025-05-08 06:00:00"
}
Booking event:
"id": 1,
"slotSize": 20,
"slotGap": 5,
"slots": [
{
"from": "02:00",
"to": "06:00",
"dates": [1746662400000] // 2025-05-08
}
]
}
- Regular Multi-Day Event
Since Booking can only generate slots within one day, you need to split a multi-day event into the required number of slots, one for each day.
For instance, let us consider the conversion of a Scheduler event that starts at 8 PM on one day and ends at 4 AM on the next day:
Scheduler event:
"doctor_id": 1,
"start_date": "2025-05-08 20:00:00",
"end_date": "2025-05-09 04:00:00"
}
Booking event:
"id": 1,
"slotSize": 20,
"slotGap": 5,
"slots": [
{
"from": "20:00",
"to": "24:10",
"dates": [1746662400000] // 2025-05-08
},
{
"from": "00:10",
"to": "04:00",
"dates": [1746748800000] // 2025-05-09
}
]
}
Conversion of Recurring Events
Recurring events in Scheduler include all parameters of a regular event and several extra parameters:
- rrule – defines the rule of repetition,
- duration – the duration of the recurring instance.
Here, it is important to remember that Booking supports only weekly events! It means that the rrule parameter can comply with the following pattern only:
where … – listing of weekdays. For example:
When it comes to creating recurring events in Booking i.e., converting Scheduler events into Booking slots, you’ll need one more slot parameter, namely, days. It refers to days of the week when a slot can be booked.
There are several scenarios for the conversion of Scheduler recurring events into Booking events:
- Recurring Event
In case of a basic recurring event, you need to convert start_date and duration to from and to and transform rrule in days:
Scheduler event:
"doctor_id": 2,
"start_date": "2025-05-08 09:00:00",
"end_date": "2027-05-08 00:00:00",
"rrule": "INTERVAL=1;FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
"duration": 28800 // 8 hours in seconds
}
Booking event:
"id": 2,
"slotSize": 45,
"slotGap": 5,
"slots": [
{
"from": "09:00",
"to": "17:00",
"days": [1, 2, 3, 4, 5] // Monday to Friday
}
]
}
- Multi-day Event in Recurring Series
It works similarly to regular multi-day events, but in this scenario, you need to split days rather than dates:
Scheduler event:
"doctor_id": 2,
"start_date": "2025-05-08 20:00:00",
"end_date": "2027-05-08 00:00:00",
"rrule": "INTERVAL=1;FREQ=WEEKLY;BYDAY=TH",
"duration": 28800 // 8 hours in seconds
}
Booking event:
"id": 2,
"slotSize": 45,
"slotGap": 5,
"slots": [
{
"from": "20:00",
"to": "24:10",
"days": [4] // Tuesday
},
{
"from": "00:10",
"to": "04:00",
"days": [5] // Wednesday
}
]
}
- Recurring Event + Regular Event
For this scenario, it is important to emphasize that a regular event has a higher priority than a recurring one in Booking. More info on the matter is provided in the info section of this documentation page.
Scheduler events:
// regular event
{
"doctor_id": 2,
"start_date": "2025-05-10 02:00:00",
"end_date": "2025-05-10 06:00:00"
},
// recurring event
{
"doctor_id": 2,
"start_date": "2025-05-08 09:00:00",
"end_date": "2027-05-08 00:00:00",
"rrule": "INTERVAL=1;FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA",
"duration": 28800 // 8 hours in seconds
}
]
In this example, the date of the regular event (May 10th) is added to the rule of rendering for recurring slots in Booking so that it is not excluded by a regular event taking place on the same day.
Booking event:
"id": 2,
"slotSize": 45,
"slotGap": 5,
"slots": [
{
"from": "02:00",
"to": "06:00",
"dates": [1746835200000] // 2025-05-10
},
{
"from": "09:00",
"to": "17:00",
"days": [0, 1, 2, 3, 4, 5, 6],
"dates": [1746835200000] // 2025-05-10 (added)
}
]
}
- Start Date Discrepancy
It is important to take into account the fact that Booking cannot identify specific start dates for slots with days, while recurring events in Scheduler usually have these details. It brings up the question of how to deal with this discrepancy during data conversion.
For instance, if the event is created on Thursday and should be repeated on Thursdays and Fridays, starting next week, Booking won’t be able to identify the exact start date for this recurring event i.e. whether it should be started this or next week.
To solve this issue, you need to create “empty” slots (slots with “00:00” values in from and to parameters and specific dates) that will block displaying of slots on Thursdays and Fridays of the week when the events should not occur as in the example below:
Scheduler event:
"doctor_id": 2,
"start_date": "2025-05-15 09:00:00", // next Thursday
"end_date": "2027-05-08 00:00:00",
"rrule": "INTERVAL=1;FREQ=WEEKLY;BYDAY=TH,FR",
"duration": 28800 // 8 hours in seconds
}
Booking event:
"id": 2,
"slotSize": 45,
"slotGap": 5,
"slots": [
{ "from": "09:00", "to": "17:00", "days": [4, 5] },
{ "from": "00:00", "to": "00:00", "dates": [
1746662400000, // 2025-05-08 - Thursday
1746748800000 // 2025-05-09 - Friday
]}
]
}
And what if your series should include some events that do not follow recurring rules? These are exceptions and we’ll consider them in the following section.
Conversion of Exception Events
In DHTMLX Scheduler, events with modified settings (or deleted ones) in recurring series are called exceptions. They are stored as separate records related to their parent series. Under the hood, exceptions are specified with three additional parameters for modified or deleted instances of the series:
- recurring_event_id – ID of the parent recurring series,
- original_start – the original date and time of the edited instance in the recurring series (i.e. before editing),
- deleted – the deleted instance of the series.
Using these properties, you can specify modified or deleted instances and how they are related to the parent series.
When converting exception events to slots, you’ll also need to create an “empty” slot.
- Editing a Single Instance in Recurring Series
Any instance in the series is converted as a regular event, and an “empty” slot must be created for its initial date.
In the code sample below, we have recurring events for Thursdays and Fridays, where the instance on Friday the 9th is rescheduled for Saturday the 10th.
Scheduler events:
{
"id": 1,
"doctor_id": 3,
"start_date": "2025-05-08 09:00:00",
"end_date": "2027-05-08 00:00:00",
"rrule": "INTERVAL=1;FREQ=WEEKLY;BYDAY=TH,FR",
"duration": 28800 // 8 hours in seconds
},
{
"doctor_id": 3,
"start_date": "2025-05-10 09:00:00",
"end_date": "2025-05-10 12:00:00",
"recurring_event_id": "1",
"original_start": "2025-05-09 09:00"
}
]
Booking event:
"id": 3,
"slotSize": 30,
"slotGap": 10,
"slots": [
{
"from": "09:00",
"to": "17:00",
"days": [4, 5]
},
// modified slot
{
"from": "09:00",
"to": "12:00",
"dates": [1746835200000] // 2025-05-10
},
// “empty” slot
{
"from": "00:00",
"to": "00:00",
"dates": [1746748800000] // 2025-05-09
}
]
}
NOTE: If an exception event has only modified time (the date is the same), you don’t need to create an “empty” slot for the initial date of the exception event.
- Excluding a Single Instance from a Recurring Series
Instead of removed date, you need to create a new “empty” slot:
Scheduler event:
{
"id": 1,
"doctor_id": 3,
"start_date": "2025-05-08 09:00:00",
"end_date": "2027-05-08 00:00:00",
"rrule": "INTERVAL=1;FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR",
"duration": 28800 // 8 hours in seconds
},
{
"doctor_id": 3,
"start_date": "2025-05-09 09:00:00",
"end_date": "2025-05-09 17:00:00",
"recurring_event_id": "1",
"original_start": "2025-05-09 09:00",
"deleted": true
}
]
Booking event:
"id": 3,
"slotSize": 30,
"slotGap": 10,
"slots": [
{
"from": "09:00",
"to": "17:00",
"days": [1, 2, 3, 4, 5] // Monday to Friday
},
// “empty” slot
{
"from": "00:00",
"to": "00:00",
"dates": [1746748800000] // 2025-05-09
}
]
}
Booked Slots
When Scheduler events are modified (i.e. rescheduled), it may affect booked slots based on these events. By default, Booking won’t display booked slots if they are unavailable after slots are regenerated from edited events. But if this scenario is not good for you, there are two possible solutions:
- Disable editing of scheduler events for time intervals containing any booked slots.
- If regenerated slots do not contain the same options as already booked slots, you block the reservation of two neighbouring slots on both sides to keep the booked slots relevant.
We adhere to the second approach, which is vividly demonstrated with the following code samples:
Scheduler event:
"doctor_id": 4,
"start_date": "2025-05-09 09:00:00",
"end_date": "2027-05-09 15:00:00"
}
Booked slots:
1746781200000, // 2025-05-09 09:00
1746792000000 // 2025-05-09 12:00
]
According to our approach, it is necessary to create usedSlots from the array of booked slots so that the booking system could identify which time slots should be blocked.
Booking event:
"id": 4,
"slotSize": 60,
"slotGap": 10,
// 09:00 10:10 11:20 12:30 13:40 (time slots)
"slots": [
{
"from": "09:00",
"to": "15:00",
"dates": [1746748800000] // 2025-05-09
}
],
"usedSlots": [
1746781200000, // 2025-05-09 09:00 (no changes)
1746789600000, // 2025-05-09 11:20 (was 2025-05-09 12:00)
1746793800000 // 2025-05-09 12:30 (was 2025-05-09 12:00)
]
}
These are the main cases of event conversion between DHTMLX Scheduler and Booking based on specific rules. However, the full-fledged backend integration of these DHTMLX tools also requires creating endpoints for data exchange between the client and server sides. You can learn more about this aspect in the documentation.
The source code of the backend integration is available in our GitHub repository.
Conclusion
This blog post covers the main aspects required for integrating DHTMLX Scheduler and Booking on the backend. Together with front-end insights provided in the previous article, you have enough knowledge to combine these components within a single app. It can be a great solution for web projects demanding both flexible visual scheduling and a user-friendly booking experience.