Cascading Dropdown in Scheduler Editor for CORE Razor Pages

1 Answer 262 Views
Scheduler
randy2101
Top achievements
Rank 1
randy2101 asked on 08 Sep 2021, 04:28 AM

Howdy.. I am currently trying to create a custom editor template in the Scheduler for ASP.NET CORE using Razor pages. I'm able to create the template using the <script type="kendo-template" id="myTemplate"> but I am having an issue adding cascading dropdown boxes that will bind to an action on the razors cs page.  Is this possible and if so what is the preferred method to achive this.

Thanks.....

1 Answer, 1 is accepted

Sort by
0
Aleksandar
Telerik team
answered on 10 Sep 2021, 12:07 PM

Hi randy2101,

When using HTML wrappers you can create a EditorTemplate, place it in the ~/Pages/Shared/EditorTemplates folder and then point the Scheduler that a particular template should be used for editing the events.

That said you can create cascading DropDownLists in a custom template the following way:

Define a Scheduler and set the custom template for editing:

@(Html.Kendo().Scheduler<TelerikAspNetCoreApp346.Data.MeetingViewModel>()
    .Name("scheduler")
    .Height(600)
    .Views(views =>
    {
        views.DayView();
        views.WeekView(weekView => weekView.Selected(true));
        views.MonthView();
        views.AgendaView();
    })
    .Editable(e=>e.TemplateName("~/Pages/Shared/EditorTemplates/CustomEditor.cshtml"))
    .Timezone("Etc/UTC")
    .Resources(resource =>
    {
        resource.Add(m => m.RoomID)
            .Title("Room")
            .DataTextField("Text")
            .DataValueField("Value")
            .DataColorField("Color")
            .BindTo(new[] {
                    new { Text = "Meeting Room 101", Value = 1, Color = "#6eb3fa" },
                    new { Text = "Meeting Room 201", Value = 2, Color = "#f58a8a" }
                });
        resource.Add(m => m.Attendees)
            .Title("Attendees")
            .Multiple(true)
            .DataTextField("Text")
            .DataValueField("Value")
            .DataColorField("Color")
            .BindTo(new[] {
                    new { Text = "Alex", Value = 1, Color = "#f8a398" },
                    new { Text = "Bob", Value = 2, Color = "#51a0ed" },
                    new { Text = "Charlie", Value = 3, Color = "#56ca85" }
                });
    })
    .DataSource(d => d
        .Model(m =>
        {
            m.Id(f => f.MeetingID);
            m.Field(f => f.Title).DefaultValue("No title");
            m.Field(f => f.Attendees).DefaultValue(1);
            m.RecurrenceId(f => f.RecurrenceID);
        })
        .Events(e => e.Error("error_handler"))
        .Read(read=>read.Url(Url.Page("Index","Meetings_Read")).Data("forgeryToken"))
        .Create(create=>create.Url(Url.Page("Index", "Meetings_Create")).Data("forgeryToken"))
        .Destroy(destroy=>destroy.Url(Url.Page("Index", "Meetings_Destroy")).Data("forgeryToken"))
        .Update(u=>u.Url(Url.Page("Index", "Meetings_Update")).Data("forgeryToken"))
    )
)

<script>
    function forgeryToken() {
        return kendo.antiForgeryTokens();
    }
    function error_handler(e) {
        if (e.errors) {
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
            var scheduler = $("#scheduler").data("kendoScheduler");
            scheduler.one("dataBinding", function (e) {
                //prevent saving if server error is thrown
                e.preventDefault();
            })
        }
    }
    function filterProducts() {
        return {
            categoryId: $("#CategoryID").val(),
            __RequestVerificationtoken:forgeryToken().__RequestVerificationtoken
        };
    }
</script>

CustomEditor.cshtml

@model TelerikAspNetCoreApp346.Data.MeetingViewModel
@{
    //required in order to render validation attributes
    ViewContext.FormContext = new FormContext();
}

@functions{
    public Dictionary<string, object> generateDatePickerAttributes(
           string elementId,
           string fieldName,
           string dataBindAttribute,
           Dictionary<string, object> additionalAttributes = null)
    {

        Dictionary<string, object> datePickerAttributes = additionalAttributes != null ? new Dictionary<string, object>(additionalAttributes) : new Dictionary<string, object>();

        datePickerAttributes["id"] = elementId;
        datePickerAttributes["name"] = fieldName;
        datePickerAttributes["data-bind"] = dataBindAttribute;
        datePickerAttributes["required"] = "required";
        datePickerAttributes["style"] = "z-index: inherit;";

        return datePickerAttributes;
    }
}

<div class="k-edit-label">
    @(Html.LabelFor(model => model.Title))
</div>
<div data-container-for="title" class="k-edit-field">
    @(Html.TextBoxFor(model => model.Title, new { @class = "k-textbox", data_bind = "value:title" }))
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.Start))
</div>
<div data-container-for="start" class="k-edit-field">

    @(Html.Kendo().DateTimePickerFor(model => model.Start)
        .HtmlAttributes(generateDatePickerAttributes("startDateTime", "start", "value:start,invisible:isAllDay")))
    @(Html.Kendo().DatePickerFor(model => model.Start)
        .HtmlAttributes(generateDatePickerAttributes("startDate", "start", "value:start,visible:isAllDay")))

    <span data-bind="text: startTimezone"></span>
    <span data-for="start" class="k-invalid-msg"></span>
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.End))
</div>
<div data-container-for="end" class="k-edit-field">

    @(Html.Kendo().DateTimePickerFor(model => model.End)
        .HtmlAttributes(generateDatePickerAttributes(
            "endDateTime",
            "end",
            "value:end,invisible:isAllDay",
            new Dictionary<string, object>() {{"data-dateCompare-msg", "End date should be greater than or equal to the start date"}})))
    @(Html.Kendo().DatePickerFor(model => model.End)
        .HtmlAttributes(generateDatePickerAttributes(
            "endDate",
            "end",
            "value:end,visible:isAllDay",
            new Dictionary<string, object>() {{"data-dateCompare-msg", "End date should be greater than or equal to the start date"}})))

    <span data-bind="text: endTimezone"></span>
    <span data-for="end" class="k-invalid-msg"></span>
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.IsAllDay))
</div>
<div data-container-for="isAllDay" class="k-edit-field">
    <input data-bind="checked: isAllDay" data-val="true" id="IsAllDay" name="IsAllDay" type="checkbox" />
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.RecurrenceRule))
</div>
<div data-container-for="recurrenceRule" class="k-edit-field">
    @(Html.Kendo().RecurrenceEditorFor(model => model.RecurrenceRule)
        .HtmlAttributes(new { data_bind = "value:recurrenceRule" }))
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.Description))
</div>
<div data-container-for="description" class="k-edit-field">
    @(Html.TextAreaFor(model => model.Description, new { @class = "k-textbox", data_bind = "value:description" }))
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.RoomID))
</div>
<div data-container-for="RoomID" class="k-edit-field">
    @(Html.Kendo().DropDownListFor(model => model.RoomID)
        .HtmlAttributes(new { data_bind = "value:RoomID", style = "width: 200px" })
        .DataTextField("Text")
        .DataValueField("Value")
        .OptionLabel("None")
        .ValuePrimitive(true)
        .Template("<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#")
        .BindTo(new[] {
                new { Text = "Meeting Room 101", Value = 1, Color = "\\#6eb3fa" },
                new { Text = "Meeting Room 201", Value = 2, Color = "\\#f58a8a" }
            }).ToClientTemplate()
    )
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.Attendees))
</div>
<div data-container-for="Attendees" class="k-edit-field">
    @(Html.Kendo().MultiSelectFor(model => model.Attendees)
        .HtmlAttributes(new { data_bind = "value:Attendees" })
        .DataTextField("Text")
        .DataValueField("Value")
        .ValuePrimitive(true)
        .TagTemplate("<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#")
        .ItemTemplate("<span class='k-scheduler-mark' style='background-color:\\#= data.Color?Color:'' \\#'></span>\\#=Text\\#")
        .BindTo(new[] {
                new { Text = "Alex", Value = 1, Color = "\\#f8a398" },
                new { Text = "Bob", Value = 2, Color = "\\#51a0ed" },
                new { Text = "Charlie", Value = 3, Color = "\\#56ca85" }
            })
    )
</div>

<div class="k-edit-label">
    @(Html.LabelFor(model => model.CategoryID))
</div>
<div data-container-for="Attendees" class="k-edit-field">
    @(Html.Kendo().DropDownListFor(x=>x.CategoryID)
              .HtmlAttributes(new { data_bind = "value:CategoryID" })
              .OptionLabel("Select category...")
              .DataTextField("CategoryName")
              .DataValueField("CategoryID")
              .ValuePrimitive(true)
              .DataSource(source =>
              {
                  source.Read(read =>
                  {
                      read.Url(Url.Page("Index","Categories")).Data("forgeryToken");
                  });
              })
    )
</div>
<div class="k-edit-label">
    @(Html.LabelFor(model => model.ProductID))
</div>
<div data-container-for="Attendees" class="k-edit-field">
    @(Html.Kendo().DropDownListFor(x=>x.ProductID)
              .HtmlAttributes(new { data_bind = "value:ProductID" })
              .OptionLabel("Select product...")
              .DataTextField("ProductName")
              .DataValueField("ProductID")
              .ValuePrimitive(true)
              .DataSource(source =>
              {
                  source.Read(read =>
                  {
                      read.Url(Url.Page("Index", "Products"))
                          .Data("filterProducts");
                  })
                  .ServerFiltering(true);
              })
              .Enable(false)
              .AutoBind(false)
              .CascadeFrom("CategoryID")
    )
</div>

As a result you will have two cascading DropDownLists in the editor template. Here is a screencast demonstrating the above.

I hope this helps.

Regards,
Aleksandar
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Scheduler
Asked by
randy2101
Top achievements
Rank 1
Answers by
Aleksandar
Telerik team
Share this question
or