Telerik blogs

What if you need to let your users edit some data in their grid? You can have whatever level of control you want over what your users enter with Telerik UI for ASP.NET Core.

In a previous post, I looked at all the options the Progress Telerik UI for ASP.NET Core DataGrid gives you for creating the variety of update experiences that users need—and all without writing any code.

But, if you read that post, I suspect that you were already thinking about the special cases where you might want to take more control of the update process than that no-code solution gives you. So, in this post, I’m going to look at some of the places where you can add your own code to take control of the grid’s update user experience.

Getting a Reference to the Grid

The first step in customizing the kendo-grid’s update UX is to get a reference to the grid. The easiest way to do that is, in jQuery’s ready function, to retrieve the grid through the name you assigned it. Once you have that reference, you just need to call the reference’s data function, passing the string "kendoGrid".

So, if your ASP.NET Core Razor Page or View has a grid configured like this:

<kendo-grid name="gridCustomer">
   <datasource …

then you can use the following JavaScript to get a reference to the grid and store it in a variable to be used by other functions in your page (I’ve cleverly given the name “grid” to the variable that will hold the reference to my grid):

<script type="text/javascript">
    let grid;    
    $(
        () => {
            grid = $("#gridCustomer").data("kendoGrid");
        } 
    );

Setting Editability

The only real limitation of the no-code approach for handling updates with the grid is that you have to decide at compile time what update experience the grid will give your users. That can mean having to create multiple pages of, essentially, the same grid because you have different users or scenarios that require different UXes. The most obvious example is where one group of users isn’t allowed to update the data in the grid and the other group is permitted.

If that sounds like something you might face, one of the first things you will want to do is dynamically change the grid’s editing state so that you can switch between read-only and “editable,” based on the logged-in user’s identity (or whatever other criteria make sense to you).

To keep my case study code simple, however, I’m going to demonstrate the necessary code by wrapping it up in a function called enableEditing and calling it from the click event of a button:

<button type="button" onclick="turnonEditing()">Enable Editing</button>

In the most recent version of the grid, you can switch a grid between its read-only and editable states just by calling the grid’s enableEditing and disableEditing functions. Here’s all that’s required in my turnonEditing function to put the grid in an editable state:

    let turnonEditing = () => grid.enableEditing();

If you have an older version of the grid (and don’t want to upgrade) then you can change the editable property by creating a JavaScript object literal that sets the grid’s editable property and then passing that object to the grid’s setOptions function. This version enables editing in older versions of the grid:

    let turnonEditing = () => grid.setOptions({ editable: true });

There’s only one real problem implementing this: The grid looks exactly the same before editing is enabled as after—you might want to update your UI to let your user know that they can make changes.

If you want, you can retrieve the grid’s current editability state through the grid’s getOptions function which, among other values, returns an editable property which is true if the grid is currently in an editable state. This code takes advantage of that to toggle the grid’s editability:

let toggleEditing = () => { 
       if (grid.getOptions().editable) { 
                    grid.disableEditing();
       }
      else
      {
           grid.enableEditing();
     }
};

One warning: You might be tempted to use one of the grid’s data-related events to execute this code. Don’t. Changing editability in either the on-data-binding or on-data-bound events causes the grid to redisplay and rebind, which will cause the on-data-* events to fire again, which will cause your code to re-execute, which will … basically, you’ll be caught in an endless loop (let’s not ask how I know this). Generally speaking, you don’t want to alter anything data-related in the grid during the on-data-* events.

Setting Edit Mode

Once the grid is in an editable state, the grid can be in one of three modes (see my previous post for the differences in the UX):

  • incell
  • inline
  • popup

Here, again, rather than set the mode at compile time, you might want to dynamically switch between these modes at run time depending on the user, the data or some other set of conditions.

You can set the grid’s edibility mode dynamically from code by calling the setOptions function and, in this case, setting the editable property’s mode property. That mode property can be set to one of "incell" (the default), "inline" or " popup".

The mode property and the grid’s editable state are interrelated: setting the mode also enables editing; making the grid editable is equivalent to setting mode to "incell".
Here are three sample JavaScript functions that:

  • Enable editing and set the edit mode to popup
  • Set editing back to the default of incell
  • Disable editing
let enablePopup = () => grid.setOptions({
      editable: { mode: "popup" }
  });
let restoreDefault = () => grid.enableEditing();
let disableEditing = () => grid.disableEditing();

In older versions of the grid, those last two functions would look like this:

let restoreDefault = () => grid.setOptions({
      editable: true
  });
let disableEditing = () => grid.setOptions({
      editable: false
  });

Controlling Adds and Updates to Individual Rows

In addition to controlling the edit mode, you might also want to control the users’ ability to update or delete individual rows.

In the grid’s UI, you generate buttons that the user can click to enable editing or deleting individual rows by adding a column-commandto your grid with its name attribute set to edit or destroy. If you don’t want that column to be displayed initially—effectively preventing the user from updating or deleting individual rows—you can set the column’s hidden attribute to true, as in this example which has both an edit and a delete button:

<columns>
    <column hidden="true">
        <commands>
            <column-command Name="edit" />
            <column-command Name="destroy" />
        </commands>
    </column>
   <column field="CustId" …

To display the column—effectively enabling updates and deletes of individual rows for your user—you can use the grid’s showColumn function, passing the member of the grid’s columns collection that you want to display. Since my command column is the first column in my grid, a function displaying that column would look like this:

    let enableAddsDeletes = () => {
        grid.showColumn(grid.columns[0]);
}

You can also hide the column with the grid’s hideColumn function. If you want to enable updates and deletes separately, just put the edit and delete buttons in separate columns and show/hide them individually.

Managing the Toolbar

In the grid’s UX, adding new rows to the grid is handled through an Add New Record button in the grid’s toolbar. You can control when buttons appear in the toolbar and add your own buttons to the toolbar, also, by using the grid’s toolbar element.

Once you add the grid’s toolbar element, it’s up to you what buttons appear at the top of your grid. The easiest way to add a button is to use the toolbar-button element to add one the grid’s built-in buttons. You specify which of the built-in buttons to add by setting the button’s Name attribute to of the grid’s built-in commands.

This example sets the toolbar-button's Name attribute to "create' to put an “Add new record” button on the toolbar:

<kendo-grid name="gridCustomer">
    <toolbar>
        <toolbar-button Name="create"/>

The Name attribute also sets the data-role attribute on the HTML button that’s generated from this markup—you can use that data-role to get a reference to this button so you can manage it. This code, for example, sets up a variable to hold a reference to my create button, then finds that create button in the jQuery ready function, and (finally) hides the button:

let createButton;
$(
        () => {
                     createButton = $('button[data-role="create"]');
                     createButton.hide();
        }
);

You can also use the toolbar-button element to add your own buttons to the toolbar. You can define your new button’s UI (which doesn’t have to be a button) by nesting a toolbar-command-template inside the toolbar-button.

This example extends the toolbar with a kendo-button displaying the text “Enable Creates” and one of the icons from Telerik’s icon list. The button’s on-click event is set to call a function called showCreate that will reveal the create button:

<kendo-grid name="gridCustomer">
    <toolbar>
        <toolbar-button Name="create"/>

       <toolbar-button> 
            <toolbar-command-template> 
               <kendo-button name="showCreateButton"                                 
                                                icon="thumb-up-outline"
                                                on-click="showCreate"> 
                    Enable Creates
                </kendo-button> 
            </toolbar-command-template> 
      </toolbar-button>

Here’s that showCreate function, leveraging the reference to the create button I created in my previous code example:

let showCreate =  () =>  createButton.show();

This is, obviously, “demo code” (why hide the create button if just clicking another button will display it?). In real life, you’d call the showCreate function as part of checking the user’s permissions (or other conditions) to decide if the user should have access to the create button.

In this post, I’ve deliberately restricted myself to the parts of kendo-grid’s JavaScript API directly related to the grid’s update UX. There’s a reason for that: The grid’s API is huge and I needed to keep this blog post to some (semi-reasonable) length. But there’s a larger point here: If you ever find there’s something you can’t do when declaring your grid, you can probably find something in the grid’s API that will let you do what you want.


Peter Vogel
About the Author

Peter Vogel

Peter Vogel is both the author of the Coding Azure series and the instructor for Coding Azure in the Classroom. Peter’s company provides full-stack development from UX design through object modeling to database design. Peter holds multiple certifications in Azure administration, architecture, development and security and is a Microsoft Certified Trainer.

Related Posts

Comments

Comments are disabled in preview mode.