Howdy, I am trying to make a right click context menu when you right click on an scheduled event in the scheduler. I have gotten it mostly working however when I right click on an event the context menu appears about 25 pixels or so below the mouse cursor(see screenshot). I would prefer it to work like every other context menu which is aligned with the mouse cursor. The code below seems pretty basic. In testing I also removed all CSS to ensure there wasn't something causing issues there. Due to the nature of the context menu I can't inspect the element properly in Chrome's console. The target element is the scheduled event which I can confirm through console.
So how do I make the right click menu actually show up along the mouse when clicking an appt?
I have spent the past two days of stripping code and adding it back so in my code below there will be some things that aren't necessary but it shouldn't bog down any troubleshooting.
import { Component, ViewChild, ElementRef, ViewChildren, QueryList } from '@angular/core';
import { ApptDetail } from '../../interfaces/apptdetail.interface';
import { SchedulerEvent, } from '@progress/kendo-angular-scheduler';
import valueHelpers from '../../shared/value-helpers';
import { ApptService } from '../../interfaces/services/appt.service';
import { GenericPagedResponse } from '../../interfaces/pagedresponse.interface';
import { Client } from '../../interfaces/client.interface';
import { ClientService } from '../../interfaces/services/client.service';
import { ContextMenuComponent, ContextMenuSelectEvent, ContextMenuPopupEvent } from '@progress/kendo-angular-menu';
@Component({
selector: 'app-appointments',
templateUrl: './appointments.component.html',
styleUrls: ['./appointments.component.css']
})
export class AppointmentsComponent {
public appointments: ApptDetail[] = [];
selectedDate: Date = new Date();
public contextMenuEvent!: SchedulerEvent;
@ViewChild(ContextMenuComponent, { static: true }) apptContextMenu!: ContextMenuComponent;
@ViewChild('apptScheduler', { read: ElementRef }) apptScheduler!: ElementRef;
@ViewChildren('apptEvent', { read: ElementRef }) apptEventElements!: QueryList<ElementRef>;
apptContextMenuItems: any[] = [
{
text: "Cashout Appointment",
value: "cashout"
},
{
text: "Edit",
value: "edit",
},
{
text: "Delete",
value: "delete"
},
{
text: "Send SMS Reminder",
value: "sendSMS"
},
{
text: "Send Email Reminder",
value: "sendEmailReminder"
},
];
ngOnInit() {
this.loadApptData();
}
constructor(private apptService: ApptService) { }
loadApptData() {
console.log("Load appt data");
const fromDate = valueHelpers.getStartOfWeek(this.selectedDate);
const toDate = valueHelpers.getEndOfWeek(this.selectedDate);
this.apptService.getApptsForCalendar(fromDate, toDate).subscribe((data: GenericPagedResponse<ApptDetail>) => {
this.appointments = data.data;
// Update the schedulerEvents array with the new data
this.updateSchedulerEvents();
});
}
private updateSchedulerEvents() {
this.schedulerEvents = this.appointments.map(appointment => {
const startDateTime = new Date(appointment.startDateTime); // Convert to Date object
const endDateTime = new Date(appointment.endDateTime); // Convert to Date object
return {
id: appointment.apptDetailId.toString(),
start: startDateTime,
end: endDateTime,
title: appointment.clientName + ' <br> ' + appointment.itemName,
description: appointment.apptNote,
resourceId: appointment.employeeId
};
});
}
public schedulerEvents: SchedulerEvent[] = [];
onDateChange(event: any) {
console.log(event);
if (this.selectedDate != event.selectedDate)
this.selectedDate = event.selectedDate;
console.log('Selected Date:', this.selectedDate);
this.loadApptData();
}
public onApptContextMenuSelect(e: ContextMenuSelectEvent): void {
if (e.item.value == "edit") {
}
else if (e.item.value == "delete") {
}
else if (e.item.value == "cashout") {
}
else if (e.item.value == "sendSMS") {
}
else if (e.item.value == "sendEmailReminder") {
}
}
public onEventContextMenu(event: any): void {
this.contextMenuEvent = event; // Save the event for later use
const targetElement = event.target;
// Get the unique identifier from the custom attribute
// const apptId = targetElement.getAttribute('data-appt-id');
// Find the corresponding 'apptEvent' element based on the 'data-appt-id' attribute
// console.log(apptId)
if (targetElement) {
this.apptContextMenu.show(targetElement);
}
event.preventDefault();
}
}
<kendo-scheduler [events]="schedulerEvents" (dateChange)="onDateChange($event)" [selectedDate]="selectedDate"
(contextmenu)="onEventContextMenu($event)" #apptScheduler>
<kendo-scheduler-week-view> </kendo-scheduler-week-view>
</kendo-scheduler>
<kendo-contextmenu #apptContextMenu [items]="apptContextMenuItems" (select)="onApptContextMenuSelect($event)">
</kendo-contextmenu>