KendoUI-如何在运行时基于用户输入创建控件? [英] KendoUI - How to create controls at runtime based on user input?

查看:90
本文介绍了KendoUI-如何在运行时基于用户输入创建控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以在运行时在KendoUI网格列中创建不同类型的控件?场景是,我的网格中有2列.第一列显示一个下拉列表,其中包含一些字符串,例如名称","StartDate"等.当用户从中选择一个值时,我想在第二列中显示一个适当的控件.如果用户选择"StartDate",我想显示"DateTime"控件.您能否让我知道如何通过ASP.Net MVC 5包装器做到这一点?

Is there a way to create different type of controls in a KendoUI grid column at runtime? The scenario is, I have 2 columns in my grid. The first column displays a dropdown list which has the some strings like, 'Name', 'StartDate', etc. When user selects a value from it, I want to show an appropriate control in the 2nd column. If the user picks 'StartDate', I want to show the 'DateTime' control. Can you please let me know how to do this thru ASP.Net MVC 5 wrapper?

示例代码:

@(Html.Kendo().Grid<ArulUI.Models.UserFilter>()
    .Name("Grid")
    .Columns(columns =>
    {
        columns.ForeignKey(f => f.FilterName, (System.Collections.IEnumerable)ViewData["Filters"], "Name", "Name");
        columns.Bound(f => f.FilterValue).ClientTemplate("#= gridValueColumnFormatter(data) #");

        columns.Template(t => { }).HeaderTemplate("").ClientTemplate(@"
            <a href='javascript: void(0)' class='abutton delete' onclick='deleteRow(this)' title='remove'>remove</a>")
             .Width(100).Title("");
    })
    .ToolBar(toolbar =>
    {
        toolbar.Create();
        toolbar.Save();
    })

    .Editable(editable => editable.Mode(GridEditMode.InCell))
    .Editable(e => e.DisplayDeleteConfirmation(false))
    .Sortable()
    .Scrollable()
    .Events(e => e.Edit("onEdit"))
    .DataSource(dataSource => dataSource
        .Ajax()
        .ServerOperation(false)
        .Model(model =>
        {
            model.Id(f => f.Id);
            model.Field(f => f.Id).Editable(false);
        })
        .Create(create => create.Action("Filter_Create", "Home"))
        .Destroy(destroy => destroy.Action("Filter_Delete", "Home"))
        .Read(read => read.Action("Filter_Read", "Home"))
        .Update(update => update.Action("Filter_Update", "Home"))
    )
)

<script>

    function gridValueColumnFormatter(dataRow) {
        var returnValue = "";
        if (dataRow.FilterName == "DateTimeRange") {
            returnValue = kendo.format('{0:MM/dd/yyyy hh:mm}', new Date(dataRow.FilterValue));
        }
        else {
            returnValue = dataRow.FilterValue;
        }

        return returnValue;
    }


    function onEdit(e) {
        var actElement = document.activeElement;
        //alert(txt.id);
        if (actElement.id == "FilterValue") {
            var selectedValue = e.model.FilterValue;
            var selectedDate = Date.parse(selectedValue);
            console.log(selectedValue);
            console.log(selectedDate);

            if (e.model.FilterName == "DateTimeRange") {
                if (isNaN(selectedDate)) {
                    initDatePicker(new Date());
                } else {
                    //initDatePicker(selectedValue);
                    $("#FilterValue").kendoDateTimePicker({
                        value: new Date(selectedValue)
                    });
                }
            } else {
                if (!isNaN(selectedDate)) {
                    $("#FilterValue").val("");
                }
            }
        }
    }

    function initDatePicker(dateValue) {
        $("#FilterValue").empty();

        $("#FilterValue").kendoDateTimePicker({
            value: new Date(dateValue),
            format: "MM/dd/yyyy hh:mm",
            parseFormats: "MM/dd/yyyy hh:mm"
        });
        var dateTimePicker = $("#FilterValue").data("kendoDateTimePicker");
        dateTimePicker.value(dateValue);

    }

    function disposeDatePicker() {
        var datepicker = $("#FilterValue").data("kendoDateTimePicker");
        if (datepicker) {
            popup = datepicker.dateView.popup;
            element = popup.wrapper[0] ? popup.wrapper : popup.element;

            //Move the shared calendar to the body
            kendo.ui.DatePicker.sharedCalendar.element.hide().appendTo(document.body);

            //remove popup element;
            element.remove();
            //unwrap element
            var input = datepicker.element.show();

            input.removeClass("k-input"); //.css("width", "auto");
            input.insertBefore(datepicker.wrapper);

            datepicker.wrapper.remove();

            //remove DatePicker object
            input.removeData("kendoDateTimePicker");
        }
    }

    function deleteRow(element) {
        grid = $("#Grid").data("kendoGrid");
        grid.removeRow($(element).closest("tr"));
    }

    function createRow() {
        grid = $("#Grid").data("kendoGrid");
        grid.addRow();
    }
</script>

Controller:

public class HomeController : Controller
    {
        public static List<ArulUI.Models.Filter> ListFilter = new List<ArulUI.Models.Filter>();
        public static List<UserFilter> ListUserFilters = new List<UserFilter>();
        public void Seed()
        {
            ListFilter = new List<Models.Filter>{
                new ArulUI.Models.Filter { Name = "Name", Type="string"},
                new ArulUI.Models.Filter { Name = "Dept", Type="string"},
                new ArulUI.Models.Filter { Name = "Age", Type="string"},
                new ArulUI.Models.Filter { Name = "DateTimeRange", Type="datetime"}
            };

            ListUserFilters = new List<UserFilter> {
                new UserFilter { Id = 1, FilterName="Name", FilterValue = "Empty"},
                new UserFilter { Id = 2, FilterName="Dept", FilterValue = "Empty2"},
                //new UserFilter { Id = 2, FilterName="DateTimeRange", FilterValue = "12/20/2013 10:00"}
            };
        }

        public ActionResult Index()
        {
            this.Seed();
            ViewData["Filters"] = ListFilter.Select(f => new
            {
                Name = f.Name,
                Type = f.Type
            });

            return View();
        }

        public ActionResult Filter_Read([DataSourceRequest] DataSourceRequest request)
        {
            return Json(ListUserFilters.ToDataSourceResult(request));
        }

        public ActionResult Filter_Delete([DataSourceRequest] DataSourceRequest request, UserFilter userFilter)
        {
            if (userFilter != null && ModelState.IsValid)
            {
                var target = ListUserFilters.Where(f => f.Id == userFilter.Id).FirstOrDefault();

                if (target != null)
                {
                    ListUserFilters.Remove(target);
                }
            }

            return Json(ModelState.ToDataSourceResult());
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Filter_Update([DataSourceRequest] DataSourceRequest request, UserFilter userFilter)
        {
            if (userFilter != null && ModelState.IsValid)
            {
                var target = ListUserFilters.Where(f => f.Id == userFilter.Id).FirstOrDefault();
                if (target != null)
                {
                    int targetIndex = ListUserFilters.IndexOf(target);
                    ListUserFilters[targetIndex].FilterName = target.FilterName;
                    ListUserFilters[targetIndex].FilterValue = target.FilterValue;
                }
            }

            return Json(ModelState.ToDataSourceResult());
        }

        public ActionResult Filter_Create([DataSourceRequest] DataSourceRequest request, UserFilter userFilter)
        {
            userFilter.Id = ListUserFilters[ListUserFilters.Count - 1].Id + 1;
            userFilter.Id = 10;
            ListUserFilters.Add(userFilter);

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


        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
    }

谢谢

推荐答案

您可能必须自己实现该功能,例如通过绑定下拉菜单的更改事件来存储所选控件类型(例如,"kendoDatePicker)在变量的地方,然后有一个数据结构,为您提供每个控件类型相应的选项.然后,您可以根据该控件类型变量使第二列的编辑器模板动态化.

You'll likely have to implement that yourself, e.g. by binding the dropdown's change event to store the selected control type (e.g. "kendoDatePicker") in a variable somewhere, then have a data structure that gives you the appropriate options for each control type. Then you can make your editor template for the second column dynamic based on that control type variable.

如果您使用内联编辑并且想直接替换编辑器,则下拉更改处理程序可能看起来像这样(请注意,为了很好地显示各种值类型,您可能还需要一个复杂的显示模板):

If you use inline editing and you want to replace the editor directly, your dropdown change handler might look something like this (note that in order to display the various value types nicely, you'll probably need a complex display template as well):

change: function (e) {
    // select other column by index, for example
    var secondColumn = $(e.sender.element).closest("td").siblings().eq(0);
    var name = $(secondColumn).find("input").attr("name");
    secondColumn.empty(); // remove existing editor (you should also call .destroy() for existing widgets in there!)
    var model = grid._modelForContainer(secondColumn); // get associated data model from kendoGrid instance

    $("<input data-bind='value: " + name + "'/>").appendTo(secondColumn).kendoDatePicker();
    kendo.bind(secondColumn, model); // bind the model again manually
}

请参见此处演示

如果您使用单元内编辑,则应使用我之前建议的编辑器模板;您的动态列的模板函数可能看起来像这样:

If you use in-cell editing, then you should use the editor template as I suggested before; the template function for your dynamic column might look something like this:

editor: function (container, options) {
    // model.typeTitle is set by the dropdown column
    if (options.model.typeTitle === "DateTime") {
        $("<input data-bind='value:name' />")
            .appendTo(container).kendoDateTimePicker(controlOptions["kendoDateTimePicker"]);
    } else if (options.model.typeTitle === "String") {
        $("<input data-bind='value:name' />")
            .appendTo(container);
    } else if (options.model.typeTitle === "Number") {
        $("<input data-bind='value:name' />")
            .appendTo(container).kendoNumericTextBox();
    }  
}

此处演示

这篇关于KendoUI-如何在运行时基于用户输入创建控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆