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?