This is a migrated thread and some comments may be shown as answers.

Posting data from a Kendo pop up form back to the controller using AJAX in .Net Core

1 Answer 1400 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Joe
Top achievements
Rank 1
Joe asked on 15 Jan 2019, 04:22 PM

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.

popup

@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.

Error

Would anyone know the best way to persist that piece of data from my pop up form to my controller?

 

1 Answer, 1 is accepted

Sort by
0
Tsvetomir
Telerik team
answered on 18 Jan 2019, 02:37 PM
Hi Joe,

There are two approaches which can be used to send the ProductID parameter to the controller:

1. Use the default delete command of the grid. If you would like upon a button click the built-in delete command to be executed, simply add the "k-grid-delete" class to the button. The Grid uses the jQuery Delegate to wire up the standard Grid commands to any link that contains the following classes:
  • for add record: k-grid-add
  • for delete: k-grid-delete
  • for add record: k-grid-add
  • for edit: k-grid-edit
  • for cancel: k-grid-cancel
  • for batch editing cancel: k-grid-cancel-changes
  • for batch editing save: k-grid-save-changes
2. Since the used edit mode of the grid is different than "InCell", you can obtain the currently edited data item as follows:

var grid =$('#grid').data('kendoGrid');
var model = grid.editable.options.model;

Via the model, access the field of interest. It can be sent to the Controller via the data object in the jQuery.ajax() request. 

As a reference, there is no need to pass the objects are separate query parameters. You can pass an object to the "data" and it will be serialized and sent to the controller.

Try out the suggestions above and let me know in case additional assistance is needed.


Kind regards,
Tsvetomir
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
Grid
Asked by
Joe
Top achievements
Rank 1
Answers by
Tsvetomir
Telerik team
Share this question
or