有没有办法在运行时在KendoUI网格列中创建不同类型的控件?场景是,我的网格中有2列。第一列显示一个下拉列表,其中包含一些字符串,如'Name','StartDate'等。当用户从中选择一个值时,我想在第二列中显示一个适当的控件。如果用户选择“StartDate”,我想显示“DateTime”控件。你能通过ASP.Net MVC 5包装让我知道怎么做吗?
示例代码:
@(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();
}
}
谢谢
答案 0 :(得分:1)
您可能必须自己实施,例如通过绑定下拉列表的change event将选定的控件类型(例如“kendoDatePicker”)存储在某个变量中,然后有一个数据结构,为每种控件类型提供适当的选项。然后,您可以根据该控件类型变量使第二列的编辑器模板动态化。
如果您使用内联编辑并且想要直接替换编辑器,则下拉更改处理程序可能看起来像这样(请注意,为了很好地显示各种值类型,您可能还需要一个复杂的显示模板):
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
}
请参阅demo here
如果您使用单元格内编辑,那么您应该使用我之前建议的编辑器模板;动态列的模板函数可能如下所示:
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();
}
}