Custom appointment edit dialog - delete single / recurring event hook

Hi!

We are currently testing Your scheduler controller ability to handle custom dialogs.

Given situation that, as Your tutorial states, we want to create a dialog for custom appointment edit with validation.

Assume, that:

  • We are using simplest possible scheduler instance with custom data model (imagine appointment from Your demo with additional fields, so auto binding should work)
  • We are hooking up our custom dialog launch to Your "OnPopupOpen" event.

Our dialog starts and async finish inside of method handling said event (async Task PopupOpen(PopupOpenEventArgs args).

Dialog is being open, user can edit all the data that he want and on close, dialog returns either modified or new instance of data model (appointment).

Said dialog is not a Syncfusion product.


Absolutely crude and ugly version of said method looks like that:

private async Task PopupOpen(PopupOpenEventArgs args)

{

if (args.Type == PopupType.Editor)

{

args.Cancel = true; //to prevent the default editor window

var action = args.Data.Id == 0 ? "CellClick" : "AppointmentClick"; //to check whether the window opens on cell or appointment


if (action.Equals("CellClick"))

{

var dialog = DialogService.Show("Adding", new DialogParameters()

{

{"Data", args.Data}

});

var result = await dialog.Result;

if (result.Cancelled)

return;

var data = result.Data as DeparturePlanGuiModel;

data.Id = rand.Next(99999);

await SchedulerRef.AddEventAsync(data.Copy());

}

else

{

var dialog = DialogService.Show("Editing", new DialogParameters()

{

{"Data", args.Data}

});


var result = await dialog.Result;

if (result.Cancelled)

return;

await SchedulerRef.SaveEventAsync(result.Data.Copy() as DeparturePlanGuiModel);

}

}

if (args.Type == PopupType.QuickInfo)

{

args.Cancel = true;

}

}

)

There are two main issues:

First - We cannot correctly hook to Scheduler's 'delete occurrence or series' popup - how we could do that?
Second - after editing recurring meeting's single occurrence, when tested with ActionComplete event handler, there is no new appointment created in addition to recurring meeting edit - only edited appointment is given in handler args.


Custom dialog is displayed using MudBlazor dialog service.


3 Replies 1 reply marked as answer

NR Nevitha Ravi Syncfusion Team September 9, 2021 03:14 PM UTC

Hi Henryk, 

Greetings from Syncfusion Support. 

Q1: Can’t hook delete occurrence or series 
We suspect that you have delete button on you custom dialog and need to open Delete series or occurrence popup. For that you have to manually open another custom dialog and on clicking on delete occurrence you need pass current action as DeleteOccurrence to DeleteEventAsync method. Similarly on clicking delete series button on your custom dialog, you need to pass DeleteSeries to DeleteEventAsync method. 

Q2: Issue with editing occurrence. 
You need to pass the current action properly to SaveEventAsync method like below code. Currently we are facing issue with passing EditOccurrence as current action in SaveEventAsync. We will provide you further details on September 14, 2021. 

if (Action == "CellClick") 
        { 
            await ScheduleRef.AddEventAsync(EventData); //to add new appointment 
        } 
        else 
        { 
            if (EventData.RecurrenceRule == null) 
            { 
                await ScheduleRef.SaveEventAsync(EventData); // to save the existing appointment 
 
            } 
            else 
            { 
                if (ScheduleRef.GetCurrentAction() == CurrentAction.EditOccurrence) 
                { 
                    await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditOccurrence); 
                } 
                else 
                    { 
                        await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditSeries); 
                    } 
            } 
        } 

Regards, 
Nevitha 



HW Henryk Wisniewski September 10, 2021 11:58 AM UTC

I presume, that problems with passing Edit occurrence are:

When editing already modified occurrence of a series by changing a subject for example, the newly changed occurrence does not replace the old one but instead adds completely new, edited occurrence to the scheduler.


Is this the case? Or is it issue on my side?



In this case, bottom right occurrence was edited and the additional 999 occurrence is the result.

Below is my current (after Your suggestions) implementation of OnPopupOpen handler.
I Would like your opinion on the matter.


private async Task PopupOpen(PopupOpenEventArgs args)
{
var popupType = args.Type;
var schedulerAction = SchedulerRef.GetCurrentAction();
var plan = args.Data;


// Leave those as default Syncfusion implementations.
switch (popupType)
{
case PopupType.RecurrenceAlert or PopupType.DeleteAlert or PopupType.RecurrenceValidationAlert:
return;


// Disable QuickInfo
case PopupType.QuickInfo:
args.Cancel = true;
return;
}


// Everything else will be handle by custom dialogs
args.Cancel = true;


var dialog = DialogService.Show("Main dialog", new DialogParameters
{
{ "Data", plan.Copy() }, // Copy method creates deep copy of the plan object
{ "EditAction", plan.RecurrenceID is null ? CurrentAction.EditSeries : CurrentAction.EditOccurrence },
{ "DeleteAction", CurrentAction.Delete }
});


var result = await dialog.Result;
if (result.Cancelled) return;
var (model, action) = ((DeparturePlanGuiModel, CurrentAction?))result.Data;


switch (plan)
{
case var p when p.Id == default && action is CurrentAction.Delete:
break;


case var p when p.Id == default:
await SchedulerRef.AddEventAsync(model);
break;


case var p when p.RecurrenceRule is null && action is CurrentAction.Delete:
await SchedulerRef.DeleteEventAsync(model);
break;


case var p when p.RecurrenceRule is null:
await SchedulerRef.SaveEventAsync(model);
break;


case var _ when schedulerAction is CurrentAction.EditOccurrence or CurrentAction.EditSeries && action is CurrentAction.Delete:

await SchedulerRef.DeleteEventAsync(model, schedulerAction is CurrentAction.EditOccurrence ? CurrentAction.DeleteOccurrence : CurrentAction.DeleteSeries);
break;


case var _ when schedulerAction is CurrentAction.EditOccurrence or CurrentAction.EditSeries:
await SchedulerRef.SaveEventAsync(model, schedulerAction);
break;


default:
throw new UnknownArgumentException($"Unhandled action for departure plan - {schedulerAction}", nameof(args));
}
}



With regards,

Henryk



NR Nevitha Ravi Syncfusion Team September 13, 2021 08:22 AM UTC

Hi Henryk, 

Thanks for your update. 

We are glad that our shared code helped you. To resolve the issue with editing the occurrence of a series, you can use the following code in which we have updated the RecurrenceID field as parent recurrence Id. Please try the following sample which prepared with the same code. 

private async void OnValidSubmit() //triggers on save button click 
    { 
        DialogVisibility = false; 
        AppointmentData EventData = new AppointmentData(); 
        EventData.Subject = AppointmentValidation.Subject; 
        EventData.EndTime = (DateTime)AppointmentValidation.EndTime; 
        EventData.StartTime = (DateTime)AppointmentValidation.StartTime; 
        EventData.Description = AppointmentValidation.Description; 
        EventData.OwnerId = AppointmentValidation.OwnerId; 
        EventData.AppointmentType = AppointmentValidation.AppointmentType; 
        EventData.RecurrenceRule = AppointmentValidation.RecurrenceRule; 
        EventData.Id = Id; 
        if (Action == "CellClick") 
        { 
            await ScheduleRef.AddEventAsync(EventData); //to add new appointment 
        } 
        else 
        { 
            if (EventData.RecurrenceRule == null) 
            { 
                await ScheduleRef.SaveEventAsync(EventData); // to save the existing appointment 
 
            } 
            else 
            { 
                if (ScheduleRef.GetCurrentAction() == CurrentAction.EditOccurrence) 
                { 
                    EventData.RecurrenceID = EventData.Id; 
                    EventData.Id = await ScheduleRef.GetMaxEventIdAsync<int>() + 1; 
                    await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditOccurrence); 
                } 
                else 
                { 
                    await ScheduleRef.SaveEventAsync(EventData, CurrentAction.EditSeries); 
                } 
            } 
        } 
    } 
 
    private void PopupOpen(PopupOpenEventArgs<AppointmentData> args) 
    { 
 
        if (args.Type == PopupType.RecurrenceAlert || args.Type == PopupType.DeleteAlert || args.Type == PopupType.RecurrenceValidationAlert) 
        { 
            return; 
        } 
        if (args.Type == PopupType.Editor) 
        { 
            args.Cancel = true; //to prevent the default editor window 
            this.Action = args.Data.Id == 0 ? "CellClick" : "AppointmentClick"; //to check whether the window opens on cell or appointment 
            if (Action == "CellClick") 
            { 
                AppointmentValidation.StartTime = args.Data.StartTime; 
                AppointmentValidation.EndTime = args.Data.EndTime; 
                AppointmentValidation.Description = args.Data.Description; 
                AppointmentValidation.OwnerId = args.Data.OwnerId; 
                Random random = new Random(); 
                Id = random.Next(2, 1000); 
            } 
            else 
            { 
                Id = args.Data.Id; 
                AppointmentValidation.StartTime = args.Data.StartTime; 
                AppointmentValidation.EndTime = args.Data.EndTime; 
                AppointmentValidation.AppointmentType = args.Data.AppointmentType; 
                AppointmentValidation.OwnerId = args.Data.OwnerId; 
            } 
            AppointmentValidation.Description = args.Data.Description == null ? "" : args.Data.Description; 
            AppointmentValidation.Subject = args.Data.Subject == null ? "Add title" : args.Data.Subject; 
            DialogVisibility = true; 
        } 
        if (args.Type == PopupType.QuickInfo) 
        { 
            args.Cancel = true; 
        } 
    } 

Please try the above sample and let us know if you need any further assistance. 

Regards, 
Nevitha 


Marked as answer
Loader.
Up arrow icon