Wrestling With the Telerik MVC Grid Control (Part 1)

Third party controls can be a great option when building cost-effective client solutions, but there’s always a learning curve that comes with it. It may cost you some significant non-billable time up-front, but will pay dividends down the line.

When I first experimented with Telerik’s MVC Grid control, I thought, “This is so cool! I can just drop this in, and have a really slick UI in minutes!”

When will I learn?

Yes, the Telerik MVC Grid control is very powerful and flexible, but it comes with some significant idiosyncrasies, and requires some workarounds (hacks) for limitations and bugs.

I spent a lot of time over a couple of weeks, implementing an AJAXified master / detail, editable grid. I had to make significant use of search engines, StackOverflow, and the Telerik support forums, often jumping between several articles and form posts at a time to troubleshoot many issues. Unfortunately, the documentation is inconsistent at best, and information is scattered everywhere. I guess that’s all you can expect from a “free” library.

So, I’m writing a detailed article here, in hope that it can be a one-stop resource for others wrestling with similar issues, as well as being a resource I can refer back to for future implementations.

I feel that for the majority of use cases, the best user experience takes advantage of the supported AJAX features of the grid, so my discussion will focus on such an implementation.
Grid

Supporting Pieces

In order to implement any Telerik MVC Grid control, several pieces need to be in place; most of which are typical for an MVC-based solution:

  1. Adding required Telerik references, etc.
  2. Implementing the view, with the grid component, itself.
  3. Implementing several JavaScript functions to handle grid events.
  4. Implementing a View Model to support the page implementing the grid control.
  5. Implementing several controller actions to support the control.

I’ll skip the part on incorporating the Telerik MVC library into your app, since their documentation and videos cover this pretty well. I do want to point out one thing, though. If you’re using a later version of jQuery than Telerik provides and uses out of the box, you’ll need to suppress their loading of it via the ScriptRegistrar command near the bottom of your _Layout.cshtml file:

@(Html.Telerik().ScriptRegistrar().jQuery(false))

Data Binding

The grid component makes use of a fluent syntax for specifying options. Since without data, a grid is useless, we’ll start our focus there.

There are several ways you can tell the grid control how to databind. The method we’re using here is to pass the view model as a generic type to the control, but to not pass any parameters to the main call. Using the view model (or part of it) as a parameter would cause the grid to be bound when the view is loaded (usually via the Index controller action).

By not passing a parameter, and by just specifying the view model as the generic, causes the view to not be pre-loaded, but will instead cause the AJAX binding to load the data after the page initially loads:

@{Html.Telerik().Grid<CustomerViewModel>()
    .Name("Customers")
    .DataKeys(keys => keys
        .Add(c => c.CustomerId)
        .RouteKey("CustomerId"))
    .DataBinding(dataBinding => dataBinding.Ajax()
            .Select("AjaxCustomersHierarchy", "Home")
            .Insert("AjaxAddCustomer", "Home")
            .Update("AjaxSaveCustomer", "Home")
            .Delete("AjaxDeleteCustomer", "Home"))
Note: In the grid code examples that build on each other, I’m using line numbers to retain continuity. If I break into other code, those examples will have line numbers starting at 1.

The Name option is important, as you’ll see later. It assigns an id attribute to the div tag it creates to wrap the grid. Since some hacks are needed to modify the default behavior of the grid, we’ll be making use of this.

Our grid is editable, so we need to add two critical options. One is the DataKeys option, which is where we specify what uniquely identifies a row we’ll be performing a CRUD operation on, above and beyond the required parameters for the route. By specifying CustomerId, this parameter will be passed in any subsequent AJAX call as a querystring value. If we omit this, the controller action would not receive this piece of data.

Important: By default, the grid assumes a DataKey called Id when databinding, even if the lambda expression specifies a different name. If your route expects a different value, you must specify it using the RouteKey sub-option. We’re forcing it to use CustomerId here.

The second critical piece of the puzzle is the DataBinding option. If we were using server-side binding, we wouldn’t require the Select option, since the data would be loaded in the (typically) Index action. But since we’re using AJAX binding, the grid needs to be told how to load the data. Since we have an editable grid, we must also specify the Insert, Update, and Delete options. Quite simply, these specify the action and controller that the Telerik-generated jQuery AJAX calls will use as their URL.

You may be wondering how it knows, for instance, what value(s) to pass in for the editable fields we may change when updating or adding a row. You’ll see when we discuss the detail view (this is the master view), that we would pass in those values as an object in the third parameter. I’ll discuss this in more detail in part 3.

Displaying the Grid

Now that we’ve specified the source of our data, as well as the types of operations we plan on using against that data, it’s time to focus on what to display in our grid. Several types of columns are available to display in the grid, and each are defined via lambda expressions.

Since we’re allowing the user to edit and delete rows, we’ll start out by defining a column dedicated to buttons that will trigger those commands. Although Telerik’s examples show command buttons on the right of each column, most sites and applications seem to show them on the left. We’ll use the Command type option for this first column. Since we’re putting both buttons in the same physical column, we’re specifying multiple statements in the lambda expression; one for the Edit button, and the other for the Delete button.

There are a few display options to choose from. In order to keep the rows lean, we’ve selected to show just the image (since commonly recognized icons are supplied) by using the GridButtonType of Image:

    .Columns(columns =>
    {
        columns.Command(commands =>
        {
            commands.Edit()
                .ButtonType(GridButtonType.Image);
            commands.Delete()
                .ButtonType(GridButtonType.Image);
        }).Width(80);

        columns.Bound(c => c.LastName)
            .ClientTemplate("<#=LastName#>, <#=FirstName#>" + 
                              "<#=MiddleInitial#>")
            .Title("Full Name");
        columns.Bound(c => c.AccountNumber);
    })

Next, we’ll display the actual data. In the master grid, we’re only displaying one column. We use the Bound type option to bind this column to what’s defined in the lambda expression.

As with other web controls you may be used to, we can also define a template (using the Template option) to totally customize the look of the column, injecting specific HTML for formatting the data beyond the default, but we have no need to do that here. What we are using, though, is a ClientTemplate for laying out the full name of the customer. Don’t confuse ClientTemplate with the Template option also provided by Telerik. It’s important to realize that formatting of these columns is done on the client side when using an AJAX-driven grid, so you must use the ClientTemplate option here.

The grid is intelligent enough to format the column titles by creating separate words based on the camel casing of the model property name, but if you want total control, you can specify the Title option, as we’re doing for the Full Name column. But the second column, AccountNumber, will automatically and properly receive the title “Account Number”.

Of course, we’ll also need a way to add new rows. The grid provides us with a Toolbar option, where we can place an Add button. The context of the Edit and Delete buttons are self-explanatory, so we just used icons for those buttons. But I like to make the Add button explicit, since it’s physically separated from the grid body. So we’re going to use the GridButtonType of ImageAndText. I didn’t like the way the button was formatted by default, so I removed the margin using the ImageHtmlAttributes option:

    .ToolBar(commands => commands.Insert()
        .ButtonType(GridButtonType.ImageAndText)
        .ImageHtmlAttributes(new { style = "margin-left:0" }))

Also, since we’re making this a master / detail grid, and the detail will also be editable, it could get a bit confusing if we had two generic Add buttons floating around on toolbars. So we’ll do one further thing to add custom text to our master grid Add button (and we’ll do something similar later for the detail grid). Unfortunately, Telerik doesn’t make this an easy option, so we’ll need to provide a bit of a jQuery hack, which I’ll explain below the code:

$(document).ready(function () {
    $("#Customers .t-grid-add")
        .first()
        .text("Add new Customer")
        .prepend("<span class='t-icon t-add'>");
});

In this forum post on the Telerik site, someone named Aaron provided part of this hack. But if you’re not using the Text GridButtonType (we’re using ImageAndText), this hack wipes out the icon. So I had to tweak the hack a bit. In the jQuery “document ready” block, we need to dynamically force the button text to our custom text.

We do this by locating the element with the first t-grid-add class within the master grid (using the Name we gave the grid – remember, it uses that to create the id and name attributes on the div wrapper tag). Then we overwrite the text. My tweak is what follows – we have to pre-pend the span that defines the Add icon. Yep – this is just about the only way to get this formatted within the grid’s required markup.

Event Hooks

The grid’s default “delete confirmation” dialog is too generic for my taste as well, so there’s yet another hack we need to do. This is a good time to introduce the event hooks the grid provides us with.

We need to specify the ClientEvent option, where we inform the grid of which events to raise, by chaining one or more events to this option:

    .ClientEvents(events => events
        .OnError("onError")
        .OnLoad("onLoadCustomers")
        .OnDataBound("onLoadCustomers")
        .OnEdit("onEditCustomers"))

We need to create an event handler for OnLoad and OnDataBound.

Note: If you don’t create an event handler for each of the events specified in ClientEvents, the grid will fail. You need to at least create an empty handler for each.

Also, since we’re going to want to customize the dialog for both the master and detail grids, we need to create a JavaScript function to accept the deletion target for the message:

function onLoadCustomers(e) {
    replaceDeleteConfirmation(this, "Customer");
}

function replaceDeleteConfirmation(item, itemType) {
    var grid = $(item).data('tGrid');

    $(item).find('.t-grid-delete').click(function (e) {
        grid.localization.deleteConfirmation =
            "Are you sure you want to delete this " +
            itemType + "?";
    });
}

I spent a lot of time in the Chrome inspector to figure this out, and then I found this post that confirmed and improved upon my original attempt. These hacks make for a great learning experience, but I just hope Telerik adds some more elegant hooks in future releases. I’d much rather spend my time on the business problem than the plumbing that libraries like this are supposed to help us avoid. These tools are supposed to help us avoid plumbing, but as we’ve experienced with ASP.NET Web Forms, it helps maybe 90% of the time. Paradoxically, with the other 10%, it often feels like we have to plumb deeper we would’ve, if we had started from the bare metal.

In the replaceDeleteConfirmation function, above, we’re first grabbing a pointer to the grid itself. Since we’re passing the sender to the function from the event handler via “this”, we can easily get a handle to the correct grid. Then we’re creating a click handler for the delete button (via the t-grid-delete class), and changing the deleteConfirmation setting that isn’t currently exposed very well.

Note: Notice that we’re directly using the localization string here, which is not a best practice. It should only really be used for localization purposes. But since we only plan on US clients in the foreseeable future, this is ok. If we didn’t do this though, our hack would have been even “hackier,” as in the prior example for changing the Add button text. We could have done that using the localization string as well, but I wanted to show the pros and cons of each.

Editing

Since this grid will be editable, the next setting we need is the Editable option. I really wanted to use the InLine GridEditMode setting, because I feel that the user experience for editing is a lot cleaner in this type of grid. But there appears to be a bug in the current version of the control (also affecting the InForm mode). In those modes, it appears the “dirty bit” for tracking modified rows is not being reset correctly. So, upon each row save, all the previously modified rows are unnecessarily re-validated and re-saved as well. Therefore, we’ll have to settle with using the PopUp mode instead, which isn’t too bad:

    .Editable(editing =&gt; editing.Mode(GridEditMode.PopUp))

But that leads us to another annoying issue if we’d like to control the title bar of the pop-up. Since there’s no direct way to do this, it requires yet another JavaScript hack. We have to add an OnEdit handler, where we need to locate the pop-up window and change the title based on the edit mode:

function onEditCustomers(e) {
    var popup = $("#" + e.currentTarget.id + "PopUp");
    var popupDataWin = popup.data("tWindow");

    if (e.mode == "insert")
        popupDataWin.title("Add new Customer");
    else
        popupDataWin.title("Edit Customer");
}

Another option would be to completely customize the pop-up using Telerik’s MVC Window control instead, but that’s beyond what we need in this example.

Other Options

Finally, we want to specify the remaining options for the master grid. We’re displaying 15 rows per page, using the PageSize option within the Pageable option. The KeyboardNavigation option allows for keyboard support, which is something I always try to provide in my Web apps. We also want to make this grid sortable and filterable. We can customize this at the column level, but I’ll show that when we discuss the detail grid. Finally, since I don’t want the grid to stretch completely across the page, we pass in a width using the HtmlAttributes option, similar to the way we do this with the MVC Html helpers.

    .Pageable(pagerAction => pagerAction.PageSize(15))
    .KeyboardNavigation()
    .Sortable()
    .Filterable()
    .HtmlAttributes(new { style = "width:50%;" })

If we didn’t have a master / detail pair of grids, we would just need to chain the Render option to the grid definition and be done with it. But we have a lot more to cover in part 2 of this series before we get into the detail grid. We’ll likely get to the detail grid in part 3.

Feedback

I’m not necessarily sure my approach is the “best” solution. There are many ways to handle this, and my experience with the Telerik MVC Grid control is relatively new. So if anyone wants to take me to task on anything, or suggest some other approaches, please comment. Also, if anyone from Telerik reads this, and thinks, “You’re crazy, man — of course there’s a better way to do this!”, please chime in as well.

Similar Posts:

image_pdf

Comments

  1. Atanas Korchev says

    Thanks for sharing your pain :)

    I work for Telerik on the MVC team. You are right that we currently don’t expose API for setting the popup window title, text of the add button or the delete confirmation. Those are all valid points which we will address in a future release!

  2. nax says

    Thank you very much, your hacks are very useful and your article is clear.
    Could you detail the “dirty bit” issue ? I’m not using the popup mode and I’m wondering if I should…

  3. says

    Thanks, Nax. I probably should have explained the “dirty bit” issue more in the post, but it was getting too long…

    I came across this issue accidentally. It’s quite possible that many people wouldn’t have come across it.

    I had server-side validation to ensure that duplicate “customers” weren’t added. The validation code ignored the current record’s id when checking for a pre-existing customer. So the initial update worked fine (if there was no dupe). But then I noticed that on subsequent updates (using the currently edited record’s id), the validation logic was being triggered for the previously updated records — and now that the id value was different, those validation attempts were failing.

    I then looked deeper at the action methods being triggered, and noticed that the prior records were being treated as if they were never already saved. I couldn’t for the life of me pinpoint where the “dirty bit” was maintained on the client side, and was running out of time to research deeper, to possibly update Telerik’s code, so I experimented with the other modes. When I saw PopUp mode didn’t have this issue, I went with it for now.

    I hope I explained this ok. I may need to show specific examples in a future post.

  4. nax says

    Thank you Mark, it’s perfectly clear.
    I didn’t encounter the issue but there is a big difference between your example and my code, I don’t use the generic type. (And Telerik didn’t usually on their demo website).

    I’ll try to use the generic type instead of using the dirty “index” way… I’ll let you know if I reproduce the issue.

  5. says

    Good idea — I only focused on this in the pure AJAXy way. I don’t know if it would make a difference when pre-loading the data, or with server binding. Please let me know how that works for you.

  6. nax says

    I’ve updated my code to use the AJAXy way described in your example, and it works fine, my code is clearer therefore thanks again.

    I didn’t reproduce the issue you mentionned at the end of your article but I’ve probably missed something in your explanation.
    Anyway it should be interesting to have access to your controller implementation to have more detail about it.

  7. Tomas says

    Hi Mark, Nax

    I´m new with mvc3 and Telerik and i want to program a master-details. When do you think you can post the second and third parts. Can you send me the code example about your posts.
    Thank you very much, its a nice post.

  8. says

    Sorry for the delay, Tomas. Part 2 is nearly complete, but it’s taken a back seat to other priorities over the last and next couple of weeks (daughter’s wedding, UG presentation preparation, code camp organization). I guess I should have timed this better.

    Look for part 2 in mid-October, and code examples (above and beyond the posts) shortly after part 3.

  9. Jyri says

    Thanks for sharing this.

    It’s just like you wrote, the info about these things is scattered here and there around the web.

    Will definitely check the upcoming part 2.

  10. Michael says

    Hi everyone,

    I am new to telerik mvc grid and i have some questions, maybe somebody can give me an easy answer. I am trying to implement hierarchy with 3 levels with Telerik mvc grid with ASP.net 4.0 C#
    parent
    —child
    ——grandchild
    binding to datatable or dataset(from stored procedure from sql server)
    I can get first level binding to datatable, but how can i add detail view to child grid? How can I get ID from parent row?

  11. says

    Hi, Michael. This series is meant to explain the scenario you’re looking for (at two levels — but the logic would be similar). The data sources don’t really matter.

    If you can hang on for a bit, I plan on publishing part 2 next week, and part 3 (which will discuss the child grid) soon afterwards. I’ve been behind due to other obligations, but those are done, so I can focus on this series of articles again.

  12. Michael says

    Hi Mark,

    Thanks for your responce. Do you have, by any chance, sample project with hierarchy with code example that I can reference?
    I am really working with MVC few weeks, and one week with Telerik MVC Grid, so everything is really new to me.

  13. says

    Working on part 2 now. Also modifying part 1 to use the sample app, so I don’t expose any proprietary info from the client’s app I built the original example upon.

  14. Rob Paddock says

    Can you provide a download of this tutorial. Really struggling to get my data into the grid from the model.

    Thanks

  15. Brandon says

    Thanks for the great post. Your experiences have been similar to mine. I was able to start using the grid quickly and was really impressed intially. But then as I dug deeper into customizing it, things started to get much trickier than I expected. Looking forward to part 2 (and 3)

  16. Amr says

    Excellent one :)… thx much , i have a small comment on the second code snippet , forgot to give the grid the ViewModel , is that ok??

  17. Arnold Smith says

    Hi Mark,

    Thanks for the work! You’re hitting every point that I hit, and then some. I had been searching for a way to customize the popup title bar.

    -Arnold

  18. Ragini says

    @(Html.Telerik().Grid(new List())
    .Name(“EventsTestGrid”)
    .DataKeys(keys => keys.Add(e => e.IdEvent))
    .Columns(column =>
    { column.Bound(e => e.IdEvent).Title(“Id”).Width(“3em”).Hidden(true);
    column.Bound(e => e.Status).Title(“Event”).Width(“9em”);
    column.Bound(e => e.Date).Title(“Event Date”).Width(“9em”).Format(“{0:dd/MM/yyyy}”);
    column.Bound(e => e.Comment).Title(“Edit”).ClientTemplate(“<img id='Images" + "” + “‘ style=’cursor:hand’ src=’/Content/themes/cynergy/PatientChart/btn_edit_tile.png’ />”).Width(“2em”);
    }) //Details grid binds the intervention
    .DetailView(detailView => detailView.ClientTemplate
    (
    Html.Telerik().Grid(new List())
    .Name(“Intervention_”)
    .DataBinding(dbp => dbp.Ajax()
    .Select(“GetInterventions”, “AccessManagement”, new { EventID = “” })
    )

    .Columns(columns =>
    {
    columns.Bound(o => o.Comment);
    columns.Bound(o => o.IdIntervention).ClientTemplate(“<img id='ChildImages" + "” + “‘ style=’cursor:hand’ src=’/Content/themes/cynergy/PatientChart/btn_edit_tile.png’ />”).Width(“2em”);
    })
    //Details Grid Events and properties set
    .Pageable()
    .ClientEvents(events => events
    .OnLoad(“onLoad”)
    .OnRowDataBound(“onDetailsRowDataBound”)

    )
    // The client detail view template requires a string so we are using the ToHtmlString method
    .ToHtmlString()
    ) )

    //Master Grid Events and properties set
    .ClientEvents(events => events.OnRowDataBound(“onRowDataBound”))
    .Selectable()
    .Pageable(paging => paging.PageSize(4)
    .Style(GridPagerStyles.NextPreviousAndNumeric)
    .Position(GridPagerPosition.Bottom))
    )

  19. Chris says

    Mark, your example notes adding an “onError” ClientEvent but the body of that JavaScript function isn’t included anywhere. Without this being defined I had issues where my grid wouldn’t load the initial data via Ajax. You may want to remove it from the definition or include what you had planned for in that method?

  20. says

    I planned on this being in the final post, with the full code. Got home late from the user group meeting, so let me take a look tomorrow and see if there’s a good place to plug it into this post.

  21. says

    Chris, although there’s not really a good place for the onError handler in this post, I do have this listing in part 2. For convenience sake, here it is:

    function onError(e) {
    e.preventDefault();
    alert(e.XMLHttpRequest.getResponseHeader(“message”));
    }

    I will edit this post to point out that the grid will fail if you haven’t created all the event handlers defined in the grid.

  22. Chris says

    Thanks again Mark.
    The more I think about it, this will be a non-issue once all 3 parts are up as people will most likely go through all 3 before trying to run the project. I’m only running into issues because I’m totally new to this, so having each “part” work, is the only way for me to measure progress/success! :)

  23. Atanas Korchev says

    This is Atanas from the Telerik team again.

    RE: “dirty bit”

    What do you mean by dirty bit issue? I couldn’t understand based on your description what you mean. Could you please elaborate? Can you reproduce it in our online demos http://demos.telerik.com/aspnet-mvc/grid/editingajax ?

    On a side note quite a lot of our customers are using the in-line and in-cell editing modes. This baffles me even more because such a blocking issue would have been spotted long ago.

  24. says

    Hi Atanas. “Dirty bit” is a term that was used often (at least in my early days in software, a couple of decades ago), which refers to a boolean flag used for indicating if something has not yet been processed (saved, etc.). It gets reset upon save, for instance.

    Someone else asked me to elaborate the issue in an earlier comment. I’ll re-post my attempted explanation here. I hope it helps:

    I came across this issue accidentally. It’s quite possible that many people wouldn’t have come across it.

    I had server-side validation to ensure that duplicate “customers” weren’t added. The validation code ignored the current record’s id when checking for a pre-existing customer. So the initial update worked fine (if there was no dupe). But then I noticed that on subsequent updates (using the currently edited record’s id), the validation logic was being triggered for the previously updated records — and now that the id value was different, those validation attempts were failing.

    I then looked deeper at the action methods being triggered, and noticed that the prior records were being treated as if they were never already saved. I couldn’t for the life of me pinpoint where the “dirty bit” was maintained on the client side, and was running out of time to research deeper, to possibly update Telerik’s code, so I experimented with the other modes. When I saw PopUp mode didn’t have this issue, I went with it for now.

    I’ll try to reproduce it, and send a sample.

  25. Atanas Korchev says

    I guess I know what “dirty bit” means in general ;)

    The behavior which you are describing is very odd indeed. Which editing mode did you use before switching to Popup? We are tracking “dirty” state only for “InCell” editing mode. Every other editing mode sends the changes made by the user immediately when the “update” button is pressed. The editing works like this (except in InCell mode):
    1) The user presses the edit button and enters edit mode (popup, inline or inform)
    2) The grid creates a form and displays various editing controls
    3) The user changes some values and clicks the “Update” button
    4) The grid submits the form to the action method specified in the DataBinding configuration
    5) The action method updates the database and returns the updated records (the current page of updated records to be more precise)
    6) The grid binds to the returned records

    I hope this sheds some light on how the grid editing works.

  26. says

    Hi Atanas,

    Sorry for my delayed response. Been overwhelmed at work this week, and every time I start something, I get interrupted. I hope to get to this shortly, and provide you with some answers.

    I’m also looking forward to trying out Kendo UI — are you doing work on that as well? I downloaded it, but haven’t had a chance to look at it yet.

    Thanks.

  27. Trupti says

    Hi Mark,

    Excellent work..
    I am working on having multi select option in Telerik Grid column.
    I want to refer my grid column in jquery to enable multiselect on that column. But I am not able to figure out a way to do so. ( I have enabled multi select on a html column earlier, but not with telerik grid column)

    My Grid code is some what like :
    <%= Html.Telerik().Grid()
    .Name(“TESTGrid”)
    .Sortable(sorting => sorting.OrderBy(sortOrder => sortOrder.Add(o => o.TESTDATE)))
    .Pageable(paging =>
    paging.PageSize(10)
    .Style(GridPagerStyles.NextPreviousAndNumeric)
    .Position(GridPagerPosition.Bottom)
    .Total((int)ViewData["total"])
    ).Filterable()
    .Groupable()
    .Selectable()
    .Resizable(c => c.Columns(true))
    .DataKeys(dataKeys => dataKeys.Add(c => c.Id))
    .ToolBar(commands =>
    {
    commands.Custom().Text(“Add a new Test”).ButtonType(GridButtonType.ImageAndText).HtmlAttributes(new { @class = “add-test”, onclick = “$(‘#TESTGrid’).data(‘tGrid’).addRow(); $(‘#test-created-at’).text(”); return false;” });
    commands.Custom().Text(“Edit Selected”).ButtonType(GridButtonType.ImageAndText).HtmlAttributes(new { @class = “edit-selected”, onclick = “editSelected(event)” });
    commands.Custom().Text(“Delete Selected”).ButtonType(GridButtonType.ImageAndText).HtmlAttributes(new { @class = “delete-selected”, onclick = “deleteSelected(event)” });
    .DataBinding(dataBinding => dataBinding.
    Ajax()
    .Select(“_ClientEditTemplate”, “TEST”)
    .Update(“_ClientUpdate”, “TEST”)
    .Insert(“_ClientInsert”, “TEST”)
    .Delete(“_ClientDelete”, “TEST”))
    .EnableCustomBinding(true)
    .Localizable(“de-DE”)
    .Columns(columns =>
    {
    //Bound columns
    columns.Bound(c => c.Completed).Width(85).ClientTemplate(“<input id='Completed' name='Completed' type='Checkbox' disabled='true' >”);
    columns.Bound(c => c.Description).Width(300).Groupable(false);
    columns.Bound(c => c.TESTUSER).Width(200).ClientTemplate(“”).Filterable(false);
    columns.Bound(c => c.TESTDATE).Width(225).Format(“{0:MM/dd/yyyy h:mm tt}”);
    //Command column with two commands
    columns.Command(commands => { commands.Edit(); commands.Delete(); }).Width(1).Visible(true);
    })
    .ClientEvents(events => events.OnDataBound(“onDataBound”))
    %>

    My Jquery code will some what be like this:
    function onDataBound() {
    var grid = $(this).data(‘tGrid’);

    // some how refer the telrik grid column “TESTUSER here in User”

    var sel = $(“#User”).multiselect({
    header: false,
    noneSelectedText: “Please select users”,
    click: function (event, ui) {
    var users = $(“#User”).multiselect(“getChecked”).map(function () {
    return this.value;
    }).get();
    }

    });

    $.ajax({
    type: “POST”,
    async: true,
    url: “/TESTCONTROLLER/GetUsers/” + project.currentId,
    contentType: “application/json; charset=utf-8″,
    dataType: “json”,
    success: function (response) {
    list = response;
    if (list.length > 0) {
    $.each(list, function (i, v) {
    var opt = $(”, { value: list[i].Id, text: list[i].Name, selected: “selected” });
    opt.appendTo(sel);
    });
    sel.multiselect(‘refresh’);
    }
    else
    sel.multiselect(‘disable’);
    },
    error: function () {
    project.notice(“An error occurred while setting up multiselect users, please try again.”);
    sel.multiselect(‘disable’);
    }
    });
    }

    Please advice as early as possible… I am stuck with this since last 2 days..:(

  28. says

    Trupti, I believe one of the things you may be struggling with is that there appears to be no easy way to reference columns within the onDataBound event (onRowDataBound, yes, but not onDataBound).

    I’m assuming at this point you’re looking at the checked items with the checked state that existed for each row before being displayed in the grid. You can perhaps try a couple of different ways:

    1) You can use the onRowDataBound event to interrogate the column of each row as this event is hit, through the e.row argument parameter, and build an array of selected rows. Or…

    2) You may need to give all the items in that column a class that you can reference with jQuery, and then can use the onDataBound event, traversing the wrapped set using the “checked” attribute.

    I don’t have time right now to experiment, myself. Maybe this article can point you in a better direction: http://blog.cdeutsch.com/2011/02/preserve-telerik-mvc-grid-checkboxes.html. He’s not doing quite what you’re trying to do, but he is referencing checked items.

    Good luck.

  29. vinny says

    hi mark,
    Nice article.
    Due to being new to mvc(maily mvc3) and telerik grid(built for razor) m gettimg some problem in rebinding my grid.
    1) My requirements is that “On select of any item (or onchange event of a dropdownlist)in a dropdownlist i want to repopulate grid with different datasource”

    for eg;
    i have a dropdown containing to values product1 and product 2
    for first time load i am keeping dropdowns value as product1 and populated grid with dtProduct1 datasource(could be datatable or anything)

    now if i change dropdown to product2 to then i want to perform some action(either client or server side) to get required data in dtProduct2 datasource and want to bind this new datasource to grid.

    How can it be done in MVC3 razor for telerik grid?
    Please let me as soon as possible.

    Thanks for your precious time.

    Vinny….Yo! :)

  30. vinny says

    Dear Mark,

    Thanks a tonnnn!!!

    It took me hardly 2 hrs to complete my required objective with your help which i was searching for more than 2 days.

    Keep up the good work

    Thanks again!!

    yo! :)

  31. Trupti says

    Hi Mark,

    Could not get the multiselect implemented in telerik grid , had to take a different approach but thanks for the directions.

    I have another question :

    want to limit the number columns to be dragged and dropped to group the grid data by those columns.

    “Drag a column header and drop it here to group by that column”

    Limit these to max of say 8.

    How can i do this?

  32. says

    Trupti,

    You would think they’d have an event hook, like they do for onColumnReorder and OnColumnResize, but they don’t. So some hacky JS way may be necessary.

    Unfortunately, I’m in the middle of a big move right now, and won’t be able to experiment until sometime in August.

  33. Shalini says

    Hi Mark,

    Pls. give me some suggestion to resolve my issue.

    I need to perform telerik grid edit. I am able to do when edit button placed in the grid row.

    But my requirement is, the edit button should be placed outside the grid. It is an individual button. When im clicking that button it should pop up with the grid selected row data.

    I am really struggling to get the selected row data in the pop up.

    Please help me in resolving this issue.

    Thanks.

  34. Stuart says

    Just wanted to add my appreciation to you for sharing this information. I’ve been going though the same process of going from hmm, not bad but no cigar yet – to what you managed to acheive here. Its going to save me days of scouring and scratching my head. Many thanks.

  35. says

    Hi Mark,

    Thanks for the very useful page.

    Now that Telerik has started redirecting all of the Google results for telerik MVC Extensions to their Kendo promotion page, it is one of very few good examples and references. Probably not looking at Kendo for that exact reason. I like being supported on projects that are less than 2 years old. :)

    Thanks again for digging in, and for organizing the results into a useful post and example.

  36. says

    No problem. I have already started using Kendo UI, and the main problem I have with that is their documentation. A lot of info, poor organization, and it takes searching in a half dozen different places to really find an answer or a hint. But I heard they’ve hired someone full-time to update the docs. We’ll see how that goes. They’ve been frustrating at times.

    Turns out, I actually stopped using the Telerik MVC Extensions shortly after writing these posts, for a variety of reasons outside of the library itself.

Leave a Reply

Your email address will not be published. Required fields are marked *