Hi there,
I am using a simple Kendo grid which contains a pop up form to allow a user to either add or delete new "categories" (many) for one product.
@using KendoGridOneToMany.Models
@(Html.Kendo().Grid<
ProductModel
>()
.Name("persons")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(m => m.Id))
.Read(read => read.Action("GetProducts", "Home"))
.Update(up => up.Action("UpdateCategory", "Home"))
.Create(x => x.Action("CreateProduct", "Home"))
)
.ToolBar(x => x.Create())
.Columns(columns =>
{
columns.Bound(c => c.Id).Width(200);
columns.Bound(c => c.Type);
columns.Bound(c => c.DisplayCatogories);
columns.Command(cmd => cmd.Edit());
})
.Events(ev => ev.Edit("addDeleteButton"))
.Pageable()
.Sortable()
.Editable(ed => ed.Mode(GridEditMode.PopUp).TemplateName("PopUpView"))
)
I have altered the pop up to contain an additional "delete" button. As this extra button is not supported by the grid's inbuilt update function, I have used AJAX to capture data within the pop up held in a form and return it to the controller's separate "delete" method.
The pop up form code is contained on a partial view that looks like so:
@model ProductModel
<
div
>
<
fieldset
id
=
"popUpForm"
>
<
dl
>
<
dt
>
@Html.HiddenFor(m => m.Id)
@Html.ValidationMessageFor(m => m.CategoryId)
</
dt
>
<
dd
>
@(Html.Kendo().DropDownListFor(m => m.CategoryId).AutoBind(false).OptionLabel("Select Category...").DataTextField("Name").DataValueField("Id").DataSource(dataSource =>
{ dataSource.Read(read => read.Action("GetCategories", "Home")).ServerFiltering(true); }))
</
dd
>
</
dl
>
</
fieldset
>
And just for reference, the "Product" model like so:
public ProductModel()
{
public int Id { get; set; }
public string Type { get; set; }
public int CategoryId { get; set; }
public ICollection<
CategoryModel
> Categories { get; set; }
}
I've added the delete button by using the grid's edit event to add the button dynamically via JavaScript:
function addDeleteButton(e) {
$('<
a
class
=
"k-button k-button-icontext k-grid-delete custom"
href
=
"\\#"
k-icon k-i-delete"></
span
>Delete</
a
>').insertAfter(".k-grid
-update");
$('.k-window-title').text("Edit Categories");
$(".custom").click(function (e) {
e.preventDefault();
var formContainer = $("#popUpForm");
SubmitInfo(formContainer);
});
}
So, when the user selects a category, they have the option to either add or delete a category from the selected "product". However, where "add" is handled by Kendo, I need to handle delete using AJAX.
The delete button is linked to the following JavaScript.
function SubmitInfo(formContainer) {
var grid = $("#persons").data("kendoGrid"),
parameterMap = grid.dataSource.transport.parameterMap;
var data = parameterMap({ sort: grid.dataSource.sort(), filter: grid.dataSource.filter(), group: grid.dataSource.group() });
$.ajax({
url: '@Url.Action("Delete", "Home")',
type: "POST",
dataType: "JSON",
data: data + "&" + formContainer.serialize(),
success: function (result) {
// Clear the input tags
formContainer.find("input[type='text']").each(function (i, element) {
$(this).val('');
});
$('#persons').data('kendoGrid').dataSource.read();
$('#persons').data('kendoGrid').refresh();
}
}
});
}
And the corresponding Controller method like this:
[HttpPost]
public Void Delete([DataSourceRequest] DataSourceRequest request, ProductModel product)
{
var productModel = siteRepository.GetProductById(product.Id);
var categoryToRemove = productModel.Categories.SingleOrDefault(r => r.Id == product.CategoryId);
if (categoryToRemove != null)
{
product.Categories.Remove(categoryToRemove);
siteRepository.UpdateProduct(product);
}
}
This works pretty well at posting back the required Id from the desired Category, but I am unable to persist the Product ID back to the controller required to know from which product to remove the selected category from. This is despite including the relevant @Html.HiddenFor(m => m.Id) in the pop up form.
Would anyone know the best way to persist that piece of data from my pop up form to my controller?