Scheduler Custom Edit window - Manipulate footer buttons?

Hello,
I created a custom edit window using the example presented on the documentation and everything is working great. However I would like manipulate the footer buttons but  can't seem to find a solution. So is it possible to:
  1. Hide the footer buttons on the custom edit window? right now 3 buttons appear that are delete, save and cancel. I know, for example, I can set the "AllowDelete="false" but I would like to hide it. 
  2. Is there a way to change the names of the buttons?
  3. How can I catch the events of the custom edit window? I have OnActionBegin and ActionCompleted and they are not firing

Thank you!

13 Replies

AK Alagumeena Kalaiselvan Syncfusion Team February 12, 2020 11:28 AM UTC

Hi Rodrigo, 

Greetings from Syncfusion support! 

Query 1: How to hide the footer buttons on the custom edit window ? 

The footer buttons can be hidden by applying the display property as none to the specified button. Refer below code for that 

... 
<EjsSchedule TValue="AppointmentData" Width="100%" Height="650px" SelectedDate="@(new DateTime(2020, 1, 31))"> 
    ... 
   <ScheduleEvents TValue="AppointmentData" ActionCompleted="ActionCompleted"></ScheduleEvents> 
    <ScheduleEventSettings DataSource="@DataSource" AllowDeleting="false"></ScheduleEventSettings> 
</EjsSchedule> 
 
@code{ 
    [Inject] 
    protected IJSRuntime JsRuntime { get; set; } 
    protected override void OnAfterRender(bool firstRender) 
    { 
        this.JsRuntime.Ejs().LoadLocaleData("Pages/locale.json"); 
    } 
    public void ActionCompleted(ActionEventArgs<AppointmentData> args) 
    { 
       if(args.RequestType == "eventCreate") 
        { 
            // Triggers on successful completion of scheduler event create actions 
        } 
        else if(args.RequestType == "eventChange") 
        { 
            // Triggers on successful completion of scheduler event change actions 
        } 
    } 
} 
 
<style> 
    .e-schedule-dialog .e-event-delete:disabled { 
        display: none;   // hide the disabled delete button 
    } 
</style> 

Query 2:  Is there a way to change the name of buttons ? 

Yes, Scheduler supports to change the button name by changing the appropriate localized word collection used in scheduler. We have already documented this requirement. So, please refer the below UG link to know more 


Query 3:  How to catch the events of custom edit window ? 

You can use the Scheduler’s “ActionCompleted”  event with “RequestType” argument to customize the appointment data. It triggers for every successful completion of scheduler actions .  We have defined the “ActionCompleted” event in the shared sample for your reference. 

Also, we have prepared a sample based on your requirement which can be downloaded from the below link 

Kindly try out with above sample and get back to us, If you need further assistance 

Regards 
Alagumeena.K 



RO Rodrigo February 12, 2020 12:10 PM UTC

Thank you for the Reply!

Query 1 and 2 are resolved and everything is working. as for query 3 it seems the ActionCompleted is not firing. 

Another question: Is there a possibility of adding new buttons to the event custom window? I would like to have an extra button for some new actions. If it's possible, how can I define the action for this new button?

Here is my code for the scheduler

        <EjsSchedule @ref="lookSchedule" TValue="ViewModel.Look" Height="100%" Width="100%" CurrentView="View.Month" AllowDragAndDrop="false" AllowResizing="false"
                     RowAutoHeight="true" FirstDayOfWeek="1" ShowQuickInfo="false">
            <ScheduleWorkHours Highlight="false" />
            <ScheduleEvents TValue="ViewModel.Look" Navigating="NavigatingHandler" EventRendered="OnEventRenderedHandler" ActionCompleted="ActionCompletedHandler" />
            <ScheduleViews>
                <ScheduleView Option="View.Month" />
                <ScheduleView Option="View.Week">
                    <ScheduleViewTimeScale Interval="60" SlotCount="2" />
                </ScheduleView>
                <ScheduleView Option="View.Day" />
            </ScheduleViews>
            <ScheduleTemplates>
                <EditorTemplate>
                    @{
                        var entity = (context as ViewModel.Look);
                        <input type="hidden" name="Id" class="e-field" value="@(entity.Id)" />
                        <table class="custom-event-editor" width="100%" cellpadding="5">
                            <tbody>
                                <tr>
                                    <td class="e-textlabel">Craft</td>
                                    <td colspan="4">
                                        <EjsTextBox Readonly="true" Id="Subject" CssClass="e-field e-input" Value="@(entity.Craft)"></EjsTextBox>
                                    </td>
                                </tr>
                                <tr>
                                    <td class="e-textlabel">Site</td>
                                    <td colspan="4">
                                        <EjsTextBox Readonly="true" Id="Site" CssClass="e-field e-input" Value="@(entity.Site)"></EjsTextBox>
                                    </td>
                                </tr>
                                <tr>
                                    <td class="e-textlabel">Time</td>
                                    <td colspan="4">
                                        <EjsTextBox Readonly="true" Id="Time" CssClass="e-field e-input" Value="@($"{entity.StartTime.ToUniversalTime().ToString("hh:mm tt")} - {entity.EndTime.ToUniversalTime().ToString("hh:mm tt")}")"></EjsTextBox>
                                    </td>
                                </tr>
                                <tr>
                                    <td class="e-textlabel">Duration</td>
                                    <td colspan="4">
                                        <EjsTextBox Readonly="true" Id="Duration" CssClass="e-field e-input" Value="@($"{TimeSpan.FromSeconds(entity.Duration).ToString(@"mm")} min")"></EjsTextBox>
                                    </td>
                                </tr>
                                <tr>
                                    <td class="e-textlabel">Status</td>
                                    <td colspan="4">
                                        <EjsTextBox Readonly="true" Id="Status" CssClass="e-field e-input" Value="@(entity.Status)"></EjsTextBox>
                                    </td>
                                </tr>
                                <tr>
                                    <td class="e-textlabel">Organization</td>
                                    <td colspan="4">
                                        <EjsTextBox Readonly="true" Id="Organization" CssClass="e-field e-input" Value="@((String.Join(", ", entity.Organizations.Select(o => o.Name))))"></EjsTextBox>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    }
                </EditorTemplate>
            </ScheduleTemplates>
            <ScheduleEventSettings DataSource="@DataSource" AllowAdding="false" AllowDeleting="false" EnableTooltip="true">
                <Template>
                    @{
                        var entity = (context as ViewModel.Look);
                        <div class="template-wrap">
                            <div class="subject">@($"{entity.StartTime.ToUniversalTime().ToString("hh:mm tt")} - {entity.Craft} - {entity.Status}")</div>
                        </div>
                    }
                </Template>
                <TooltipTemplate>
                    @{
                        var entity = (context as ViewModel.Look);
                        <div class="tooltip-wrap">
                            <div class="content-area">
                                <div class="name">@entity.Craft</div>
                                <div class="city">@entity.Site</div>
                                <div class="time">@($"{entity.StartTime.ToUniversalTime().ToString("hh:mm tt")} - {entity.EndTime.ToUniversalTime().ToString("hh:mm tt")}")</div>
                                <div class="time">@($"{TimeSpan.FromSeconds(entity.Duration).ToString(@"mm")} min")</div>
                            </div>
                        </div>
                    }
                </TooltipTemplate>
            </ScheduleEventSettings>
        </EjsSchedule>



RO Rodrigo February 12, 2020 01:56 PM UTC

My backend code is:
```
public partial class LookView : ComponentBase
{
[Inject] private IScheduleService ScheduleService { get; set; }
[Inject] protected IJSRuntime JsRuntime { get; set; }

private IEnumerable DataSource { get; set; } = new List();
private EjsSchedule lookSchedule;
private List Filters { get; set; } = new List();
private Guid? SelectedOrganizationId { get; set; }
public string[] ReservedClass = { "reserved-class" };
public string[] BookedClass = { "booked-class" };
public string[] LockedClass = { "locked-class" };
public string[] RunningClass = { "running-class" };
public string[] ProcessingClass = { "processing-class" };
public string[] CompletedClass = { "completed-class" };


protected async override Task OnInitializedAsync()
{
await GetDataSource(Filters, CalculateDate(DateTime.Now));
}

private async void OnOrganizationChangedHandler(ViewModel.EntityLookup entity)
{
SelectedOrganizationId = entity == null || entity.Id == Guid.Empty ? (Guid?)null : entity.Id;
await GetDataSource(Filters, CalculateDate(lookSchedule.SelectedDate));
}

private void ActionCompletedHandler(ActionEventArgs args)
{
// Triggers on successful completion of scheduler actions
}

protected override void OnAfterRender(bool firstRender)
{
JsRuntime.Ejs().LoadLocaleData("Features/Schedule/Pages/scheduleLocale.json");
}

private async void NavigatingHandler(NavigatingEventArgs args)
{
await GetDataSource(Filters, CalculateDate(args.CurrentDate, args));
}

private void OnEventRenderedHandler(EventRenderedArgs args)
{
if (args.Data == null)
{
return;
}
switch (args.Data.Status)
{
case "Reserved":
args.Element.AddClass(ReservedClass);
break;
case "Booked":
args.Element.AddClass(BookedClass);
break;
case "Locked":
args.Element.AddClass(LockedClass);
break;
case "Running":
args.Element.AddClass(RunningClass);
break;
case "Processing":
args.Element.AddClass(ProcessingClass);
break;
case "Completed":
args.Element.AddClass(CompletedClass);
break;
}
}

private async void OnFilterCalendar(List filters)
{
Filters = filters;
await GetDataSource(filters, CalculateDate(lookSchedule.SelectedDate));
}

private async Task GetDataSource(List filters, (DateTime start, DateTime end) date)
{
DataSource = await ScheduleService.GetLooks(filters, date.start, date.end, SelectedOrganizationId);
StateHasChanged();
}
}
```


AK Alagumeena Kalaiselvan Syncfusion Team February 14, 2020 12:47 PM UTC

Hi Rodrigo, 

Thanks for your update! 

We have checked with your shared code and we suggest you use the Start Time and End time fields which are mandatory to customize the appointment data but you have used “Time” alone. So, Due to  the absence of required fields the scheduler editor window events won’t fired and also we suggest you to use the “OnPopupClose” event to handle the editor window customization. Here, we have prepared a sample based on your shared code. Refer the below code for that 

<EjsSchedule @ref="LookSchedule" TValue="ViewModel.Look" Height="100%" Width="100%" CurrentView="View.Month" AllowDragAndDrop="false" AllowResizing="false" 
             RowAutoHeight="true" FirstDayOfWeek="1" ShowQuickInfo="false"> 
    <ScheduleWorkHours Highlight="false" /> 
    <ScheduleEvents TValue="ViewModel.Look" Navigating="NavigatingHandler" EventRendered="OnEventRenderedHandler" OnPopupClose="PopupClose"/> 
    <ScheduleViews> 
        <ScheduleView Option="View.Month" /> 
        <ScheduleView Option="View.Week"> 
            <ScheduleViewTimeScale Interval="60" SlotCount="2" /> 
        </ScheduleView> 
        <ScheduleView Option="View.Day" /> 
    </ScheduleViews> 
    <ScheduleTemplates> 
        <EditorTemplate> 
            @{ 
                var entity = (context as ViewModel.Look); 
                <input type="hidden" name="Id" class="e-field" value="@(entity.Id)" /> 
                <table class="custom-event-editor" width="100%" cellpadding="5"> 
                    <tbody> 
                        <tr> 
                            <td class="e-textlabel">Craft</td> 
                            <td colspan="4"> 
                                <EjsTextBox Id="Craft" CssClass="e-field e-input" Value="@(entity.Craft)"></EjsTextBox> 
                            </td> 
                        </tr> 
                        <tr> 
                            <td class="e-textlabel">Site</td> 
                            <td colspan="4"> 
                                <EjsTextBox Readonly="true" Id="Site" CssClass="e-field e-input" Value="@(entity.Site)"></EjsTextBox> 
                            </td> 
                        </tr> 
                        <tr> 
                            <td class="e-textlabel">Time</td> 
                            <td colspan="4"> 
                                <EjsTextBox Readonly="true" Id="Time" CssClass="e-field e-input" Value="@($"{entity.StartTime.ToUniversalTime().ToString("hh:mm tt")} - {entity.EndTime.ToUniversalTime().ToString("hh:mm tt")}")"></EjsTextBox> 
                            </td> 
                        </tr> 
                        <tr style="display: none;">    // Need to maintain the DateTime filed to handle scheduler actions and based on your wish you can hide or display this field  
                            <td class="e-textlabel">DateTime</td> 
                            <td colspan="4"> 
                                <EjsTextBox Readonly="true" Id="DateTime" CssClass="e-field e-input" Value="@($"{entity.StartTime.ToUniversalTime().ToString()} - {entity.EndTime.ToUniversalTime().ToString()}")"></EjsTextBox> 
                            </td> 
                        </tr> 
                        <tr> 
                            <td class="e-textlabel">Status</td> 
                            <td colspan="4"> 
                                <EjsTextBox Readonly="true" Id="Status" CssClass="e-field e-input" Value="@(entity.Status)"></EjsTextBox> 
                            </td> 
                        </tr> 
                        ... 
@code{ 
    [Inject] protected IJSRuntime JsRuntime { get; set; } 
 
    Dictionary<string, object> StartName = new Dictionary<string, object>() 
{ 
        {"data-name","StartTime"}, 
    }; 
    Dictionary<string, object> EndName = new Dictionary<string, object>() 
{ 
        {"data-name","EndTime"}, 
    }; 
 
    public void PopupClose(PopupCloseEventArgs<ViewModel.Look> args) 
    { 
        if(args.Type == PopupType.Editor && args.Data != null) 
            { 
                args.Data.StartTime = Convert.ToDateTime(args.Data.DateTime.Split(" - ")[0]); // Need to be convert the string to date time object to avoid serialization issue 
 
                args.Data.EndTime = Convert.ToDateTime(args.Data.DateTime.Split(" - ")[1]); 
            } 
         
    } 
} 
 

Also, you can download this sample from the below link  


Kindly try out with shared sample and let us know, If need further assistance 

Regards 
Alagumeena.K 



RO Rodrigo February 17, 2020 11:33 AM UTC

I'm getting access denied when trying to download the sample.Can you please check the problem?

thank you


AK Alagumeena Kalaiselvan Syncfusion Team February 17, 2020 12:34 PM UTC

Hi Rodrigo, 

Sorry for the inconvenience caused! 

Now, you can download this sample by the below link 

Please let us know, If have further assistance. 

Regards 
Alagumeena.K 



RO Rodrigo February 17, 2020 03:00 PM UTC

Thank you for the quick fix! I was able to put the ActionCompleted to work so thank you for the help. I have some additional question if you don't mind:

  1. Is it possible to add additional custom buttons to the Custom Edit window ? so right now we have Remove, Add and Cancel and I would like to be able to add some buttons to do some custom work and make them recognizable on the ActionCompleted.
  2. As you can see from the code I posted before, to put some color on the events I'm using the OnEventRenderedHandler and setting the args.Element.AddClass(ReservedClass). Is there a more elegant way to do this?
Thank you for the help!! it's been really on point.


AK Alagumeena Kalaiselvan Syncfusion Team February 18, 2020 12:19 PM UTC

Hi Rodrigo, 

Thanks for your update! 

Query 1:  “Is it possible to add additional custom buttons to the Custom Edit window” 
 
Yes, scheduler supports to add additional custom buttons to the Custom Edit window but you can achieve this case by creating own custom dialogue for the data operations instead of using scheduler inbuild dialogue. We have prepared a sample based on your requirement which can be downloaded from the below link 
 


Query 2: “Is there a more elegant way to coloring the events?” 

Yes, you can add the color to the appointment dynamically by simply customizing the style attribute of the appointment like below code  
 
@using Syncfusion.EJ2.Blazor.Schedule  
  
<EjsSchedule TValue="AppointmentData" Height="650px" SelectedDate="new DateTime(2019, 1, 17)">  
    <ScheduleEvents TValue="AppointmentData" EventRendered="OnEventRendered"></ScheduleEvents>  
    <ScheduleViews>  
        <ScheduleView Option="View.Day"></ScheduleView>  
        <ScheduleView Option="View.Week"></ScheduleView>  
        <ScheduleView Option="View.Month"></ScheduleView>  
        <ScheduleView Option="View.WorkWeek"></ScheduleView>  
    </ScheduleViews>  
    <ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>  
</EjsSchedule>  
  
@code{  
    public async Task OnEventRendered(EventRenderedArgs<AppointmentData> args)  
    {  
        string style = (await args.Element.GetAttribute("style")).ToString();  // Get style attribute of the element  
        style += "background:" + args.Data.CategoryColor;               // concatenate the background color  
        args.Element.SetAttribute("style", style);                      // Reset the values of style attribute  
    }  
    List<AppointmentData> DataSource = new List<AppointmentData>  
{  
        new AppointmentData { Id = 3, Subject = "South Park", StartTime = new DateTime(2019, 1, 17, 9, 30, 0) , EndTime = new DateTime(2019, 1, 17, 11, 0, 0), CategoryColor= "#df5286" },  
        new AppointmentData { Id = 1, Subject = "Vikings", StartTime = new DateTime(2019, 1, 15, 9, 30, 0) , EndTime = new DateTime(2019, 1, 15, 11, 0, 0), CategoryColor= "#7fa900" },  
        new AppointmentData { Id = 2, Subject = "Rick and Morty", StartTime = new DateTime(2019, 1, 27, 9, 30, 0) , EndTime = new DateTime(2019, 1, 27, 11, 0, 0),  
        RecurrenceRule = "FREQ=DAILY;INTERVAL=1;COUNT=5", CategoryColor= "#1aaa55" }  
    };  
  
    public class AppointmentData  
    {  
        public int Id { getset; }  
        public string Subject { getset; }  
        public string Location { getset; }  
        public DateTime StartTime { getset; }  
        public DateTime EndTime { getset; }  
        public string Description { getset; }  
        public bool IsAllDay { getset; }  
        public string RecurrenceRule { getset; }  
        public string RecurrenceException { getset; }  
        public Nullable<int> RecurrenceID { getset; }  
        public string CategoryColor { getset; }  
    }  
}  

Kindly get back to us, If you need further assistance 

Regards 
Alagumeena.K 



RO Rodrigo February 18, 2020 07:07 PM UTC

Hey Alagumeena!

I got things to work following you example so thank you for you support! it has been really good.
One small problem on the colors of the events on the scheduler. Following your example, as I change date I'm getting some flickering when the background colors are applied. One of the reasoning is when I change a date, I'm fetching remote data and using the StateHasChanged to refresh the scheduler causing the flicker on every date change. Is there any way to resolve this?

Please check the gif provided to understand the problem reported.

Regards,
Rodrigo F.

Edit: I did a test where I load more data initially instead of using the event Navigating and the flickering still happens 


Attachment: SchedulerFlicker_95c7a9ac.7z


RO Rodrigo February 19, 2020 10:12 AM UTC

Hello!,
Another thing that I noticed that's happening is sometimes the text on the events are not rendered but the tool tip still shows the relevant information Please check the image below.

Regards,
Rodrigo






RO Rodrigo February 19, 2020 03:13 PM UTC

Don't know if I should report this here or not.

When changing views (month to week, etc) I'm getting there error on the image below. Is this because I'm not setting the StartTime / EndTime values on my custom edit window?




AK Alagumeena Kalaiselvan Syncfusion Team February 19, 2020 03:35 PM UTC

Hi Rodrigo 

Thanks for your update! 

Query 1: “Scheduler gets flickered while applying color to the large number of appointment data” 

We have validated with your query and the reported issue occurs for when the color applied for large number of data through the “EventRendered” event. The scheduler flickers because of the “EventRendered” invoked for every appointments. So, we have considered this as improvement and logged the feature request. Refer below link for that. 


We will implement this feature request for our volume 1,  SP1 release on end of April, 2020.  

Query 2 & 3: “sometimes event data seems empty but tooltip shows the relevant information ” & “Getting console error while navigating scheduler views” 

Could you please create new ticket for your further queries ? 

Kindly get back to us, If you need further assistance. 

Regards 
Alagumeena.K 



VM Vengatesh Maniraj Syncfusion Team October 7, 2020 09:12 AM UTC

Hi Rodrigo, 

We are glad to announce that our Essential Studio 2020 Volume 3 Release v18.3.0.35  is rolled out and in that release, We've included the option to customize appointments from build-in CSS class field mapping. So please update your package to this version to include the feature. 


We thank you for your support and appreciate your patience in waiting for this release. Please get in touch with us if you would require any further assistance. 

Regards, 
Vengatesh  


Loader.
Up arrow icon