angularangular9angular17

How can i use angular-calendar in Angular 17?


I'm converting Angular 9 project into Angular 17 and one component got angular-calendar plugin which was last published an year ago,

in component.html it's implemented like this,

    <mwl-calendar-month-view
      *ngSwitchCase="CalendarView.Month"
      [viewDate]="viewDate"
      [events]="events"
      [refresh]="refresh"
      [activeDayIsOpen]="activeDayIsOpen"
      (dayClicked)="dayClicked($event.day)"
      (eventClicked)="handleEvent('Clicked', $event.event)"
      (eventTimesChanged)="eventTimesChanged($event)">
    </mwl-calendar-month-view>

in the component.ts i have imported the modules like following,

  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule,
    FormsModule,
    HttpClientModule,
    NgxDropzoneModule,
    CalendarModule.forRoot({
      provide: DateAdapter,
      useFactory: adapterFactory,
    }),
  ],

but still the component didn't get recognized, in component.html. getting errros like this,

NG8002: Can't bind to 'refresh' since it isn't a known property of 'mwl-calendar-day-view'.
1. If 'mwl-calendar-day-view' is an Angular component and it has 'refresh' input, then verify that it is included in the '@Component.imports' of this component.
2. If 'mwl-calendar-day-view' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@Component.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@Component.schemas' of this component. [plugin angular-compiler]

Solution

  • Here is a working example for angular standalone component, we need to import CalendarModule to the imports array of the standalone component, also ensure that we add the environment providers using importProvidersFrom so that the providers are available in the application

    full code

    import { Component, importProvidersFrom } from '@angular/core';
    import { provideAnimations } from '@angular/platform-browser/animations';
    import { bootstrapApplication } from '@angular/platform-browser';
    import 'zone.js';
    import {
      CalendarEvent,
      CalendarEventTimesChangedEvent,
      CalendarWeekViewBeforeRenderEvent,
      CalendarDayViewBeforeRenderEvent,
      CalendarModule,
      DateAdapter,
    } from 'angular-calendar';
    import { Subject } from 'rxjs';
    import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
    
    export const colors: any = {
      red: {
        primary: '#ad2121',
        secondary: '#FAE3E3',
      },
      blue: {
        primary: '#1e90ff',
        secondary: '#D1E8FF',
      },
      yellow: {
        primary: '#e3bc08',
        secondary: '#FDF1BA',
      },
    };
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [CalendarModule],
      template: `
        <mwl-calendar-month-view
          [viewDate]="viewDate"
          [events]="events"
          [activeDayIsOpen]="true"
          [refresh]="refresh"
          (eventTimesChanged)="eventTimesChanged($event)"
        >
        </mwl-calendar-month-view>
      `,
    })
    export class App {
      view: string = 'week';
      snapDraggedEvents = true;
    
      dayStartHour = 6;
      viewDate: Date = new Date();
    
      events: CalendarEvent[] = [
        {
          title: 'Draggable event',
          color: colors.yellow,
          start: new Date(),
          draggable: true,
        },
        {
          title: 'A non draggable event',
          color: colors.blue,
          start: new Date(),
        },
      ];
    
      refresh: Subject<any> = new Subject();
    
      eventTimesChanged({ event, newStart, newEnd }: any): void {
        event.start = newStart;
        event.end = newEnd;
        this.refresh.next(null);
      }
      public segmentIsValid(date: Date) {
        // valid if time is greater than 0800 andd less than 1700
        return date.getHours() >= 8 && date.getHours() <= 17;
      }
      beforeDayViewRender(day: CalendarDayViewBeforeRenderEvent): void {
        // day.body.hourGrid.forEach((hour) => {
        //   hour.segments.forEach((segment) => {
        //     if (!this.segmentIsValid(segment.date)) {
        //       delete segment.cssClass;
        //       segment.cssClass = 'cal-disabled';
        //     }
        //   });
        // });
      }
      beforeWeekViewRender(body: CalendarWeekViewBeforeRenderEvent): void {
        body.hourColumns.forEach((hourCol) => {
          hourCol.hours.forEach((hour) => {
            hour.segments.forEach((segment) => {
              if (!this.segmentIsValid(segment.date)) {
                delete segment.cssClass;
                segment.cssClass = 'cal-disabled';
              }
            });
          });
        });
      }
    }
    
    bootstrapApplication(App, {
      providers: [
        provideAnimations(),
        importProvidersFrom(
          CalendarModule.forRoot({
            provide: DateAdapter,
            useFactory: adapterFactory,
          })
        ),
      ],
    });
    

    Stackblitz Demo