Completed
Last Updated: 12 Oct 2021 09:45 by ADMIN
Tech
Created on: 22 Sep 2021 16:50
Category: Grid
Type: Feature Request
1
Provide a column parameter (similar to OnCellRender) to more easily allow enable and disable of cells in different rows

Our application has, on many pages, complex business logic to enable or disable specific cells based upon the viewing mode, the user's capabilities, the type of data in the row, etc.   If a cell is to be disabled, we also want to change the background color..  This is easily accomplished with the OnCellRender property.

However, we cannot enable/disable specific cells within a column without creating a column template with conditional logic.  And so, in all our grids, EVERY column has to have a template, just for that trivial function.  And now we have business logic smeared across both the razor page and the code page. 

A template should be required only if you are doing something unusual or exceptional.  Setting a cell to be enabled or disabled is completely routine, and one should not have to create a template just for that.

If you would add a property such as OnCellEnable, to override the column Enabled property on a per-cell basis, it would be extremely useful and would eliminate the need for literally hundreds of templates.

Thanks

 


 


6 comments
ADMIN
Nadezhda Tacheva
Posted on: 12 Oct 2021 09:45

Hello,

We are planning some enhancements in the InCell edit mode of the Grid that can help you achieve your desired result via another approach - cancel the OnEdit event for specific cells based on some condition instead of toggling the Editable property of the whole column.

As per the current configuration of the InCell edit mode, the OnEdit event fires once per row and not for every cell. While this introduces less events firing for performance optimization, you are not actually able to cancel the event for specific cell. As of version 2.28.0 of Telerik UI for Blazor OnEdit, OnUpdate and OnCancel will fire for every cell - check this item Trigger OnEdit, OnUpdate, OnCancel on every cell in Incell EditMode.

To achieve your desired scenario, you need to specify the condition based on which the cell will be disabled and to check whether the user is trying to edit that cell, so you can cancel the OnEdit event for it. You can use the Field parameter from the GridCommandEventArgs to check which is the edited field. Currently the Field and Value properties are not populated in the InCell edit as they were marked as obsolete. However, it looks like they can be useful in such cases, so I logged an issue for updating them - Field and Value properties from GridCommandEventArgs are null.

I have added a vote on your behalf to increase the bug popularity as we are prioritizing the bug fixes based on the community interest and demand. You can also subscribe to receive email notifications when its status changes.

Once both of the above listed features are implemented you will be able to disable the desired cells while using the InCell editing of the Grid. Example for cancelling the OnEdit event of the Name column only for the records whose Id is less than 6:

    void OnEditHandler(GridCommandEventArgs args)
    {
        var item = args.Item as SampleData;

        if (item.Id < 6 && args.Field == "Name")
        {
            args.IsCancelled = true;
        }
    }

In case you are not able to wait for the listed enhancements, until they are live, you can proceed with two options:

  • Use Inline or Popup edit mode of the Grid and apply the previously listed approach for toggling the Editable property

  • Use Editor templates

That said, I will now mark this thread as "Completed" since the desired result can be achieved for the Inline and Popup editing with the current Grid configuration and for the InCell edit mode - with the upcoming enhancements.

I hope you will find this information useful. Please let us know if any further questions appear.

Regards,
Nadezhda Tacheva
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Tech
Posted on: 05 Oct 2021 15:19

Sorry, that should have been:

 

For InCell mode, something else is needed; perhaps a grid parameter named OnInCellEdit?

Tech
Posted on: 05 Oct 2021 15:18

Hello Nadezhda,

The approach you describe will work, as you say, for Grid Inline and Popup edit modes.  However, in our application we are using exclusively the InCell edit mode.  The OnEdit cannot be used in that mode.

For InCelledit mode, something else is needed; perhaps a grid parameter named OnInCellEdit?

Thank you!

 

 

ADMIN
Nadezhda Tacheva
Posted on: 01 Oct 2021 15:54

Hello,

Thank you for the confirmation! After further research for your desired scenario, it looks to me that it can be achieved with the current configuration of the Grid component. It will actually track a dynamic change in the Editable parameter, however there are two important points when performing that change:

  • A more suitable place to change the value of the Editable parameter will be in the OnEdit event handler rather than in the OnCellRender event handler. The reason behind this is that OnCellRender event fires when the Grid is rendered and a dynamic change in the Editable parameter will not be reflected in this case. OnEdit, on the other hand, fires when the user is about to enter edit mode for an existing row. So, this is the place where you can prevent editing for some fields based on your desired business logic.

  • Once you set the Editable parameter value to false for the cells you want to disable, you need to change it back to true in case there are other cells in this column after the disabled ones that you want to allow the editing for. Otherwise the field will remain false, and all the rest of the cells will not be editable.

An important point to take into consideration is that the described approach will be applicable for the Grid Inline and Popup edit modes. I have prepared a sample example to better illustrate how to achieve it. The disabled cells are Name for the items whose id is less than 6 and Team for the items whose id is between 6 and 10 inclusively.

<TelerikGrid Data="@MyData"
             Pageable="true"
             EditMode="@GridEditMode.Inline"
             OnEdit="@OnEditHandler">
    <GridColumns>
        <GridColumn Field="@(nameof(SampleData.Id))" Width="120px" />
        <GridColumn Field="@(nameof(SampleData.Name))"
                    Title="Employee Name"
                    Editable="@NameEditable"
                    OnCellRender="@((x) => OnCellRenderHandler(x, "Employee Name"))" />
        <GridColumn Field="@(nameof(SampleData.Team))"
                    Title="Team"
                    Editable="@TeamEditable"
                    OnCellRender="@((x) => OnCellRenderHandler(x, "Team"))" />
        <GridColumn Field="@(nameof(SampleData.HireDate))" Title="Hire date" />
        <GridCommandColumn>
            <GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update
            </GridCommandButton>
            <GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
            <GridCommandButton Command="Delete" Icon="delete">Delete
            </GridCommandButton>
            <GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel
            </GridCommandButton>
        </GridCommandColumn>
    </GridColumns>
</TelerikGrid>

@code {
    public bool NameEditable { get; set; } = true;

    public bool TeamEditable { get; set; } = true;

    void OnEditHandler(GridCommandEventArgs args)
    {
        var item = args.Item as SampleData;

        if (item.Id < 6)
        {
            NameEditable = false;
        }
        else if (item.Id > 5 && item.Id <= 10)
        {
            NameEditable = true;
            TeamEditable = false;
        }
        else
        {
            TeamEditable = true;
            NameEditable = true;
        }
    }

    void OnCellRenderHandler(GridCellRenderEventArgs args, string columnName)
    {
        var item = args.Item as SampleData;

        if ((columnName == "Employee Name" && item.Id < 6) ||
             (columnName == "Team" && item.Id > 5 && item.Id <= 10))
        {
            args.Class = "myCustomCellFormatting";
        }
    }

    public IEnumerable<SampleData> MyData = Enumerable.Range(1, 30).Select(x => new SampleData
    {
        Id = x,
        Name = "name " + x,
        Team = "team " + x % 5,
        HireDate = DateTime.Now.AddDays(-x).Date
    });

    public class SampleData
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Team { get; set; }
        public DateTime HireDate { get; set; }
    }
}

<style>
    .myCustomCellFormatting {
        background-color: red;
        opacity: 0.5;
        color: white;
        font-size: 10px;
        pointer-events: none;
        cursor: none !important;
    }
</style>

Please revise and let me know your thoughts. With some simple additional customizations this approach can save you using EditorTemplate for all columns and you will be able to apply it right away.

Regards,
Nadezhda Tacheva
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tech
Posted on: 29 Sep 2021 19:06

Hello Nadezhda, 

You have correctly summarized the request:  It would be very helpful to easily disable editing in cells on a row-by-row basis, when using in-cell editing. 

I want to emphasize **easily**.   Right now AFAIK this can only be achieved by creating an editor template for the column and putting logic in it to render either static text or an editor control.   For our application, we have to do that on most pages and most columns, which is laborious and error-prone.   The "native" Grid in-cell editing would be fine for 95% of our columns, but instead we have to created an EditorTemplate essentially everywhere.

Here is an illustration of what we want to achieve.  In this illustration, the blue cells may not be edited.  You can see that it varies by row.

 

 

Your suggestion to bind the Editable field to a bool unfortunately will not work for this scenario.  The Editable property applies to the entire column, and you cannot adjust it so it’s different for each row. 

I believe one of the design goals of the Telerik Blazor controls is to make simple things easy to do.  At present this very simple function is not easy.  I am sure many other developers would welcome a column property that, like OnRowRender, allows enable/disable on a row-by-row basis. 

Thanks!

ADMIN
Nadezhda Tacheva
Posted on: 29 Sep 2021 12:46

Hello,

In order to provide a solution that will best match your desired scenario, I want to double check and make sure we are on the same page. As far as I can understand regarding disabling certain cells, apart from visually marking them as disabled by changing their background color, you also want to prevent their editing. Am I missing something or these are the requirements to classify a cell as disabled in your use case?

If so, I am considering a simpler alternative - bind the Editable field of the column to a bool and toggle its value based on the application business logic. This approach will allow you to handle the OnCellRender to not only change the background color of a cell but to also disable its editing using the very same logic.

Currently, the Grid does not listen to a dynamic change in the Editable parameter, however we can open a feature request for that if you consider this option as a good fit for your use case.

Please revise and let me know your thoughts.

Regards,
Nadezhda Tacheva
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.