Kendo Grid Datasource and passing read parameters

Kendo Grid Ajax Data source

The kendo grid can be configured so that it will pull its data from the server with an Ajax call rather than using view data at server page build time.
Its easily done by using the grids DataSource and a controller action for its Read operation.

Example:

    @(Html.Kendo().Grid<MyDataViewModel>()
        .Name("Grid")
        .Columns(columns => {
            columns.Bound(p => p.Id).Hidden(true);
            columns.Bound(p => p.Name);
            columns.Bound(p => p.Description);
            columns.Bound(p => p.blah1);
            columns.Bound(p => p.blah2);
        })
        .Sortable()
        .Filterable()
        .DataSource(dataSource => dataSource
            .Ajax()
            .Read( read => read.Action("myactionRead","mycontroller"))
            .ServerOperation(false)
        )
    )

In the controller (mycontroller in example) you need to handle the action with something like

public ActionResult myactionRead([DataSourceRequest]DataSourceRequest request) {  
  return Json( myservice.GetData().ToDataSourceResult(request));
}

The request parameters contains all the filtering, sorting, paging details from the grid.
The myservice.getdata just returns a list of the mydataviewmodel that the grid is looking for.
The .ToDataSourceResult(request) part takes your data and performs the paging, sort, filtering the grid is looking for.
Improtant to note that its best to past an Iqueryable to this as that will allow the filtering etc. to be applied at the time of data gathering and minimise data passed around. See section for more details.

The filtering etc. can be applied server or client side.
.ServerOperation(false) To pull all data and do the grid filter etc. client side. Only valid if small data set.
.ServerOperation(true) To only pull down the filtered data for display. Used for large data sets. It does incur a server call each user operation.


Kendo Grid Ajax Data Source with Parameters

You have a data grid that is being populated by the Ajax read in its datasource.
This read gets passed all the sorting/filtering details on the grid but say you have additional parameters that are out with the grid normal operation. In this case you want to pass additional parameters.
For example: Say you only want data from a specific customer thus need to pass the customer id to the data read or another drop down list elsewhere on the page needs to limit the grid data.

Its easy to do.
Build the Kendo grid as normal but with the DataSource modified to

.DataSource(dataSource => dataSource
  .Ajax()
  .Read(read => {
    read.Action("myaction_read", "Register").Data("filterdata");
})

The addition of .Data specifies that the javascript function filterdata will provide details.
So need to add javascript as such.

function filterdata() {  
  return {
    CustomerId: 5
  };
}

Note: its hard coded to return id of 5 but you can put whatever is required

Alternatively if it’s a fixed value or can be set at server page build time then

    .Data("{ CustomerId: 5}"))
or  
    .Data("{ CustomerId: "+@Model.CustId+"}"))

In the controller add the extra parameter information like the following

public ActionResult myaction_read([DataSourceRequest]DataSourceRequest request  
            ,  int CustomerId) {
    return Json( myservice.GetData(CustomerId).ToDataSourceResult(request));
}

The parameter is specified and you must make the name given in the javascript code exactly.

If more parameters are required then just add them as required.

return {  
    CustomerId: 5 ,
    projId: 10
};

The parameter in the controller can be a class instead when dealing with multiple parameters.

public ActionResult myaction_read([DataSourceRequest]DataSourceRequest request  
            ,  int CustomerId, int projId ) 

Can be

public ActionResult myaction_read([DataSourceRequest]DataSourceRequest request  
            ,  CustProj mymodel) {
    int cid = Mymodel.CustomerId;
    int pid = Mymodel.projId;

The properties must match the javascript names exactly again.


Kendo Grid Controlled by Kendo Combo

We have a Kendo grid and its datasource is required to be filtered by a Kendo combo box elsewhere on the page.
To achieve this we want to use the same data source with parameters as covered done before but modified that the javascript pulls it data from the combo

First the combo box:

<script>  
function OnChange(e) {  
    $('#Grid').data('kendoGrid').dataSource.read();
};
</script>  
<p>Select Customer:</p>  
@(Html.Kendo().ComboBox()
          .Name("customercombo")
          .DataTextField("Title")
          .DataValueField("CustomerId")
          .Placeholder("Select Customer")
          .HtmlAttributes(new { style = "width:250px" })
          .Filter("contains")
          .AutoBind(false)
          .MinLength(3)
          .BindTo(Model.SomeDataViewModel)
          .Events(e => e.Change("OnChange"))
)

The combo doesn’t have anything other than normal Kendo stuff. The value is bound to the customerId that we want to use in the grid parameter.
The on change event is specified (Used rather than onselect as it triggers even if the user selects the existing selection)
The javascript for the onchange refreshes the grid forcing it to go fetch its data then redraw itself

The grid:
It remains the same but we change the filterdata function to

function filterdata() {  
  return {
    CustomerId: $("#customercombo").val() === "" ? 0 : $("#customercombo").val()
  };
}

This sets the customer id to the currently selected value of the combo. The check with "" is there for when the users enters the page and nothing is selected. It returns 0 which is assumed will return no data. Change as required.

The grid read needs to be modified to use the filter data.

.DataSource(dataSource => dataSource
    .Ajax()
    .Read(read => {
        read.Action("myaction_read", "Register").Data("filterdata");
})

The controller will need modified as shown in other example.


Above referring to version
Telerik Kendo UI Professional Q1 2015
Telerik UI for ASP.NET MVC Q1 2015


comments powered by Disqus