Enhancing DHTMLX JavaScript Scheduler with a Custom Toolbar

When using JavaScript UI libraries in a web project, you have to be sure that your tool is customizable enough to meet specific requirements and user preferences. DHTMLX Scheduler is a feature-packed JS component for delivering calendar functionalities with ample customization options. Not to be unfounded, we want to show you how to enhance its interface with a custom toolbar.

This tutorial will guide you through creating a custom toolbar for our JavaScript scheduling calendar, including controls for searching events, adding new events, refreshing the event list, filtering by categories, switching between different views, and toggling themes. After following all steps described in this tutorial, that’s what you should get in the end:
Check the sample >

Setting the Stage

Before diving into the customization process, ensure you have the basic setup of the DHTMLX Scheduler on your page, as outlined in our documentation. The foundation of our custom toolbar will build upon the following initial HTML structure:

<div id="scheduler_here" class="dhx_cal_container" style='width:100%; height:100%;'>
    <div class="dhx_cal_navline">
        <div class="dhx_cal_prev_button"></div>
        <div class="dhx_cal_next_button"></div>
        <div class="dhx_cal_today_button"></div>
        <div class="dhx_cal_date"></div>
        <div class="dhx_cal_tab" data-tab="day"></div>
        <div class="dhx_cal_tab" data-tab="week"></div>
        <div class="dhx_cal_tab" data-tab="month"></div>
    </div>
    <div class="dhx_cal_header">
    </div>
    <div class="dhx_cal_data">
    </div>
</div>

Check the sample >

Crafting the Custom Toolbar

Our goal is to replace the default navigation within the dhx_cal_navline element with a custom toolbar that enhances functionality and aesthetics. Here’s how you can modify the HTML to include new controls:

<div id="scheduler_here" class="dhx_cal_container" style='width:100%; height:100%;'>
    <div class="dhx_cal_navline">
        <input type="text" id="event_search" placeholder="Search events">
        <button id="add_event">Add Event</button>
        <button id="refresh_events">Refresh</button>
        <select id="event_filter">
            <option value="all">All</option>
            <option value="meetings">Meetings</option>
            <option value="appointments">Appointments</option>
            <option value="personal">Personal</option>
        </select>
        <select id="view_selector">
            <option value="day">Day</option>
            <option value="week">Week</option>
            <option value="month">Month</option>
        </select>
        <button id="toggle_theme">Toggle Theme</button>
        <span id="current_date"></span>
        <button id="today_button">Today</button>
        <button id="prev_button">Previous</button>
        <button id="next_button">Next</button>
    </div>
    <div class="dhx_cal_header">
    </div>
    <div class="dhx_cal_data">
    </div>
</div>

Check the sample >
Pay attention to the addition of a view_selector dropdown for switching between Day, Week, and Month views, and a current_date span for displaying the currently viewed date.

Styling the Toolbar

To ensure our toolbar not only functions well but also looks the part, you add some CSS. These styles aim to create a modern and clean appearance that complements the Scheduler’s design:

.dhx_cal_navline button {
    padding: 8px 15px;
    border: none;
    border-radius: 4px;
    background-color: #007bff;
    color: white;
    cursor: pointer;
    font-size: 14px;
}

.dhx_cal_navline button:hover {
    background-color: #0056b3;
}

.dhx_cal_navline input, .dhx_cal_navline select {
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    font-size: 14px;
    background-color: white;
}

#current_date {
    font-weight: bold;
}

Check the sample >

Bringing the Toolbar to Life

With the HTML and CSS in place, the next phase of our tutorial will involve writing JavaScript to integrate the new toolbar controls with the DHTMLX Scheduler’s functionality. This includes implementing the search functionality, event filtering, view switching, theme toggling, and dynamically updating the displayed date.

Implementing Event Search Functionality

To facilitate event searching within the DHTMLX Scheduler, you’ll need to leverage the Scheduler’s filtering capabilities. This approach allows you to dynamically control which events are displayed based on the user’s search criteria. Here’s how to set it up:

Step 1: Define the Filter Function

First, you need to define a generic filter function that will be used across multiple views (Day, Week, Month). This function determines whether an event should be displayed based on the current filterValue.

let filterValue = ""; // Holds the current search term

function filterFunction(id, event) {
    // Check if the event's text includes the filterValue
    return event.text.toLowerCase().includes(filterValue.toLowerCase());
}

By converting both the event’s text and filterValue to lowercase, you ensure that the search is case-insensitive, making it more user-friendly.

Step 2: Apply the Filter Function to Scheduler Views

After that, you assign filterFunction to each of the Scheduler’s view filters. Thus, the custom filtering logic will be applied consistently across different calendar views.

scheduler.filter_day = scheduler.filter_week = scheduler.filter_month = filterFunction;
Step 3: Capture User Input for Filtering

Next, you set up an event listener on the search input to capture user input and update filterValue. Following the update, you call scheduler.render() to reapply the filters and update the display.

document.getElementById('event_search').addEventListener('input', function(e) {
    filterValue = e.target.value;
    scheduler.render(); // Rerender the scheduler to apply the filter
});

Check the sample >
As a result, when an end-user types into the search box, the calendar dynamically updates to show only the events that match the search term.

Full Example

Combining the above steps, here is how the JavaScript part integrates into the overall solution:

window.addEventListener("DOMContentLoaded", function() {
    // Initialize the scheduler here as per the previous setup
    // scheduler.init('scheduler_here', new Date(), "week");

    let filterValue = ""; // Holds the current search term

    function filterFunction(id, event) {
        // If filterValue is empty, don't filter out any events
        if (!filterValue) return true;
        // Otherwise, return true if the event text includes the filterValue
        return event.text.toLowerCase().includes(filterValue.toLowerCase());
    }

    // Apply the filter function to all views
    scheduler.filter_day = scheduler.filter_week = scheduler.filter_month = filterFunction;


    // Event listener for the search input
    document.getElementById('event_search').addEventListener('input', function(e) {
        filterValue = e.target.value;
        scheduler.render(); // Rerender the scheduler to apply the filter
    });

    scheduler.init('scheduler_here', new Date(2024, 3, 20), "week");

});
Implementing “Add Event” Button

The “Add Event” button enables users to quickly insert a new event into the scheduler. Using the scheduler.addEventNow() method, you can prompt the user with a form to enter the details of the new event. Here’s the JavaScript code to achieve this:

document.getElementById('add_event').addEventListener('click', function() {
    scheduler.addEventNow();
});

Check the sample >
This code listens for click events on the ‘Add Event’ button and calls scheduler.addEventNow(), which opens the scheduler’s event creation form.

Implementing “Refresh” Button

The “Refresh” button is designed to clear the current event data from the scheduler and reload it from a specified source. This is particularly useful for fetching the latest event data, ensuring the scheduler displays up-to-date information. You can implement this feature with the following code:

document.getElementById('refresh_events').addEventListener('click', function() {
    scheduler.clearAll();
    scheduler.load("/data");
});

Check the sample >
This code snippet attaches an event listener to the ‘Refresh’ button, which clears the scheduler’s current data using scheduler.clearAll() and then reloads it by calling scheduler.load(“/data”). Replace “/data” with the actual URL or endpoint where your event data is located.

Enhancing Event Management with Category Filtering

To further refine the custom toolbar for the DHTMLX Scheduler, you add a category-based event filtering feature. It will allow end-users to filter events displayed on the scheduler based on predefined categories such as “Meetings”, “Appointments”, and “Personal”. By utilizing the same filterFunction implemented for the search functionality, you can seamlessly incorporate category filtering.

Here’s a step-by-step instruction on how to do it:

Step 1: Update Filter Function

First, you need to modify filterFunction to account for both the search input and the selected category from the “event_filter” dropdown. You have to introduce an additional variable to hold the selected category value and update the filter logic accordingly:

let filterValue = ""; // Holds the current search term
let filterCategory = "all"; // Holds the selected category for filtering

function filterFunction(id, event) {
    // Check if the event matches the search term
    let matchesSearch = event.text.toLowerCase().includes(filterValue.toLowerCase());
    // Check if the event matches the selected category (or if 'all' is selected)
    let matchesCategory = filterCategory === "all" || event.category === filterCategory;


    return matchesSearch && matchesCategory;
}

In this updated filterFunction, check that an event matches both the search term and the selected category to be displayed.

Step 2: Capture Category Selection Changes

Next, it is necessary to add an event listener to the “event_filter” dropdown to update the filterCategory variable whenever the user selects a different category. After updating the variable, call scheduler.render() to reapply the filters and refresh the display:

document.getElementById('event_filter').addEventListener('change', function(e) {
    filterCategory = e.target.value;
    scheduler.render(); // Rerender the scheduler to apply the new filter
});

Check the sample >

Implementing View Selector

As part of custom toolbar enhancements for the DHTMLX Scheduler, let’s bring the view selector introduced earlier into action. This control allows end-users to easily switch between the Day, Week, and Month views, enhancing the application’s navigational experience directly from the toolbar. Here’s how to activate the view selector:

Activating the View Selector

To make the view selector operational, you should add an event listener that updates the scheduler’s current view based on the user’s selection. This functionality is crucial for providing a seamless user interface that allows for flexible viewing options. The following JavaScript code snippet accomplishes this:

document.getElementById('view_selector').addEventListener('change', function(e) {
    let view = e.target.value;
    scheduler.setCurrentView(null, view); // Update the scheduler to the selected view
});

Check the sample >
This code listens for changes to the view selector and calls scheduler.setCurrentView(null, view), effectively updating the scheduler’s display to the selected view. The null argument signifies that the scheduler should use the current date when switching views, ensuring a smooth transition for end-users.

Theme Toggle Button

It is great to have at your disposal built-in themes to adjust the UI appearance to your preference. To make things more convenient, let us show you how to integrate a theme toggle button in your custom toolbar.

Toggling Between Light and Dark Themes

To achieve this, you add an event listener to the “Toggle Theme” button. This listener checks the current theme of the scheduler and switches it accordingly:

document.getElementById('toggle_theme').addEventListener('click', function() {
    if (scheduler.skin === "terrace") {
        scheduler.setSkin("dark");
    } else {
        scheduler.setSkin("terrace");
    }
});

Check the sample >
This feature will enable end-users to switch between the terrace (light) and dark themes on their preference with a single click.

Implementing Navigation Functionality
Today Button

The “Today” button should reset the scheduler’s view to the current date. This button can be added with the following piece of JavaScript code:

document.getElementById('today_button').addEventListener('click', function() {
    scheduler.setCurrentView(new Date(), scheduler.getState().mode);
});
Previous and Next Buttons

The “Previous” and “Next” buttons allow end-users to navigate to the adjacent date range based on the current view (Day, Week, Month). Here’s how to set them up:

// Previous Button
document.getElementById('prev_button').addEventListener('click', function() {
    scheduler.setCurrentView(scheduler.date.add(scheduler.getState().date, -1, scheduler.getState().mode), scheduler.getState().mode);
});

// Next Button
document.getElementById('next_button').addEventListener('click', function() {
    scheduler.setCurrentView(scheduler.date.add(scheduler.getState().date, 1, scheduler.getState().mode), scheduler.getState().mode);
});

Check the sample >
These buttons utilize the scheduler.date.add() method to calculate the date to switch to, ensuring compatibility across different views.

Updating the Displayed Date

To keep end-users informed of the current date range or day being viewed, you can dynamically update a span in the toolbar with the current date information. This enhances the scheduler’s usability by providing context to the displayed events.

Dynamically Displaying the Current Date

You need to utilize the Scheduler’s onViewChange event to update the current_date element whenever the view or date range changes:

scheduler.attachEvent("onViewChange", function (new_mode, new_date) {
    const {min_date, max_date, mode} = scheduler.getState();
    document.getElementById("current_date").innerHTML = scheduler.templates[`${new_mode}_date`](min_date, max_date, mode);
});

This setup ensures that the displayed date always reflects the current view, whether it’s a specific day, week, or month, enhancing the overall coherence and functionality of the scheduler interface.

Conclusion

Throughout this article, we’ve explored how to significantly enhance the DHTMLX Scheduler by adding a custom toolbar. This toolbar not only improves the application’s aesthetics but also introduces powerful features that enhance user interaction and accessibility. By implementing a search functionality, category-based event filtering, dynamic view switching, a theme toggle button, and an automatically updating current date display, we’ve provided users with a comprehensive toolset to manage and navigate their schedules efficiently.

Advance your web development with DHTMLX

Gantt chart
Event calendar
Diagram library
30+ other JS components