I am trying to recreate a similar solution like the one in your documentation: Room scheduler The component is rendering and the data is shown when I don't use the resourceHeaderTemplate. If I add this, I only see the header of the Schedule component and can't do anything else. While rendering, I don't receive any errors, only when I click something (change the date for example) are there errors that 'str.replace is not a function'.
I am using the same data as in the documentation and the code is also the same.
This is my template:
<ejs-schedule #timelineSchedule
[selectedDate]="selectedDate"
[eventSettings]="eventSettings"
[timeScale]="timeScale"
[group]="group"
(eventRendered)="onEventRendered($event)"
(actionBegin)="onActionBegin($event)"
(renderCell)="onRenderCell($event)"
(popupOpen)="onPopupOpen($event)">
<e-resources>
<e-resource field='RoomId' [dataSource]='resourceDataSource' idField='id' colorField='color' textField='text' name='MeetingRoom' [allowMultiple]='allowMultiple'></e-resource>
</e-resources>
<e-views>
<e-view option="TimelineDay"></e-view>
</e-views>
<ng-template #resourceHeaderTemplate let-data>
<div class='template-wrap'>
<div class="name">{{data.resourceData.text}}</div>
<div class="type">{{data.resourceData.type}}</div>
<div class="capacity">{{data.resourceData.capacity}}</div>
</div>
</ng-template>
</ejs-schedule>
And this is the component:
import { Component, OnInit, Inject, ViewChild, ViewEncapsulation } from '@angular/core';
import { ScheduleComponent, ActionEventArgs, PopupOpenEventArgs, EventRenderedArgs, RenderCellEventArgs, DragAndDropService,
TimelineViewsService, GroupModel, EventSettingsModel, ResizeService, TimeScaleModel, WorkHoursModel, View } from '@syncfusion/ej2-angular-schedule';
import { extend, isNullOrUndefined, Browser } from '@syncfusion/ej2-base';
@Component({
selector: 'app-timeline-table',
templateUrl: './timeline-table.component.html',
styleUrls: ['./timeline-table.component.css'],
encapsulation: ViewEncapsulation.None,
providers: [TimelineViewsService, ResizeService, DragAndDropService]
})
export class TimelineTableComponent {
public selectedDate: Date = new Date(2018, 7, 1);
public timeScale: TimeScaleModel = { interval: 60, slotCount: 1 };
public workHours: WorkHoursModel = { start: '08:00', end: '18:00' };
public currentView: View = 'TimelineDay';
public group: GroupModel = {
enableCompactView: false,
resources: ['MeetingRoom']
};
public resourceDataSource: Object[] = [
{ text: 'Jammy', id: 1, color: '#ea7a57', capacity: 20, type: 'Conference' },
{ text: 'Tweety', id: 2, color: '#7fa900', capacity: 7, type: 'Cabin' },
{ text: 'Nestle', id: 3, color: '#5978ee', capacity: 5, type: 'Cabin' },
{ text: 'Phoenix', id: 4, color: '#fec200', capacity: 15, type: 'Conference' },
{ text: 'Mission', id: 5, color: '#df5286', capacity: 25, type: 'Conference' },
{ text: 'Hangout', id: 6, color: '#00bdae', capacity: 10, type: 'Cabin' },
{ text: 'Rick Roll', id: 7, color: '#865fcf', capacity: 20, type: 'Conference' },
{ text: 'Rainbow', id: 8, color: '#1aaa55', capacity: 8, type: 'Cabin' },
{ text: 'Swarm', id: 9, color: '#df5286', capacity: 30, type: 'Conference' },
{ text: 'Photogenic', id: 10, color: '#710193', capacity: 25, type: 'Conference' }
];
public allowMultiple: Boolean = true;
public eventSettings: EventSettingsModel = {
dataSource: <Object[]>extend([], roomData, null, true),
fields: {
id: 'Id',
subject: { title: 'Summary', name: 'Subject' },
location: { title: 'Location', name: 'Location' },
description: { title: 'Comments', name: 'Description' },
startTime: { title: 'From', name: 'StartTime' },
endTime: { title: 'To', name: 'EndTime' }
}
};
@ViewChild('scheduleObj')
public scheduleObj: ScheduleComponent;
constructor() { }
isReadOnly(endDate: Date): boolean {
return (endDate < new Date(2018, 6, 31, 0, 0));
}
onPopupOpen(args: PopupOpenEventArgs): void {
let data: { [key: string]: Object } = <{ [key: string]: Object }>args.data;
if (args.type === 'QuickInfo' || args.type === 'Editor' || args.type === 'RecurrenceAlert' || args.type === 'DeleteAlert') {
let target: HTMLElement = (args.type === 'RecurrenceAlert' ||
args.type === 'DeleteAlert') ? (args.data as any).element[0] : args.target;
if (!isNullOrUndefined(target) && target.classList.contains('e-work-cells')) {
if ((target.classList.contains('e-read-only-cells')) ||
(!this.scheduleObj.isSlotAvailable(data.startTime as Date, data.endTime as Date, data.groupIndex as number))) {
args.cancel = true;
}
} else if (!isNullOrUndefined(target) && target.classList.contains('e-appointment') &&
(this.isReadOnly(data.EndTime as Date))) {
args.cancel = true;
}
}
}
onActionBegin(args: ActionEventArgs): void {
if (args.requestType === 'eventCreate' || args.requestType === 'eventChange') {
let data: { [key: string]: Object } = args.data as { [key: string]: Object };
let groupIndex: number = this.scheduleObj.eventBase.getGroupIndexFromEvent(data);
if (!this.scheduleObj.isSlotAvailable(data.StartTime as Date, data.EndTime as Date, groupIndex as number)) {
args.cancel = true;
}
}
}
onRenderCell(args: RenderCellEventArgs): void {
if (args.element.classList.contains('e-work-cells')) {
if (args.date < new Date(2018, 6, 31, 0, 0)) {
args.element.setAttribute('aria-readonly', 'true');
args.element.classList.add('e-read-only-cells');
}
}
if (args.elementType === 'resourceHeader') {
args.element.innerHTML = '<div><p>' + this.resourceDataSource[args.groupIndex]['text'] + '</p><p>' + this.resourceDataSource[args.groupIndex]['capacity'] + ' ' + this.resourceDataSource[args.groupIndex]['type'] + '</p></div>'
}
}
onEventRendered(args: EventRenderedArgs): void {
let data: { [key: string]: Object } = args.data;
if (this.isReadOnly(data.EndTime as Date)) {
args.element.setAttribute('aria-readonly', 'true');
args.element.classList.add('e-read-only');
}
}
}