Our powerful JS Calendar component


Post by braincept »

Hi Team,
We have created our own event dialog which we are opening in the "beforeEventEdit" listener after checking some conditions. We are able to open it and able to create and edit events.
But we are facing one problem:
1) Default calendar event editor is also opening. We don't want to open the default eventeditor.

To use the custom event editor, we have also tried to configure the editor config. but we are getting error.

eventEdit = {
      editorConfig: {
        type: 'myCustomEditorType'
      }
    }

and error is

ERROR Error: Uncaught (in promise): Error: Invalid type name "myCustomEditorType" passed to _0x5edf42 factory
Error: Invalid type name "myCustomEditorType" passed to _0x5edf42 factory
    at Function._0x1309bd (calendar.lite.umd.js:10)
    at Function._0x190901 (calendar.lite.umd.js:10)
    at Function._0x56471b (calendar.lite.umd.js:10)
    at _0x46fdd4._0x3955c6 (calendar.lite.umd.js:10)
    at _0x46fdd4._0x177f2a (calendar.lite.umd.js:10)
    at _0x46fdd4._0x5b2346 (calendar.lite.umd.js:10)
    at _0x46fdd4._0xf93a34 (calendar.lite.umd.js:10)
    at _0x4bb5e6 (calendar.lite.umd.js:10)
    at Generator._0x3e1059 [as _invoke] (calendar.lite.umd.js:10)
    at Generator.next (calendar.lite.umd.js:10)
    at resolvePromise (zone-evergreen.js:798)
    at zone-evergreen.js:705
    at _0x22e366 (calendar.lite.umd.js:10)
    at _0x2fd5c2 (calendar.lite.umd.js:10)
    at calendar.lite.umd.js:10
    at new ZoneAwarePromise (zone-evergreen.js:960)
    at _0x46fdd4.<anonymous> (calendar.lite.umd.js:10)
    at _0x46fdd4._0x376ab6 (calendar.lite.umd.js:10)
    at _0x46fdd4._0x24d3ef (calendar.lite.umd.js:10)
    at _0x46fdd4._0x481a0e (calendar.lite.umd.js:10)

but we don't want to use default event editor because we are using Angular material dialog.


Post by pmiklashevich »

Please check out the docs of https://www.bryntum.com/docs/calendar/#Scheduler/feature/EventEdit#event-beforeEventEdit

Returning false stops the default editing UI from being shown.

So just return "false" from the handler and the default editor will not be shown.

For customizing event editor please check out the guide:
https://www.bryntum.com/docs/scheduler/#guides/customization/eventedit.md
If you want to replace it completely, please see this guide:
https://www.bryntum.com/docs/scheduler/#guides/customization/replaceeventedit.md

The case when you pass "type" config to the https://www.bryntum.com/docs/calendar/#Calendar/feature/EventEdit#config-editorConfig is not what you're looking for. Let me explain. For example in case of Calendar the default type of editorConfig is 'calendareventeditor'. YOu can see it in our sources. In Calendar/lib/Calendar/feature/EventEdit.js:

    static get configurable() {
        return {
            editorConfig : {
                type  : 'calendareventeditor',

'calendareventeditor' refers to the private Calendar.widget.EventEditor:

export default class EventEditor extends SchedulerEventEditor {
    // Factoryable type name
    static get type() {
        return 'calendareventeditor';
    }

So, for example, you need to override it for some reason. Then you can do:

import EventEditor from '../../lib/Calendar/widget/EventEditor.js';

export default class MyEventEditor extends EventEditor {
    // Factoryable type name
    static get type() {
        return 'myeventeditor';
    }

static get $name() {
    return 'MyEventEditor';
}
}

// Register this widget type with its Factory
// so you can use { type : 'myeventeditor' }
MyEventEditor.initClass();

const calendar = new Calendar({
    features : {
        eventEdit : {
            editorConfig : {
                type : 'myeventeditor'
            }
        }
    },

You can try out this code in Calendar/examples/basic/app.js locally.
MyEventEditor.initClass(); is the line which registers a new "type".

Note, we do not recommend to extend private classes. That was just to show you an example. But you can create your own widget and call initClass to initialize the type and use it later.

we don't want to use default event editor because we are using Angular material dialog.

It looks like this guide is what you're looking for then:
https://www.bryntum.com/docs/scheduler/#guides/customization/replaceeventedit.md

Best,
Pavel

Pavlo Miklashevych
Sr. Frontend Developer


Post by braincept »

Hi Pavel, Thanks for the detailed description.

Now I am returning false.

this.calendarInstance.on('beforeEventEdit',  this.beforeEventEdit.bind(this));

beforeEventEdit(
    {eventEdit, eventRecord}:
      { eventEdit: EventEdit, eventRecord: BryntumCalendarEventModel }
  ): Boolean {
  	return false;
  }

but we are getting a new errors after returning false.

	ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'widgetMap' of undefined
TypeError: Cannot read property 'widgetMap' of undefined
    at _0x46fdd4._0x5b2346 (calendar.lite.umd.js:10)
    at _0x46fdd4._0xf93a34 (calendar.lite.umd.js:10)
    at _0x4bb5e6 (calendar.lite.umd.js:10)
    at Generator._0x3e1059 [as _invoke] (calendar.lite.umd.js:10)
    at Generator.next (calendar.lite.umd.js:10)
    at _0x22e366 (calendar.lite.umd.js:10)
    at _0x2fd5c2 (calendar.lite.umd.js:10)
    at calendar.lite.umd.js:10
    at new ZoneAwarePromise (zone-evergreen.js:960)
    at _0x46fdd4.<anonymous> (calendar.lite.umd.js:10)
    at resolvePromise (zone-evergreen.js:798)
    at zone-evergreen.js:705
    at _0x22e366 (calendar.lite.umd.js:10)
    at _0x2fd5c2 (calendar.lite.umd.js:10)
    at calendar.lite.umd.js:10
    at new ZoneAwarePromise (zone-evergreen.js:960)
    at _0x46fdd4.<anonymous> (calendar.lite.umd.js:10)
    at _0x46fdd4._0x376ab6 (calendar.lite.umd.js:10)
    at _0x46fdd4._0x24d3ef (calendar.lite.umd.js:10)
    at _0x46fdd4._0x481a0e (calendar.lite.umd.js:10)
defaultErrorLogger @ core.js:5973
handleError @ core.js:6021
next @ core.js:28788
schedulerFn @ core.js:25601
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:25591
(anonymous) @ core.js:28260
invoke @ zone-evergreen.js:364
run @ zone-evergreen.js:123
runOutsideAngular @ core.js:28164
onHandleError @ core.js:28260
handleError @ zone-evergreen.js:368
runGuarded @ zone-evergreen.js:136
api.microtaskDrainDone @ zone-evergreen.js:670
drainMicroTaskQueue @ zone-evergreen.js:576
invokeTask @ zone-evergreen.js:484
ZoneTask.invoke @ zone-evergreen.js:469
timer @ zone-evergreen.js:2552
setTimeout (async)
scheduleTask @ zone-evergreen.js:2573
scheduleTask @ zone-evergreen.js:385
onScheduleTask @ zone-evergreen.js:272
scheduleTask @ zone-evergreen.js:378
scheduleTask @ zone-evergreen.js:210
scheduleMacroTask @ zone-evergreen.js:233
scheduleMacroTaskWithCurrentZone @ zone-evergreen.js:1134
(anonymous) @ zone-evergreen.js:2586
proto.<computed> @ zone-evergreen.js:1449
(anonymous) @ calendar.lite.umd.js:10
ZoneAwarePromise @ zone-evergreen.js:960
_0x4ca27d @ calendar.lite.umd.js:10
_0x4b5896 @ calendar.lite.umd.js:10
_0x4bb5e6 @ calendar.lite.umd.js:10
_0x3e1059 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
_0x22e366 @ calendar.lite.umd.js:10
_0x2fd5c2 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
ZoneAwarePromise @ zone-evergreen.js:960
(anonymous) @ calendar.lite.umd.js:10
_0x1541b0 @ calendar.lite.umd.js:10
_0x2d6e4e @ calendar.lite.umd.js:10
_0x4bb5e6 @ calendar.lite.umd.js:10
_0x3e1059 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
_0x22e366 @ calendar.lite.umd.js:10
_0x2fd5c2 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
ZoneAwarePromise @ zone-evergreen.js:960
(anonymous) @ calendar.lite.umd.js:10
_0x43fe4b @ calendar.lite.umd.js:10
_0x35b8f5 @ calendar.lite.umd.js:10
_0x4bb5e6 @ calendar.lite.umd.js:10
_0x3e1059 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
_0x22e366 @ calendar.lite.umd.js:10
_0x2fd5c2 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
ZoneAwarePromise @ zone-evergreen.js:960
(anonymous) @ calendar.lite.umd.js:10
_0xf294c9 @ calendar.lite.umd.js:10
_0x510723 @ calendar.lite.umd.js:10
_0x4bb5e6 @ calendar.lite.umd.js:10
_0x3e1059 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
_0x22e366 @ calendar.lite.umd.js:10
_0x2fd5c2 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
ZoneAwarePromise @ zone-evergreen.js:960
(anonymous) @ calendar.lite.umd.js:10
_0x3949ee @ calendar.lite.umd.js:10
_0x282d19 @ calendar.lite.umd.js:10
_0x4bb5e6 @ calendar.lite.umd.js:10
_0x3e1059 @ calendar.lite.umd.js:10
(anonymous) @ calendar.lite.umd.js:10
_0x22e366 @ calendar.lite.umd.js:10
_0x2fd5c2 @ calendar.lite.umd.js:10
invoke @ zone-evergreen.js:364
onInvoke @ core.js:28237
invoke @ zone-evergreen.js:363
run @ zone-evergreen.js:123
(anonymous) @ zone-evergreen.js:857
invokeTask @ zone-evergreen.js:399
onInvokeTask @ core.js:28225
invokeTask @ zone-evergreen.js:398
runTask @ zone-evergreen.js:167
drainMicroTaskQueue @ zone-evergreen.js:569
invokeTask @ zone-evergreen.js:484
invokeTask @ zone-evergreen.js:1621
globalZoneAwareCallback @ zone-evergreen.js:1647
Show 63 more frames

Post by pmiklashevich »

Could you please try to get Scheduler/examples/angular/custom-event-editor example up and running? Let me know if it works for you. If you check Scheduler/examples/angular/custom-event-editor/src/app/app.component.ts file, you'll see:

export class AppComponent implements AfterViewInit {
    schedulerConfig: any = schedulerConfig;

@ViewChild(SchedulerComponent, { static : true }) scheduler: SchedulerComponent;

constructor(public editor: MatDialog) { }

beforeEventEdit(event): boolean {
    const
        { eventRecord, resourceRecord, eventEdit } = event,
        editorConfig = new MatDialogConfig();

    Object.assign(editorConfig, {
        disableClose : false,
        autoFocus    : true,
        width        : '500px',
        data         : {
            eventRecord,
            resourceRecord,
            eventStore : eventEdit.eventStore
        }
    });

    // console.log('data=', editorConfig.data);
    this.editor.open(EventEditorComponent, editorConfig);

    // suppress default event editor
    return false;
}

ngAfterViewInit() {
    // install beforeEventEdit listener
    this.scheduler.schedulerInstance.on('beforeEventEdit', this.beforeEventEdit.bind(this));
}

Are you using Calendar 4.0.3? The example above is from scheduler but it should work exactly the same way in Calendar. It would be nice if you can submit a runnable testcase, so we have something to inspect.

Cheers!

Pavlo Miklashevych
Sr. Frontend Developer


Post by pmiklashevich »

Please change ngAfterViewInit to this notation to avoid typings problems. It will be fixed in next release.

    ngAfterViewInit() {
        this.scheduler.schedulerInstance.on({
            beforeEventEdit : this.beforeEventEdit,
            thisObj         : this
        });
    }

Pavlo Miklashevych
Sr. Frontend Developer


Post by braincept »

Hi Panvel, In the scheduler, it is already working. We are migrating from scheduler to calendar.
Currently, we are using the 4.0.3 version.


Post by braincept »

Hi Panvel, Still getting the same error after changing to


this.calendarInstance = this.calendar.calendarInstance;
this.eventStore = this.calendarInstance.eventStore;
// this.calendarInstance.on('beforeEventEdit', this.beforeEventEdit.bind(this));
this.calendarInstance.on({
  beforeEventEdit: this.beforeEventEdit,
  thisObj: this
});

Post by pmiklashevich »

Please remove node_modules, zip your app up, and attach here. We will investigate.

Also we have a ticket to add corresponding guide and example to Calendar:
https://github.com/bryntum/support/issues/2000

Pavlo Miklashevych
Sr. Frontend Developer


Post by pconophy »

Was the return false error ever addressed or elevated as a bug?

We've been experiencing the exact same error in v4.0.6 when returning false in beforeeventedit to prevent the internal editor from displaying and using our own. This doesn't appear to be specific to framework implementations as I was able to reproduce it in the customize event editor demo by updating the config object to have a listener for beforeeventedit that returns false.

https://www.bryntum.com/examples/calendar/eventedit/

With this addition to the Calendar config object

listeners: {
  beforeeventedit: function() {
    return false;
  }
},
calendar.module.js?447703:102 Uncaught (in promise) TypeError: Cannot read property 'widgetMap' of undefined
    at EventEdit$1.internalShowEditor (calendar.module.js?447703:102)
    at EventEdit$1.doEditEvent (calendar.module.js?447703:102)
    at EventEdit$1.editEvent (calendar.module.js?447703:102)
    at EventEdit$1.onActivateEditor (calendar.module.js?447703:102)
    at Calendar.trigger (calendar.module.js?447703:10)
    at Calendar.onViewCatchAll (calendar.module.js?447703:102)
    at MonthView.trigger (calendar.module.js?447703:10)
    at MonthView.onCalendarPointerInteraction (calendar.module.js?447703:102)
    at HTMLDivElement._0x1622c6 (calendar.module.js?447703:10)

We've isolated the error to lib/Calendar/feature/EventEdit.js internalShowEditor() method where I assume event is undefined as a result of returning false.

Is there another method to disable the default/internal editor? This is currently preventing us from properly using a custom event editor in our app.


Post by mats »

Is there another method to disable the default/internal editor?

features : {
        eventEdit : false
    },

The best way to disable the editor is simply to disable the feature. That said, we'll fix the bug too for sure, thanks for the reminder. Ticket: https://github.com/bryntum/support/issues/2416


Post Reply