So i was wondering if we can render custom react component in the header cell, the reason for this is we want to add bunch of buttons for the name cell, such as expand all, create new button like below:
The left most arrows controls expand and collapse all, and on the right we have the create and sort icons. There is a headerRender function that only accepts strings, i was only able to pass rendered react cells but cannot add event handler function, as i believe the functions are stripped during parsing in bryntum.
Is there any way to render react components like we can do in the column renderer function for cells?
Installing listeners to the header elements that are created by returning html from the headerRenderer is not that difficult. I've modified out Gantt basic example the following way:
I tried passing in the reference to the component that i'm rendering the bryntum gannt component in, in my case it's returning an error:
Cannot read property 'addEventListener' of null
at Function.addElementListener (gantt.module.js?3374:10)
at Function.on (gantt.module.js?3374:10)
at Gantt.paint (TimelineCalendar.tsx?8102:179)
at Gantt.trigger (gantt.module.js?3374:10)
at Gantt.triggerPaint (gantt.module.js?3374:10)
at Gantt.render (gantt.module.js?3374:10)
at Gantt.render (gantt.module.js?3374:10)
at Gantt.render (gantt.module.js?3374:67)
at Gantt.render (gantt.module.js?3374:82)
at functionChainRunner (gantt.module.js?3374:10)
/**
* Application
*/
// Polyfills for Edge <= 18. Remove this line if you don't need support for it.
import 'core-js/stable';
import React, { Fragment, useCallback, useRef } from 'react';
import { BryntumDemoHeader, BryntumThemeCombo, BryntumGantt } from '@bryntum/gantt-react';
import { EventHelper } from '@bryntum/gantt/gantt.umd';
import { ganttConfig } from './AppConfig';
import './App.scss';
const App = () => {
const ganttRef = useRef(null); // ganttRef holds the reference to the React component (Gantt wrapper)
// edit button click handler
const handleEditClick = ({ record, grid: gantt }) => {
gantt.editTask(record);
};
const handleHeaderButtonClick = useCallback(() => {
console.log('Header button clicked')
},[]);
// listeners object is passed directly to the underlying native Bryntum Gantt component
const listeners = {
// here we install the listener that runs on paint of the Gantt
paint({ firstPaint }) {
if (firstPaint) {
EventHelper.on({
// we are inside of the paint listener that by default run in the scope of Bryntum Gantt so this is the Gantt
// we install listener on Gantt element
element: this.element,
// the listener will only listen to events that match this selector
delegate: 'button.my-button',
capture:true,
// we install click listener
click: event => {
event.stopPropagation();
handleHeaderButtonClick();
}
})
}
}
}
return (
<Fragment>
<BryntumDemoHeader
title="React Basic demo"
href="../../../../../#example-frameworks-react-javascript-basic"
children={<BryntumThemeCombo />}
/>
<BryntumGantt
ref={ganttRef}
{...ganttConfig}
listeners={listeners}
extraData={{ handleEditClick }}
/>
</Fragment>
);
};
export default App;
Should you still have problems, post please a runnable showcase, we will help you to sort it out.
I was able to make this work, though i think your initial reference created the confusion. In your snippet this.element does not exist here:
paint({ firstPaint }) {
if (firstPaint) {
EventHelper.on({
// we are inside of the paint listener that by default run in the scope of Bryntum Gantt so this is the Gantt
// we install listener on Gantt element
element: this.element,
Hence i was getting the error i mentioned above, instead paint returns an event object with params {firstPaint, source}
I used source.currentElement to attach the listener which is the Gantt element. Now it's working!