Our pure JavaScript Scheduler component


Post by Txim »

Hello,
I did the integration steps one by one and i'm trying integrate the angular 7 example on my Angular project.

The project have app.routing.ts and the module that I attach is working fine without the tag component (angular 7 example).

I created a component for tets, put inside the example and this following code is what I have on it...

First, the error that chrome is showing me.

core.js:12584 ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[SchedulerComponent -> ElementRef]: 
  StaticInjectorError(Platform: core)[SchedulerComponent -> ElementRef]: 
    NullInjectorError: No provider for ElementRef!
Error: StaticInjectorError(AppModule)[SchedulerComponent -> ElementRef]: 
  StaticInjectorError(Platform: core)[SchedulerComponent -> ElementRef]: 
    NullInjectorError: No provider for ElementRef!
    at NullInjector.push../node_modules/@angular/core/fesm5/core.js.NullInjector.get (core.js:717)
    at resolveToken (core.js:954)
    at tryResolveToken (core.js:898)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:795)
    at resolveToken (core.js:954)
    at tryResolveToken (core.js:898)
    at StaticInjector.push../node_modules/@angular/core/fesm5/core.js.StaticInjector.get (core.js:795)
    at resolveNgModuleDep (core.js:17739)
    at NgModuleRef_.push../node_modules/@angular/core/fesm5/core.js.NgModuleRef_.get (core.js:18428)
    at resolveNgModuleDep (core.js:17739)
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at zone.js:873
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:14134)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1540)

scheduletest.module.ts

import { NgModule, ErrorHandler } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from 'src/app/shared/shared.module';
import { RouterModule } from '@angular/router';
import { AuthGuard } from 'src/app/auth.guard';
import { Scheduletest1Component } from './scheduletest1/scheduletest1.component';
import { Scheduletest2Component } from './scheduletest2/scheduletest2.component';
import { Scheduletest3Component } from './scheduletest3/scheduletest3.component';
import { Scheduletest4Component } from './scheduletest4/scheduletest4.component';
import { BryntumAngularSharedModule} from 'bryntum-angular-shared';
import { AppErrorHandler } from './error.handler';


export const routes = [
  { path: '', redirectTo: 'scheduletest', pathMatch: 'full' },
  { path: 'scheduletest', component: Scheduletest1Component, data: { breadcrumb: 'Schedule Test 1' }, canActivate: [AuthGuard] },
  { path: 'scheduletest2', component: Scheduletest2Component, data: { breadcrumb: 'Schedule Test 2' }, canActivate: [AuthGuard] },
  { path: 'scheduletest3', component: Scheduletest3Component, data: { breadcrumb: 'Schedule Test 3' }, canActivate: [AuthGuard] },
  { path: 'scheduletest4', component: Scheduletest4Component, data: { breadcrumb: 'Schedule Test 4' }, canActivate: [AuthGuard] },
];

@NgModule({
  declarations: [
    Scheduletest1Component,
    Scheduletest2Component,
    Scheduletest3Component,
    Scheduletest4Component

  ],
  imports: [
    CommonModule,
    RouterModule.forChild(routes),
    BryntumAngularSharedModule,
    SharedModule,
 
  ],
  exports: [
  ],

  entryComponents: [
    
], providers: [{ provide : ErrorHandler, useClass : AppErrorHandler } ] }) export class ScheduleTestModule { }

scheduletest1.component.ts

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import { SchedulerComponent } from 'bryntum-angular-shared';
import { HttpClient } from '@angular/common/http';
import { DateField, DateHelper } from 'bryntum-schedulerpro/schedulerpro.lite.umd.js';

declare var window: any;

@Component({
  selector: 'app-scheduletest1',
  templateUrl: './scheduletest1.component.html',
  styleUrls: ['./scheduletest1.component.scss']
})
export class Scheduletest1Component implements AfterViewInit {

@ViewChild( SchedulerComponent ) scheduler:SchedulerComponent;
@ViewChild('datePickerContainer') datePickerContainer: ElementRef;

// bind properties from the application to the scheduler component
rowHeight = 60;
selectedEvent = '';
events = [];
resources = [];
timeRanges = [];
timeRangesFeature = true;
barMargin = 10;
startDate = new Date(2018, 1, 7, 8);
endDate = new Date(2018, 1, 7, 22);
eventColor = 'green';
eventStyle = 'border';
resourceImagePath = 'assets/users/';

columns = [
    { type : 'resourceInfo', text : 'Staff', field : 'name' },
    {
        text   : 'Type',
        field  : 'role',
        width  : 130,
        editor : {
            type        : 'combo',
            items       : ['Sales', 'Developer', 'Marketing', 'Product manager'],
            editable    : false,
            pickerWidth : 140
        }
    }
];

eventEditFeature = {
    // Add extra widgets to the event editor
    items : {
        description : {
            type  : 'text',
            name  : 'desc',
            label : 'Description'
        }
    }
};

eventRenderer = ({ eventRecord }) => {
    return `
    <div class="info">
        <div class="name">${eventRecord.name}</div>
        <div class="desc">${eventRecord.desc}</div>
    </div>
  `;
}

constructor(private http: HttpClient) {
    this.getData();
}

ngAfterViewInit() {
    // exposing scheduling engine to be easily accessible from console
    window.scheduler = this.scheduler.schedulerInstance;

     const field = new DateField({
         appendTo  : this.datePickerContainer.nativeElement,
         label     : 'Select date',
         width     : 220,
         value     : new Date(2018, 1, 7),
         editable  : false,
         cls       : 'b-bright',
         listeners : {
             change  : this.onDatePickerChange,
             thisObj : this
         }
     });

    // access the engine to reach the entire scheduler API, see API docs at /docs.
    // some small examples:
    //
    // 1. Sort resources by name
    // this.scheduler.schedulerInstance.resourceStore.sort('name');
    //
    // 2. Add a new event
    // this.scheduler.schedulerInstance.eventStore.add({ startDate : xx, endDate: xx, ... });
    //
    // 3. Change the color of the first event
    // this.scheduler.schedulerInstance.eventStore.first.eventColor = 'orange';
    //
}

// fetch data for the scheduler
getData() {
    const me = this;

    me.http.get('./assets/data/data.json').subscribe(data => {
        me.resources = data['resources'].rows;
        me.events = data['events'].rows;
        me.timeRanges = data['timeRanges'].rows;
    });
}

// Uncomment the code in this method to start "logging" events
onSchedulerEvents(event: any) {
    //   // catch scheduler events here, for example when dropping an event:
       if (event.type === 'eventdrop') {
         console.log('Drop: ', event);
       }
    
       // or when editing one:
       if (event.type === 'eventschange') {
         console.log('SchedulerEventStore: ', event);
       }
    
       // or when editing a resource:
       if (event.type === 'resourceschange') {
         console.log('SchedulerResourceStore: ', event);
       }
}

// add event button click handled here
onAddEventClick() {
    this.scheduler.addEvent();
}

// remove event button click handled here
onRemoveEventClick() {
    this.scheduler.removeEvent();
}

// change scheduler start/end dates
onDatePickerChange({ value }) {
    this.scheduler.schedulerInstance.setTimeSpan(DateHelper.add(value, 8, 'hour'), DateHelper.add(value, 18, 'hour'));
}

}

scheduletest1.component.html

<header>
    <h1><a id="title" href="../../../../examples/#example-examples-scheduler-angular-angular-7">Angular 7 demo</a></h1>
    <label class="sel-event">Selected event: <span>{{ scheduler.selectedEvent || 'None' }}</span></label>

<div class="barmargin">
    <label>Bar margin</label>
    <input min="0" max="20" type="number" [value]="barMargin" (input)="barMargin = $event.target.value-0">
</div>
<div #datePickerContainer class="datePickerContainer"></div>
<button (click)="onAddEventClick()"><i class="b-fa b-fa-plus"></i></button>
<button class="red" (click)="onRemoveEventClick()" [disabled]="scheduler.selectedEvent == ''"><i class="b-fa b-fa-trash"></i></button>
</header>

<bry-scheduler #scheduler [rowHeight]="rowHeight" [barMargin]="barMargin" [events]="events" [timeRanges]="timeRanges" [resources]="resources" [startDate]="startDate" [endDate]="endDate" [columns]="columns" [eventColor]="eventColor" [eventStyle]="eventStyle"
    [eventRenderer]="eventRenderer" [timeRangesFeature]="timeRangesFeature" [eventEditFeature]="eventEditFeature" [resourceImagePath]="resourceImagePath" (onSchedulerEvents)="onSchedulerEvents($event)"></bry-scheduler>

I search about on net and some people took about the tsconfig.json, that's my...

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "paths": {
      "bryntum-angular-shared":[
        "..\\..\\..\\..\\..\\..\\ProvesAngular2\\schedulerpro-4.0.7-trial\\examples-scheduler\\angular\\_shared\\dist\\bryntum-angular-shared",
      ],
      "@angular/*": [
        "node_modules/@angular/*"
      ]
    }
  }
}

Thanks in advance
Sergio.


Post by saki »

Hello Sergio, would you please zip your test case and post it here so that we can plug it into our examples folder, run it and debug it?


Post by Txim »

Hello Saki, thanks for quikly response, the support is great here, I solved this step including inside the project the node folder. I know is not recommended but it's only for try it and show. When will decided implement we buy licence and will ask you how to solve this issue and start develop in the correct way.
thanks!


Post Reply