I have been using inline edit with the Grid control in several projects for a while now and everything has worked great. However, on a new page I have a grid that uses inline editing/creation, however when create is called via Ajax, all of the rows are passed into the controller action and my code is duplicating all the records. I have compared this page with the pages that work correctly and I cannot seem to find the issue. I must be missing something. I think I just need another set of eyes. Below is the code in the page/controller that is NOT working.
@model SS.Web.Models.SystemCustomerConcernViewModel
@{
ViewBag.Title = "SystemCustomerConcern";
}
<section class="contentTitle">
Customer Concern List
</section>
@(Html.Kendo().Grid<SS.Web.Models.SystemCustomerConcernViewModel>()
.Name("SystemCustomerConcernGrid")
.Columns(columns =>
{
columns.Command(command => command.Destroy()).Width(90).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(p => p.SystemCategoryType).ClientTemplate("#=SystemCategoryType.description#").Width(160).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.customerConcern).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.billedHours).Width(100).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.techPayHours).Width(115).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.servicePerformed);
})
.ToolBar(toolBar =>
{
toolBar.Create();
toolBar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.HtmlAttributes(new { style = "height: 675px" })
.Pageable()
.Sortable()
.Scrollable()
.Navigatable() //set so user can tab between cells in edit mode
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.PageSize(100)
.Batch(true)
.ServerOperation(false)
.Model(model =>
{
model.Id(i => i.systemCustomerConcernID);
model.Field(p => p.SystemCategoryType).DefaultValue(
ViewData["defaultSystemCategoryType"] as SS.Web.Models.SystemCategoryTypeViewModel); //this is used when you add a new item
})
.Read(read => read.Action("List", "SystemCustomerConcern"))
.Create(create => create.Action("Create", "SystemCustomerConcern"))
.Update(update => update.Action("Update", "SystemCustomerConcern"))
.Destroy(destroy => destroy.Action("Delete", "SystemCustomerConcern"))
))
<script type="text/javascript">
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);
}
}
</script>
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([DataSourceRequest] DataSourceRequest request,
[Bind(Prefix = "models")]IEnumerable<SystemCustomerConcernViewModel> systemCustomerConcerns)
{
var results = new List<SystemCustomerConcernViewModel>();
if (systemCustomerConcerns != null && ModelState.IsValid)
{
foreach (var systemCustomerConcernViewModel in systemCustomerConcerns)
{
SystemCustomerConcern systemCustomerConcern = new SystemCustomerConcern
{
customerConcern = systemCustomerConcernViewModel.customerConcern,
billedHours = systemCustomerConcernViewModel.billedHours,
techPayHours = systemCustomerConcernViewModel.techPayHours,
servicePerformed = systemCustomerConcernViewModel.servicePerformed,
isActive = systemCustomerConcernViewModel.isActive,
systemCategoryTypeID = systemCustomerConcernViewModel.SystemCategoryType.systemCategoryTypeID
};
systemCustomerConcernViewModel.systemCustomerConcernID = this.systemCustomerConcernService.Create(systemCustomerConcern);
results.Add(systemCustomerConcernViewModel);
}
}
return Json(results.ToDataSourceResult(request, ModelState));
}
@model SS.Web.Models.SystemCustomerConcernViewModel
@{
ViewBag.Title = "SystemCustomerConcern";
}
<section class="contentTitle">
Customer Concern List
</section>
@(Html.Kendo().Grid<SS.Web.Models.SystemCustomerConcernViewModel>()
.Name("SystemCustomerConcernGrid")
.Columns(columns =>
{
columns.Command(command => command.Destroy()).Width(90).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(p => p.SystemCategoryType).ClientTemplate("#=SystemCategoryType.description#").Width(160).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.customerConcern).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.billedHours).Width(100).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.techPayHours).Width(115).HtmlAttributes(new { style = "vertical-align: top;" });
columns.Bound(i => i.servicePerformed);
})
.ToolBar(toolBar =>
{
toolBar.Create();
toolBar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.HtmlAttributes(new { style = "height: 675px" })
.Pageable()
.Sortable()
.Scrollable()
.Navigatable() //set so user can tab between cells in edit mode
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.PageSize(100)
.Batch(true)
.ServerOperation(false)
.Model(model =>
{
model.Id(i => i.systemCustomerConcernID);
model.Field(p => p.SystemCategoryType).DefaultValue(
ViewData["defaultSystemCategoryType"] as SS.Web.Models.SystemCategoryTypeViewModel); //this is used when you add a new item
})
.Read(read => read.Action("List", "SystemCustomerConcern"))
.Create(create => create.Action("Create", "SystemCustomerConcern"))
.Update(update => update.Action("Update", "SystemCustomerConcern"))
.Destroy(destroy => destroy.Action("Delete", "SystemCustomerConcern"))
))
<script type="text/javascript">
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);
}
}
</script>
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([DataSourceRequest] DataSourceRequest request,
[Bind(Prefix = "models")]IEnumerable<SystemCustomerConcernViewModel> systemCustomerConcerns)
{
var results = new List<SystemCustomerConcernViewModel>();
if (systemCustomerConcerns != null && ModelState.IsValid)
{
foreach (var systemCustomerConcernViewModel in systemCustomerConcerns)
{
SystemCustomerConcern systemCustomerConcern = new SystemCustomerConcern
{
customerConcern = systemCustomerConcernViewModel.customerConcern,
billedHours = systemCustomerConcernViewModel.billedHours,
techPayHours = systemCustomerConcernViewModel.techPayHours,
servicePerformed = systemCustomerConcernViewModel.servicePerformed,
isActive = systemCustomerConcernViewModel.isActive,
systemCategoryTypeID = systemCustomerConcernViewModel.SystemCategoryType.systemCategoryTypeID
};
systemCustomerConcernViewModel.systemCustomerConcernID = this.systemCustomerConcernService.Create(systemCustomerConcern);
results.Add(systemCustomerConcernViewModel);
}
}
return Json(results.ToDataSourceResult(request, ModelState));
}