We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Adding a resourceHeaderTemplate stops the content from rendering

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');
        }
    }

}

1 Reply

HB Hareesh Balasubramanian Syncfusion Team April 9, 2019 01:28 PM UTC

Hi Pieter, 

Greetings from Syncfusion solution. 

We have checked the shared code and prepared sample based on it in which schedular renders properly. We have shared the sample for your reference which can be viewed from the following link. 

Note: In your shared code id mapping is wrong for schedular instance. 

  @ViewChild('timelineSchedule'
  public scheduleObj: ScheduleComponent; 

Please try the above sample and if the issue persist kindly try to reproduce the issue in the sample. 

Regards, 
Hareesh B 


Loader.
Up arrow icon