Responsive KendoUI Grids

Kendo-UIFor those of you who use Telerik's KendoUI grids, you would know that the grids have a heavy focus on javascript. In fact, a large proportion of grid configuration results in client-side changes.

One example of this is the column property for showing/hiding columns. The following code shows a grid that is bound to a ViewModel called ViewModelEntity. This grid has a total of 5 columns - Id, Name, Description, DateField and RelatedItemName. This grid is also bound to a javascript function that runs when data is bound to the grid .Events(e => e.DataBound("onDataBound")). This function is the key to all the magic. If there is anything you want to do in your grid, do it via javascript in this function.

@(Html.Kendo().Grid<ViewModelEntity>()
    .Name("EntityGrid")
    .Columns(columns =>
    {
        columns.Bound(vm => vm.Id)
            .ClientTemplate("<a href='/Controller/Action/Index/#=Id#'>#=Id != null ? Id : '' #</a>");
        columns.Bound(vm => vm.Name);
        columns.Bound(vm => vm.Description);
        columns.Bound(vm => vm.DateField).Format(WebConstants.GLOBAL_DATE_FORMAT);
        columns.Bound(vm => vm.RelatedItemName);
    })
        .Pageable(pageable => pageable
        .Refresh(true)
        .PageSizes(new int[]{10, 25, 50})
        .ButtonCount(10))
        .Sortable()
        .Filterable()
        .ColumnMenu()
        .Events(e => e.DataBound("onDataBound"))
        .Scrollable(s => s.Height("auto"))
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(10)
            .Events(events => events
                .Error("error_handler")
            )
            .Model(model => model.Id(vm => vm.Id))
            .Read(read => read.Action("JSonGetResults", "Controller")
                                .Data("getAdditionalData"))
            )
	)
)

So now let's have a look at the onDataBound function. It's a simple javascript function that gets DOM elements via selectors and manipulates them. I will show you how to extend the selector ability in a later post.

function onDataBound(e) {
        /* fix the bootstrap tooltip issue */
        $("[title]").tooltip({
            container: "body"
        });

	/* set bootstrap button size to small */
        $(".k-button").addClass("btn btn-sm");
	
	/* set responsive classes on table headers */
	$("#EntityGrid th:eq(1)").addClass("hide-768");
	$("#EntityGrid th:eq(2)").addClass("hide-768");
	
	/* hide columns initially */
        var grid = $("#EntityGrid").data("kendoGrid");
        grid.hideColumn(2);
        grid.hideColumn(3);
        grid.hideColumn(4);
}

You can see that the javascript function gets any number of the TH elements and applies a class of hide-768. This class is used as a selector in our media query. See what I mean below.

@media (max-width: 768px) {
  .hide-768 {
    display: none;
  }
}

And there you have it. As the browser is resized, the media query selectors kick in a show/hide columns of your grid. The beauty of this approach is that the user can select which columns they want to show/hide at this screen size. The media query is merely setting the display: none;. And the code is using Kendo functionality, so there should not be any issues when you come to upgrade Kendo.

Til next time...