I’m using the Syncfusion Scheduler in TimelineWeek view to manage a calendar of equipment bookings, organized in a resource hierarchy:
Category → Subcategory → Equipment
Each equipment item has a very long description, and I’m displaying it using the resourceHeaderTemplate, like this:
resourceHeaderTemplate: props => {
const col = props.resourceData.color || '#eee';
return `
<div class="my-resource-header"
style="background:${col};color:${getContrastColor(col)}">
${props.resourceData.text}
</div>`;
}
I enabled rowAutoHeight: true and also use a helper function to manually sync the row heights:
function forceContentRowHeightSync(retries = 10) {
const resTableRows = document.querySelectorAll('.e-resource-table tbody tr');
const contentTableRows = document.querySelectorAll('.e-content-table tbody tr.e-content-row');
const count = Math.min(resTableRows.length, contentTableRows.length);
for (let i = 0; i < count; i++) {
const resourceCell = resTableRows[i].querySelector('.my-resource-header');
const height = resourceCell ? resourceCell.offsetHeight : resTableRows[i].offsetHeight;
resTableRows[i].style.height = `${height}px`;
resTableRows[i].style.minHeight = `${height}px`;
contentTableRows[i].style.height = `${height}px`;
contentTableRows[i].style.minHeight = `${height}px`;
}
if (retries > 0) {
requestAnimationFrame(() => forceContentRowHeightSync(retries - 1));
}
}
This function is called inside dataBound, contentReady, and actionComplete events.
When a resource (equipment) has a long description, the left-hand resource cell grows taller to fit the content, but the corresponding timeline row on the right does not grow in height, leading to visual misalignment between the two.
Here’s an image to illustrate the issue:
What I’ve Tried:
- Enabled rowAutoHeight: true
- Enabled allowRowHeightAdjustment: true
- Applied consistent box-sizing, padding, and font-size to both sides
- Applied CSS: white-space: normal, overflow-wrap: anywhere, etc.
- Used a JavaScript offsetHeight sync as shown above
Is there an official or recommended way to ensure proper row height alignment between the resource table (left) and content table (right) in Timeline views of the Syncfusion Scheduler?
Am I missing something in the templating or row height syncing logic?
window.scheduleObj = new ej.schedule.Schedule({
height: 'auto',
width: '100%',
rowAutoHeight: true,
allowRowHeightAdjustment: true,
selectedDate: new Date(2025, 5, 9),
locale: 'it',
cssClass: 'custom-scheduler',
currentView: 'TimelineWeek',
views: [
{ option: 'TimelineWeek', displayName: 'Settimana' },
{ option: 'TimelineMonth', displayName: 'Mese' },
{ option: 'Agenda', displayName: 'Agenda' }
],
agendaViewSettings: { allowVirtualScrolling: false, hideEmptyAgendaDays: false },
group: { resources: ['Categorie', 'Sottocategorie', 'Mezzi'], byGroupID: true, allowGroupEdit: false },
timeScale: { enable: false },
showQuickInfo: true,
allowResizing: false,
showHeaderBar: true,
eventSettings: {
dataSource: eventi,
fields: {
subject: { name: 'Subject', title: 'Titolo' },
startTime: { name: 'StartTime' },
endTime: { name: 'EndTime' },
isAllDay: { name: 'IsAllDay' }
}
},
resources: [
{
field: 'CategoriaId', title: 'Categoria', name: 'Categorie',
dataSource: risorse.categorie, textField: 'text', idField: 'id', colorField: 'color'
},
{
field: 'SottocategoriaId', title: 'Sottocategoria', name: 'Sottocategorie',
dataSource: risorse.sottocategorie, textField: 'text', idField: 'id',
groupIDField: 'groupID', colorField: 'color'
},
{
field: 'MezzoId', title: 'Mezzo', name: 'Mezzi',
dataSource: risorse.mezzi, textField: 'text', idField: 'id',
groupIDField: 'groupID', colorField: 'color'
}
],
resourceHeaderTemplate: props => {
const col = props.resourceData.color || '#eee';
return `
<div class="my-resource-header"
style="background:${col};color:${getContrastColor(col)}">
${props.resourceData.text}
</div>`;
},
eventRendered: args => {
const sc = risorse.sottocategorie.find(x => x.id === args.data.SottocategoriaId);
const col = sc?.color || '#607d8b';
args.element.style.backgroundColor = col;
args.element.style.borderColor = col;
args.element.style.color = getContrastColor(col);
},
dataBound: () => setTimeout(() => forceContentRowHeightSync(), 100),
contentReady: () => setTimeout(() => forceContentRowHeightSync(), 100),
actionComplete: args => {
if (['view','dateNavigate','resourceExpand','resourceCollapse'].includes(args.requestType)) {
setTimeout(() => forceContentRowHeightSync(), 100);
}
}
});
scheduleObj.appendTo('#scheduleContainer');
});
This is my css file
.e-resource-text,
.my-resource-header {
white-space: normal !important;
word-break: break-word;
overflow-wrap: anywhere;
}
.disabled-cell {
background-color: #ff0000 !important;
pointer-events: none;
opacity: 0.6;
}
.e-schedule .e-resource-column {
width: 130px !important;
max-width: none !important;
white-space: normal !important;
word-wrap: break-word;
}
.e-schedule .e-timeline-month-view .e-work-cells.e-parent-node.e-resource-group-cells.e-work-days,
.e-schedule .e-timeline-week-view .e-work-cells.e-resource-group-cells.e-work-hours,
.e-schedule .e-timeline-week-view .e-resource-group-cells,
.e-schedule .e-timeline-month-view .e-work-cells.e-parent-node.e-resource-group-cells {
background-color: #e8e5e5 !important;
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
#scheduleContainer {
min-height: 600px;
overflow: visible;
position: relative;
}
.e-schedule .e-resource-table th,
.e-schedule .e-resource-table td,
.e-schedule .e-content-table th,
.e-schedule .e-content-table td {
box-sizing: border-box;
}
.my-resource-header {
padding: 8px 12px;
border-radius: 8px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
white-space: normal;
line-height: 1.2;
height: 100%;
box-sizing: border-box;
}
.custom-scheduler .e-resource-column .e-resource-cell {
overflow: hidden;
padding: 0 !important;
}
.custom-scheduler .e-content-table .e-work-cells,
.custom-scheduler .e-content-table .e-work-hours {
box-sizing: border-box;
padding: 8px 12px;
overflow: hidden;
}
.custom-scheduler .e-content-table tbody tr.e-content-row td {
box-sizing: border-box;
padding: 8px 12px;
}
.e-schedule .e-resource-table td,
.e-schedule .e-content-table td {
padding-top: 8px !important;
padding-bottom: 8px !important;
}
