I have a Kendo Grid which is linked to a custom popup editor template. I'm not using the default Add button that Kendo provides, because I need to have several different buttons which pass an additional parameter to my on_edit function, which is bound to the edit event. Everything works correctly the first time I click an add button, but once the cancel button has been clicked on the editor window, pressing any of the Add buttons causes a blank row to appear in the grid (as if to be populated by the editor), but the popup editor window itself does not appear. When I simply remove the template from the equation altogether, the code all works correctly, which makes me think the problem is not with my custom Add buttons, but with the editor template.
Grid Declaration
@(Html.Kendo().Grid<ScheduleProcess.Process>
()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.TriggerName);
columns.Bound(c => c.Description);
columns.Bound(c => c.Category);
columns.Bound(c => c.Enabled).ClientTemplate("<input type='checkbox' ${ Enabled == true ? checked='checked' : '' } disabled />").Width(75);
columns.ForeignKey(c => c.TriggerType, EnumHelper.GetSelectList(typeof(ScheduleProcess.TriggerTypes)).ToList(), "Value", "Text");
columns.Bound(c => c.LastRun).Format("{0:MM/dd/yy hh:mm:ss tt}");
columns.Bound(c => c.LastUnSuccessfulRun).Format("{0:MM/dd/yy hh:mm:ss tt}");
columns.Bound(c => c.EventId);
columns.Command(c => c.Edit().UpdateText("Save"));
columns.Command(c => c.Destroy());
//Hidden Columns
columns.ForeignKey(c => c.ProcessThreadType, EnumHelper.GetSelectList(typeof(ScheduleProcess.ThreadType)).ToList(), "Value", "Text").Hidden(true);
columns.Bound(c => c.RunInterval).Hidden(true);
})
.HtmlAttributes(new { style = "height: 750px;" })
.Resizable(resize => resize.Columns(true))
.Scrollable(scrollable => scrollable.Virtual(true))
.Sortable()
.Selectable()
.Editable(edit => edit.Mode(GridEditMode.PopUp).TemplateName("ProcessesEditor"))
.ToolBar(toolbar =>
{
toolbar.Template(
@<text>
@(Html.Kendo().Button()
.Content("Add One Time Trigger")
.Name("OneTimeTriggerAdd")
.Events(e => e.Click("AddOneTimeTrigger"))
)
@(Html.Kendo().Button()
.Content("Add Interval Trigger")
.Name("IntervalTriggerAdd")
.Events(e => e.Click("AddIntervalTrigger"))
)
@(Html.Kendo().Button()
.Content("Add Daily Trigger")
.Name("DailyTriggerAdd")
.Events(e => e.Click("AddDailyTrigger"))
)
@(Html.Kendo().Button()
.Content("Add Weekly Trigger")
.Name("WeeklyTriggerAdd")
.Events(e => e.Click("AddWeeklyTrigger"))
)
@(Html.Kendo().Button()
.Content("Add Monthly Trigger")
.Name("MonthlyTriggerAdd")
.Events(e => e.Click("AddMonthlyTrigger"))
)
<br /><br />
Category:
@(Html.Kendo().MultiSelect()
.Name("CategoryMS")
.BindTo((System.Collections.IEnumerable)ViewData["Categories"])
.DataTextField("Category")
.DataValueField("Category")
.Events(e => e.Change("Refresh"))
.AutoClose(false)
)
@(Html.Kendo().Button()
.Name("Refresh")
.Events(e => e.Click("Refresh"))
.Content("Search")
)
<a class="k-button k-button-icontext k-grid-excel" href="#"><span class="k-icon k-i-excel"></span>Export</a>
</text>);
})
.Excel(excel => excel
.FileName("Process_Export.xlsx")
)
.DataSource(dataSource => dataSource
.Ajax()
.Events(e => e.Error("onError").RequestEnd("update_grid"))
.Model(model => {
model.Id(a => a.TriggerId);
model.Field(a => a.TriggerId).DefaultValue(0);
model.Field(a => a.Category);
model.Field(a => a.DayOfWeek);
model.Field(a => a.Description);
model.Field(a => a.DisableAfterFailure);
model.Field(a => a.Enabled);
model.Field(a => a.EstimatedProcessRunTime);
model.Field(a => a.EventId);
model.Field(a => a.LastRun).DefaultValue(DateTime.MinValue);
model.Field(a => a.LastUnSuccessfulRun).DefaultValue(DateTime.MinValue);
model.Field(a => a.MethodParameters);
model.Field(a => a.ProcessParameters);
model.Field(a => a.ProcessThreadType);
model.Field(a => a.Retries);
model.Field(a => a.RunEvery);
model.Field(a => a.RunEveryDays);
model.Field(a => a.RunEveryWeeks);
model.Field(a => a.RunInterval);
model.Field(a => a.RunOnDay);
model.Field(a => a.RunOnDayOf);
model.Field(a => a.RunOnlyOnWeekdays);
model.Field(a => a.RunOnWeek);
model.Field(a => a.RunProcess);
model.Field(a => a.SelectedEndpointName);
model.Field(a => a.SelectedMethodName);
model.Field(a => a.ServiceAddress);
model.Field(a => a.StartDate);
model.Field(a => a.StartTime);
model.Field(a => a.TriggerName);
model.Field(a => a.TriggerType);
model.Field(a => a.WaitTimeTillRetry);
model.Field(a => a.WeekType);
})
.Create(update => update.Action("Process_Create", "Grid"))
.Update(update => update.Action("Process_Update", "Grid"))
.Destroy(update => update.Action("Process_Destroy", "Grid"))
.Read(read => read.Action("Process_Read", "Grid"))
.PageSize(500)
)
)
Note:
Replacing
.Editable(edit => edit.Mode(GridEditMode.PopUp).TemplateName("ProcessesEditor"))
with
.Editable(edit => edit.Mode(GridEditMode.PopUp))
restores all expected functionality and completely fixes the issue.
Add Buttons' Javascript functions
function AddOneTimeTrigger() {
NewTriggerType = "4"; //OneTime
var grid = $("#grid").data("kendoGrid");
grid.addRow();
}
function AddIntervalTrigger() {
NewTriggerType = "0"; //Interval
var grid = $("#grid").data("kendoGrid");
grid.addRow();
}
function AddDailyTrigger() {
NewTriggerType = "1"; //Daily
var grid = $("#grid").data("kendoGrid");
grid.addRow();
}
function AddWeeklyTrigger() {
NewTriggerType = "2"; //Weekly
var grid = $("#grid").data("kendoGrid");
grid.addRow();
}
function AddMonthlyTrigger() {
NewTriggerType = "3"; //Monthly
var grid = $("#grid").data("kendoGrid");
grid.addRow();
}
Editor Template
@model ScheduleProcess.Process
@Html.HiddenFor(model => model.TriggerId)
@* Name *@
<div style="text-align:center">
@Html.LabelFor(model => model.TriggerName, new { style = "color:#00FF00" })
@Html.TextBoxFor(model => model.TriggerName, new { style = "width:75%; font-size:90%" })
</div>
@* Description *@
<div style="text-align:center">
@Html.LabelFor(model => model.Description, new { style = "color:#ffff99; font-size:80%" })
@Html.TextBoxFor(model => model.Description, new { style = "width:75%; font-size:90%" })
</div>
@* Category *@
<div style="text-align:center">
@Html.LabelFor(model => model.Category, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.Category)
</div>
@* Enabled *@
<div style="text-align:center">
@Html.LabelFor(model => model.Enabled, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.Enabled)
</div>
@* Disable After Failure *@
<div style="text-align:center">
@Html.LabelFor(model => model.DisableAfterFailure, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.DisableAfterFailure)
</div>
@* Process Thread Type *@
<div style="text-align:center">
@Html.LabelFor(model => model.ProcessThreadType, new { style = "color:#00FF00" })
@Html.EditorFor(model => model.ProcessThreadType)
</div>
@* Estimated Process Run Time *@
<div style="text-align:center">
@Html.LabelFor(model => model.EstimatedProcessRunTime, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.EstimatedProcessRunTime)
</div>
@* Number of Tries *@
<div style="text-align:center">
@Html.LabelFor(model => model.Retries, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.Retries)
</div>
@* Wait Time Until Retry *@
<div style="text-align:center">
@Html.LabelFor(model => model.WaitTimeTillRetry, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.WaitTimeTillRetry)
</div>
@* Service Address *@
<div style="text-align:center">
@Html.LabelFor(model => model.ServiceAddress, new { style = "color:#00FF00" })
@Html.TextBoxFor(model => model.ServiceAddress, new { style="width:75%; font-size:70%"})
</div>
@* Endpoint Name *@
<div style="text-align:center">
@Html.LabelFor(model => model.SelectedEndpointName, new { style = "color:#00FF00" })
@Html.TextBoxFor(model => model.SelectedEndpointName, new { style = "width:75%; font-size:90%" })
</div>
@* Process Name *@
<div style="text-align:center">
@Html.LabelFor(model => model.SelectedMethodName, new { style = "color:#00FF00" })
@Html.TextBoxFor(model => model.SelectedMethodName, new { style = "width:75%; font-size:90%" })
</div>
@* Process Parameters *@
<div style="text-align:center">
@Html.LabelFor(model => model.MethodParameters, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.MethodParameters)
</div>
@* Process Parameters(| delimeter) *@
<div style="text-align:center">
@Html.LabelFor(model => model.ProcessParameters, new { style = "color:#ffff99; font-size:80%" })
@Html.TextBoxFor(model => model.ProcessParameters, new { style = "width:75%; font-size:90%" })
</div>
@* Event Log ID *@
<div style="text-align:center">
@Html.LabelFor(model => model.EventId, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.EventId)
</div>
@* Trigger Type *@
<div style="text-align:center">
@Html.LabelFor(model => model.TriggerType, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.TriggerType)
</div>
@* Last Successful Run *@
<div style="text-align:center">
@Html.LabelFor(model => model.LastRun, new { style = "color:#ffff99; font-size:80%" })
@(Html.TextBoxFor(model => model.LastRun, "{0:MM/dd/yyyy hh:mm:ss tt}", new { type = "datetime-local" }))
</div>
@* Last Attempted Run *@
<div style="text-align:center">
@Html.LabelFor(model => model.LastUnSuccessfulRun, new { style = "color:#ffff99; font-size:80%" })
@Html.TextBoxFor(model => model.LastUnSuccessfulRun, "{0:MM/dd/yyyy hh:mm:ss tt}", new { type = "datetime-local" })
</div>
@* Run Interval *@
<div style="text-align:center" id="RunIntervalDiv">
@Html.LabelFor(model => model.RunInterval, new { style = "color:#ffff99; font-size:80%" })
@Html.Kendo().IntegerTextBoxFor(model => model.RunInterval.Hours).HtmlAttributes(new { style = "width: 30px;" }).Spinners(false).Max(23).Min(0).RestrictDecimals(true).Decimals(0).Format("00") :
@Html.Kendo().IntegerTextBoxFor(model => model.RunInterval.Minutes).HtmlAttributes(new { style = "width: 30px;" }).Spinners(false).Max(59).Min(0).RestrictDecimals(true).Decimals(0).Format("00") :
@Html.Kendo().IntegerTextBoxFor(model => model.RunInterval.Seconds).HtmlAttributes(new { style = "width: 30px;" }).Spinners(false).Max(59).Min(0).RestrictDecimals(true).Decimals(0).Format("00")
</div>
@* Start Date *@
<div style="text-align:center">
@Html.LabelFor(model => model.StartDate, new { style = "color:#ffff99; font-size:80%" })
@(Html.Kendo().DatePickerFor(model => model.StartDate))
</div>
@* Start Time *@
<div style="text-align:center">
@Html.LabelFor(model => model.StartTime, new { style = "color:#ffff99; font-size:80%" })
@(Html.Kendo().TimePickerFor(model => model.StartTime))
</div>
@* Run Only On Weekdays *@
<div style="text-align:center" id="RunOnlyOnWeekdaysDiv">
@Html.LabelFor(model => model.RunOnlyOnWeekdays, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.RunOnlyOnWeekdays)
</div>
@* Run Every *@
<div style="text-align:center" id="RunEveryDiv">
@Html.LabelFor(model => model.RunEvery, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.RunEvery)
</div>
@* Days *@
<div style="text-align:center" id="RunEveryDaysDiv">
@Html.LabelFor(model => model.RunEveryDays, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.RunEveryDays)
</div>
@* Run Every Week *@
<div style="text-align:center" id="RunEveryWeeksDiv">
@Html.LabelFor(model => model.RunEveryWeeks, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.RunEveryWeeks)
</div>
@* Run On *@
<div style="text-align:center" id="RunOnDayDiv">
@Html.LabelFor(model => model.RunOnDay, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.RunOnDay)
</div>
@* Day *@
<div style="text-align:center" id="RunOnDayOfDiv">
@Html.LabelFor(model => model.RunOnDayOf, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.RunOnDayOf)
</div>
@* Run On the *@
<div style="text-align:center" id="RunOnWeekDiv">
@Html.LabelFor(model => model.RunOnWeek, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.RunOnWeek)
</div>
@* Week *@
<div style="text-align:center" id="WeekTypeDiv">
@Html.LabelFor(model => model.WeekType, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.WeekType)
</div>
@* Day of Week *@
<div style="text-align:center" id="DayOfWeekDiv">
@Html.LabelFor(model => model.DayOfWeek, new { style = "color:#ffff99; font-size:80%" })
@Html.EditorFor(model => model.DayOfWeek)
</div>
I have searched StackOverflow and the Telerik forums, but the only seemingly relevant post I've found was this one, which is an attempt to use a custom popup window, not just using an editor template.