Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send an object to the Telerik MVC Grid Ajax Select() Controller Method

I am using the Telerik MVC Grid with Ajax binding, and am having a problem passing an object to the controller to be used to filter data. I am able to pass simple data (string, int), but not a more complex object.

For instance, I can to this no problem:

.DataBinding(dataBinding => dataBinding.Ajax().Select("_CasesAjaxBinding", "Home", new {orderId = "12345"} ))

And then in my controller, handle the orderId like this:

public ActionResult _CasesAjaxBinding(string orderId)

The problem I am having is when I try to pass a more complex object (in this case the @Model) to the controller, like this (The @Model is type CaseFilterModel):

.DataBinding(dataBinding => dataBinding.Ajax().Select("_CasesAjaxBinding", "Home", new {filterSpec = @Model} ))

And then trying to handle the object, like this:

public ActionResult _CasesAjaxBinding(CaseFilterModel filterSpec)

The filterSpec parameter is always null.

Thanks in advance for any ideas!

like image 471
MattW Avatar asked Sep 15 '11 15:09

MattW


People also ask

How do you pass a grid's selected row value to the controller?

You can use the select() method of the Grid to get the selected rows, and the dataItem() of the Grid to get the corresponding JavaScript model which can give you all the information you might need, then with an Ajax request you can send the whole objects or just the IDs to the action method.

What is Kendo grid in MVC?

Kendo UI Grid is an easy, more maintainable, and powerful control for displaying data in a tabular format. Kendo provides many options, such as paging, sorting, filtering, grouping, and editing. These features determine the way data is presented and manipulated.


2 Answers

As far as I can find on the Telerik forums this cannot be done this way. There was a similar question on there, which described exactly the same problem. When passing the model it was always null in the controller's action method.

However there is a workaround if you want to pass multiple parameters to the select method in order to filter the data, but it requires some client side coding.

I'll include a summary of that work around here, so that the answer is complete. A solemn link doesn't say much.

Assume we have a grid which displays orders items (articles) from all the orders. First make sure to hook up the client side onDataBinding event:

<%= Html.Telerik().Grid<Order>()
        .Name("Grid")
        .ClientEvents(events => events.OnDataBinding("onDataBinding"))
        .DataBinding(dataBinding => dataBinding.Ajax()
                                               .Select("_AjaxBinding", "Grid"))
%>

In the client side event handler you need to compose your select URL. Here I'll pass two parameters, an order id (int) and a description of an article (string).

<script type="text/javascript">

    function onDataBinding(e) {
        var orderId = 100;
        var searchText = "test";
        var params = { OrderId: orderId, ArticleDescription: searchText };
        var paramsStr = $.param(params);
        var selectUrl = "<%= @Url.Action("_AjaxFilterBinding", "Grid") %>" 
            + "?" + paramsStr;
        var grid = $('#Grid').data('tGrid');
        grid.ajax.selectUrl = selectUrl;
    } 

</script>

Then in your controller you can declare the select method as follows:

[GridAction]
public ActionResult _AjaxFilterBinding(AjaxFilterBindingModel model)
{
    // Retrieve data here and filter it based upon the data present in the model.
    var data = ...;

    return View(new GridModel<Order> { Data = data });
}

The model looks like:

public class AjaxFilterBindingModel
{
    public int OrderId { get; set; }
    public string ArticleDescription { get; set; }
}

Passing a collection via the URL (GET) is also possible. Let's assume you want a collection of order IDs instead of just one.

The model would look like this:

public class AjaxFilterBindingModel
{
    public IEnumerable<int> OrderIds { get; set; }
    public string ArticleDescription { get; set; }
}

And the JavaScript would look like this:

    function onDataBinding(e) {
        jQuery.ajaxSettings.traditional = true;
        var intArray = [1, 2, 3, 4, 5];
        var params = {  OrderIds: intArray, ArticleDescription: "Test" };
        var paramsStr = $.param(params);
        var selectUrl = "<%= @Url.Action("_AjaxFilterBinding", "Home") %>" + "?" 
            + paramsStr;
        var grid = $('#Grid').data('tGrid');
        grid.ajax.selectUrl = selectUrl;
    }

Remark: Don't forget to set "jQuery.ajaxSettings.traditional = true;" or the parameters will be serialized incorrectly and the ASP.NET MVC model binder will not be able to bind the integer array.

And to be complete here is the Telerik forum thread I mentioned:

http://www.telerik.com/community/forums/aspnet-mvc/grid/getting-the-model-object-in-a-custom-binding-grid-ajax-controller.aspx

And the suggested work around:

http://www.telerik.com/community/forums/aspnet-mvc/grid/code-sample-sending-additional-filters-with-ajax-binding.aspx

like image 130
Christophe Geers Avatar answered Oct 03 '22 23:10

Christophe Geers


Also as a note, this solution is not in Razor syntax... took me forever to spot it but the line

var selectUrl = "<%= @Url.Action("_AjaxFilterBinding", "Home") %>" + "?" + paramsStr;

should be changed to
var selectUrl = "@Url.Action("_AjaxFilterBinding", "Home")" + "?" + paramsStr;

For Razor... I copied the code but couldn't figure out why my _AjaxFilterBinding was not being called. Just thought I'd point it out in case anyone else has this problem.

Thanks for the solution, it NOW works great :)

like image 34
superservo15 Avatar answered Oct 03 '22 21:10

superservo15