Our pure JavaScript Scheduler component


Post by bernhard »

We have a React-component that is rendering the scheduler like this:

const Component = () => { 
   const locale = useLocaleContext();
   const presets = createPresets(locale);
   return <SchedulerPro presets={presets} ... />
}

Upon changing the locale the dateFormat in the headers-array of the presets change from e. g. a german to a english representation:

    headers: [
      {
        unit: 'week',
        increment: 1,
        dateFormat: '{KW} W',
      },
    ],

changed to:

    headers: [
      {
        unit: 'week',
        increment: 1,
        dateFormat: '{CW} W',
      },
    ],

Unfortunately, the component does not rerender itself and the old presets are still visible. As soon as I move the zoom-slider, the component repaints itself and everything is fine. But this seems too late.


Post by saki »

Post please a runnable code that we will be able to run, investigate and debug. We need to sort out if it is a problem in how React handles changes or a problem in our wrappers or components.


Post by bernhard »


Post by saki »

I've run the code you provided and I found that presets are changed successfully but to you need to say which of them to use afterwards. Try the following App.js:

/**
 * The React App file
 */

// React libraries
import React, { useEffect, useRef, useState } from 'react';

// Stylings
import './App.scss';

// Application components
import { BryntumSchedulerPro, BryntumButtonGroup } from '@bryntum/schedulerpro-react';
import { schedulerConfig } from './AppConfig';

const hourAndDayConfig = {
    base: 'hourAndDay',
    tickWidth: 70,
    tickHeight: 40,
    displayDateFormat: 'll LT',
    shiftIncrement: 1,
    shiftUnit: 'day',
    defaultSpan: 24,
    timeResolution: {
        increment: 30,
        unit: 'MINUTE'
    }
};

const weekAndDayConfig = {
    base: 'weekAndDay',
    tickWidth: 100,
    tickHeight: 80,
    displayDateFormat: 'll hh:mm A',
    shiftUnit: 'week',
    shiftIncrement: 1,
    defaultSpan: 1,
    mainHeaderLevel: 0,
    timeResolution: {
        increment: 1,
        unit: 'HOUR'
    }
};

export const presetData = lang => [
    {
        ...weekAndDayConfig,
        id: 'weekAndDay',
        name: 'week and day',
        tickWidth: 50,

        timeResolution: {
            unit: 'hour',
            increment: 1
        },
        shiftIncrement: 1,
        shiftUnit: 'day',
        headers: [
            {
                unit: 'week',
                increment: 1,
                dateFormat: lang === 'de' ? '{KW} W' : '{CW} W'
            },
            {
                unit: 'day',
                increment: 1,
                dateFormat: 'D MMM'
            }
        ]
    },
    {
        ...hourAndDayConfig,
        id: 'oneDay',
        name: 'oneDay',
        tickWidth: 65,
        headers: [
            {
                unit: 'day',
                increment: 1,
                dateFormat: 'dddd, DD MMMM YYYY'
            },
            {
                unit: 'hour',
                increment: 1,
                dateFormat: 'HH:mm A'
            }
        ]
    }
];

const newLocal = [
    {
        text: 'de',
        pressed: true
    },
    {
        text: 'en'
    }
];
const App = () => {
    const schedulerRef = useRef();
    const [lang, setLang] = useState('de');
    const [presets, setPresets] = useState(presetData(lang));

    const handler = button => {
        setLang(button.source.text);
    };

    useEffect(() => {
        const presets = presetData(lang);
        setPresets(presets);
    }, [lang]);

    useEffect(() => {
        schedulerRef.current.instance.viewPreset = presets[0];
    }, [presets]);

    return (
        <>
            <div className="demo-toolbar">
                <label>Language: </label>
                <BryntumButtonGroup toggleGroup={true} items={newLocal} onAction={handler} />
            </div>
            <BryntumSchedulerPro ref={schedulerRef} {...schedulerConfig} presets={presets} />
        </>
    );
};

export default App;

Post by bernhard »

Thank you for your suggestion. I removed one useEffect() in order to reduce the amount of render cycles since presets are not needed within App anyway:

const App = () => {
    const schedulerRef = useRef();
    const [lang, setLang] = useState('de');

    const handler = button => {
        setLang(button.source.text);
    };

    useEffect(() => {
        const presets = presetData(lang);
        schedulerRef.current.instance.presets = presets;
        schedulerRef.current.instance.viewPreset = presets[0];
    }, [lang]);

    return (
      <>
          <div className="demo-toolbar">
              <label>Language: </label>
              <BryntumButtonGroup toggleGroup={true} items={newLocal} onAction={handler} />
          </div>
          <BryntumSchedulerPro ref={schedulerRef} {...schedulerConfig} />
      </>
    );
};

Post by saki »

So all works now, right?


Post by bernhard »

Yes, you can close the ticket. Sorry, for not mentioning.


Post Reply