Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a DropDownList in Kendo Scheduler Custom Template (ASP.NET MVC Wrapper version)

I'm using the ASP.NET MVC wrapper for Kendo UI and I'm trying to bind several dropdownlists within a custom template (x-kendo-template). I can't figure out how to do this using the ASP.NET MVC Wrapper (this is similar to this question: How do I bind a DropDownList to a DataSource within an editor template using the scheduler?).

There are some examples on using the Kendo Web version, but no complete examples out there that show using a custom pop-up editor with the scheduler that contains a dropdownlist pulling data from a URL (json data).

Is there an end-to-end example? I can load the scheduler with data. The issue is with the custom template and dropdownlist binding.

EDIT:

After searching extensively, I stumbled upon a "getting started" page from Telerik on using the Kendo UI Scheduler in ASP.NET MVC. They (Telerik) really need to do a better job cross-linking between Demos to Documentation to APIs and Examples (Here is the example)

I've also created a blog post that wraps everything for a Scheduler (from the database table to the Views), you can see that here.Kendo UI Scheduler with ASP.NET MVC and Peta Poco

The example shed some light which the demo and documentation do not do, like for instance, the ViewModel they use in their example online:

C# ViewModel

public class Projection : ISchedulerEvent
{
    public string Title { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public string Description { get; set; }
    public bool IsAllDay { get; set; }
    public string Recurrence { get; set; }
    public string RecurrenceRule { get; set; }
    public string RecurrenceException { get; set; }

    // Custom Field
    public int EventId { get; set; }
    public int CustomerId { get; set; }
}

Your ViewModel that you use for the Scheduler must inherit from the ISchedulerEvent class or it will not work correctly.

Razor View

The Razor View is pretty straight-forward, although most of the demos you run across will show data getting passed via the server-side (from the controller). Here, I'm doing this via Ajax methods (Create, Read, Update, Destroy).

@(Html.Kendo().Scheduler<KendoUISchedulerDemo.Models.Projection>()
    .Name("scheduler")
    .Date(DateTime.Today)
    .Height(600)
    .DataSource(d => d
        .Model(m =>
        {
            m.Id(f => f.EventId);
            m.Field(f => f.Title);
            m.Field(f => f.CustomerId);
            m.Field(f => f.Description);
            m.RecurrenceId(f => f.Recurrence);
        })
        .Read("Read", "Shared", new { Area = "Events" })
        .Create("Create", "Shared", new { Area = "Events" })
        .Destroy("Destroy", "Shared", new { Area = "Events" })
        .Update("Update", "Shared", new { Area = "Events" })
)
.Events( events =>
    {
        events.Add("ABC.events.SchedulerAdd");
    })
.Editable(edit =>
{
    edit.TemplateId("schedulerTemplate");
})
)

The main point with using the datasource with ajax calls like above is that it allows us to put the methods in a separate controller so that we can keep the controller that is displaying the view clean.

Razor View - Kendo Template (for the pop-up editor of events)

This is the script block for the x-kendo-template that overwrites the default pop-up window when creating and editing events in the Kendo Scheduler. This script is pretty much the wild west and you can do whatever you want in it, and it is bound by default with the Kendo MVVM model. Take that with a grain of salt though because there is not a documented way to "extend" that ViewModel to properly put your datasources from custom drop down lists in the ASP.NET MVC wrapper (version) of the Scheduler. (This uses Twitter Bootstrap as well)

<script type="text/x-kendo-template" id="schedulerTemplate">
<div class="form-group">
    <div class="col-md-5">
        @Html.Label("title", "Title", new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            <input class="k-textbox" data-bind="value: title" />
        </div>
    </div>
</div>
<div class="form-group mTop10">
    @Html.Label("CustomerId", "Customer", new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        <input id="CustomerId" class="w450" />
    </div>
</div>
<div class="form-group mTop10">
    <div class="left col-md-5">
        @Html.Label("start", "Start", new { @class = "col-md-2 control-label left" })
        <div class="col-md-10">
            <input name="start" type="text" required  data-type="date" data-role="datetimepicker" data-bind="value: start,invisible: isAllDay" />
            <input name="start" type="text" required  data-type="date" data-role="datepicker" data-bind="value: start,visible: isAllDay" /> 
        </div>
    </div>
    <div class="left col-md-5">
        @Html.Label("end", "End", new { @class = "col-md-2 control-label left" })
        <div class="col-md-10">
            <input name="end" type="text" required data-type="date" data-role="datetimepicker" data-bind="value: end ,invisible:isAllDay" />    
            <input name="end" type="text" required data-type="date" data-role="datepicker" data-bind="value: end ,visible:isAllDay" />
        </div>
    </div>
</div>
<div class="clear"></div>
<div class="form-group mTop10">
    @Html.Label("isAllDay", "All Day", new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        <input type="checkbox" name="isAllDay" data-type="boolean" data-bind="checked:isAllDay">
    </div>
</div>
</script>

JsonResults (in Controller)

Here are the CRUD Json Results. The Create, Update and Destroy JsonResults have been trimmed for the example.

public virtual JsonResult Read([DataSourceRequest] DataSourceRequest request)
    {
        var data = new List<Projection>();
        data.Add(new Projection()
        {
            EventId = 1,
            Start = DateTime.Now.AddDays(-2),
            End = DateTime.Now.AddDays(-2).AddHours(2),
            IsAllDay = false,
            CustomerId = 1,
            Description = "Booked for plumbing",
            Title = "Manchester Residence"
        });

        return Json(data.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

public virtual JsonResult Create([DataSourceRequest] DataSourceRequest request, Projection evt)
    {
        if (ModelState.IsValid)
        {
            // Other code here
        }

        return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
    }

public virtual JsonResult Update([DataSourceRequest] DataSourceRequest request, Projection evt)
    {
        if (ModelState.IsValid)
        {
            // Other code here
        }

        return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
    }

public virtual JsonResult Destroy([DataSourceRequest] DataSourceRequest request, Projection evt)
    {
        if (ModelState.IsValid)
        {
            // Other code here
        }

        return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
    }

JavaScript

Here is the JavaScript contained within a stand alone JS file that corresponds to my "Add" event for the Scheduler. I didn't show the "Edit" event as it is pretty much the same idea and you should be able to figure it out.

ABC.Events.SchedulerAdd = function (e) {

    function GetCustomers(value) {
        var url = "/Events/Shared/GetCustomers"
        var success = function (result) {
            if (result != null) {
                $("#CustomerId").kendoDropDownList({
                    dataTextField: "FullName",
                    dataValueField: "CustomerId",
                    dataSource: new kendo.data.DataSource({ data: result })
                });
            }
        };

        $.ajax({ url: url, success: success });
    }

    GetCustomers();
};

One of the keys in this JavaScript function is that we are turning our field into a Kendo DropDownList and wiring our datasource up at the same time that we are receiving as a JsonResult (not shown, but it's a simple Json object). Another key is how we wire up the datasource as we are creating a new kendo.data.DataSource. If you try to simply wire up the JsonResult, it won't work.

Conclusion

This is a work around to fill dropdownlists in a Scheduler Template (pop-up) when using the ASP.NET MVC Wrapper version of the Kendo UI. I am open for a better way, in which I imagine it will be adding the Json list data to the Internal MVVM that the Kendo Scheduler uses, but without the documentation for ASP.NET MVC or examples of how to pull it off, this is a way it can work.

EDIT #2 - Telerik ASP.NET MVC Example

I finally heard back from Telerik Support on this issue and was directed to this link: http://www.telerik.com/support/code-library/custom-editor-9fd60fca3c02 There is a sample MVC project there that shows how to use a Custom Editor, Drop Down Lists with datasources, all within ASP.NET MVC. Why on Earth there is no link from the documentation to such projects that can obviously help is a mystery to me.

like image 990
piercove Avatar asked Mar 06 '14 20:03

piercove


1 Answers

Did you manage to figure this out? I'm working on something similar and have managed to get some of this to work and I have a demo that might help. Mine is not 100% right now but I am getting there. I have a custom template linked to a resource. My issue is sometimes the model doesn't validate so I don't get a post back to the Jason method in the controller. Have you seen this example?

like image 93
Jason James Avatar answered Oct 20 '22 16:10

Jason James