Adding A Scheduler Component To Your React App

Bryntum Scheduler supports ReactReact (also known as React.js or ReactJS) is a JavaScript library for building user interfaces. It is maintained by Facebook and a community of individual developers and companies. React makes it easier to create interactive views that react to changes in data and update accordingly.

Views implemented as components makes code more predictable and easier to debug and they encapsulate and manage their own state. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.

The React paradigm is that “everything is JavaScript” and that the JavaScript generates the HTML that is necessary to visualize the components. The generated markup is automatically updated based on the logic programmed in the components.

React does not ship with rich UI components such as grid, tree, form elements, graphs or similar so the React developer often has to resort to incorporating 3rd party widgets, such as the Bryntum component suite.

This article will describe how to use Bryntum Scheduler in a React application.

Important Note

Success in implementing the example described in this article requires a dedicated effort of the reader to understand explanations and the related code. Also, don’t slip into heedless copy&paste “development” but always try to understand the currently executed step. In many cases it is only necessary to know whata component or a function does and we don’t need to know how it does it. We are also very willing to assist you in our forums in the case you can’t find an adequate answer elsewhere.

Bryntum Scheduler in React

The Bryntum Scheduler itself is framework agnostic, but it ships with demos and wrappers to simplify using it with popular frameworks such as React. The purpose of this guide is to give you a basic introduction on how to use Scheduler with React.

The Scheduler ships with plenty of React demos which run either in development mode or can be built for production. They are located in the examples/react/javascript folder. The demos are ready for direct viewing (in production mode) here: React Integration Examples.


The React demos have been created using create-react-app script so that they can be run locally by running npm start in their respective directories, or they can be built for production by running npm run build.

The examples use our React wrapper (BryntumScheduler.js), which is a React component that uses Scheduler as an internal engine. The wrapper is at this point a basic implementation, but feel free to extend it to cover your needs.

The exceptions to the above are Localization and Advanced examples that use the Bryntum scheduler component directly without a wrapper.

Installing the Scheduler npm package

The Scheduler package contains all the Bryntum Scheduler code together with supporting widgets and utilities in the form of a module that can be installed with the npm package manager. The package is located in the build folder of the unzipped Bryntum Scheduler distribution. Run this code to install it:

npm install --save Scheduler/build

Scheduler/build should be the path to the Scheduler’s build folder and it can be a relative path. The result is the entry for bryntum-scheduler in your package.json:

"dependencies": {
    "bryntum-scheduler": "file:../../../../build"
    ... other dependencies
}

Using the BryntumScheduler wrapper

To use the BryntumScheduler wrapper, simply follow these steps:

  1. Copy BryntumScheduler.js from examples/react/_shared/src/lib to a directory in your project, for example src/components. Note: You can also copy other files from the shared library or from the examples if you want or if they contain the functionality similar to your needs.
  2. Import the wrapper in your file that will use it:
    import BryntumScheduler from './components/BryntumScheduler'

    Note: You may also take another approach instead of copying wrapper and other files to your project tree. You may want to create a separate package, a library, that would contain the wrapper and other useful files. This approach would be preferred especially when you use scheduler in several projects and you want to share the common part(s) among them.

    We use this approach in our examples. See the source of _shared folder for details. This folder contains package bryntum-react-shared that is then imported from in the examples sources. For example:

    import { BryntumScheduler } from 'bryntum-react-shared'
  3. Use it in your code at the place you need it the way similar to the following:
    <BryntumScheduler
        ref        = {scheduler}
        autoHeight = {true}
        startDate  = {new Date(2019, 5, 17, 18)}
        endDate    = {new Date(2019, 5, 17, 20)}
        // other properties
    />

The wrapper defines a React component named BryntumScheduler. You can use it the same way as you would use other React components. Here's an example of a very simple one-file application:

// the scheduler wrapper
import BryntumScheduler from './components/BryntumScheduler.js';
import React, { Component} from 'react'

export default class App extends Component {

    state = {
        events    : [ ... ],
        resources : [ ... ]
    };

    handleSelectionChange = (event) => {
        // Code to take action when an event is selected goes here
    };

    render() {
        return (
            <BryntumScheduler
                ref = {'scheduler'}

                events    = {this.state.events}
                resources = {this.state.resources}

                startDate = {new Date(2020, 1, 7, 8)}
                endDate   = {new Date(2020, 1, 7, 18)}

                onEventSelectionChange = {this.handleSelectionChange}
            />
        );
    }
}

As you can see in the example above, the component can be configured using props and it handles state and events.

Supported options

The React component supports the following configuration options:

It also supports configuring the following features:

Please note that features are distinguished from config options by a Feature suffix and are passed to the underlying engine feature with the suffix stripped. Thus, sortFeature will become feature.sort in the Bryntum Scheduler (schedulerEngine).

For example, to disable creating events by dragging on an empty area and define a default sorter:

<BryntumScheduler
    eventDragCreateFeature = {false}
    sortFeature            = {'name'}
/>

The Native Bryntum Scheduler Instance

It is important to know that the React component that we may even call "scheduler" is not the native Bryntum Scheduler instance, it remains to be a wrapper or an interface between the React application and the Bryntum Scheduler itself.

The majority of properties and features are configured on the wrapper and passed through to the underlying Bryntum Scheduler instance but there might be situations where you want to access the Bryntum Scheduler instance directly. This is fully valid approach and you are free to do it.

Accessing The Scheduler Engine

To access any Scheduler functionality not directly exposed by the wrapper, you can access the Scheduler engine directly. Within the wrapper it is available as this.schedulerEngine, from the outside it would look something like this:

<BryntumScheduler
    ref = {'scheduler'}
/>
// From within your React app
this.refs.scheduler.schedulerEngine.scrollEventIntoView(xx);

When accessing the schedulerEngine directly, please use API docs to know which properties and methods you may use and the valid parameter types.

Using Scheduler Without The Wrapper

You can also use the Scheduler directly if you prefer. In this case you must ensure that you pass the scheduler configuration to the component and that you take care of propagation of changes from your upper level components to the scheduler as necessary.

If you use React Hooks (available from React version 16.8.0) your code may look as follows:

import schedulerConfig from './components/schedulerConfig';

// refs
const
    scheduler = useRef(),
    firstRun  = useRef(true);

// create scheduler (initial, run-once)
useEffect(() => {
    scheduler.current = new Scheduler({
        ...schedulerConfig,
        appendTo : 'content'
    });
}, []);

// handles zoom level change
useEffect(() => {
    if (!firstRun.current) {
        const method = props.zoomLevel >= scheduler.current.zoomLevel ? 'zoomIn' : 'zoomOut';
        scheduler.current[method]();
    }
    else {
        firstRun.current = false;
    }
}, [props.zoomLevel]);

schedulerConfig above would be the object that contains the complete configuration for the Scheduler component. It is best to keep that configuration in a separate file (as it can get quite long).

Include/import CSS

For the scheduler styling you must also import a css file that contains you preferred theme of the scheduler. In our examples we import CSS in App.js file as follows:

import 'bryntum-scheduler/scheduler.stockholm.css';

If you don not want to use the bryntum-scheduler package feel free to copy the CSS file with the theme of your liking from the build directory to a suitable place in your project tree.

Troubleshooting

If you see a failure like the one below, it is probably your linter not accepting our bundle. Please try to exclude our bundle completely from being checked by any linters. In case you use "eslint", add /* eslint-disable */ to the top of the bundle.

./src/build/scheduler.module.js
  Line 9:   Unexpected use of 'self'                           no-restricted-globals
  Line 9:   Unexpected use of 'self'                           no-restricted-globals
  Line 10:   'jQuery' is not defined                           no-undef expressions
  Line 160:  'view' is not defined                             no-undef
  Line 160:  'centered' is not defined                         no-undef
  Line 162:  Unexpected use of 'location'                      no-restricted-globals
  Line 162:  Unexpected use of 'location'                      no-restricted-globals
  Line 162:  Unexpected use of 'location'                      no-restricted-globals
  Line 162:  'bryntum' is not defined                          no-undef
  Line 162:  'dataLayer' is not defined

If you face issues building or running our examples, they can often be resolved by running the following commands in the example or the project directory:

rm -rf package-lock.json node_modules # or the Windows equivalent
npm install
npm run build

Further reading

  • For more information on config options, features, events and methods consult please the API docs
  • For more information on React see the React docs
  • For more information on the Create React App scripts see the documentation
  • If you have any questions related to the integration or the Scheduler itself you can always ask our developers in our forums

Leave a Comment