Grid Column Read-Only setting in Batch Edit Mode

1 Answer 89 Views
Grid
Fred
Top achievements
Rank 2
Iron
Iron
Fred asked on 04 Oct 2024, 07:00 PM

I need to set the GridBound column to read-only when in edit mode but editable when in insert mode (New row added). I've attempted using the Code-Behind "ItemDataBound" event as well as Client-Side "OnBatchEditOpend" event to set the read-only property on the column. Neither attempt work as the column always allows text to be entered. Below are my code snippets:

Thank you in advance for any help you can provide.

Grid Markup:

<telerik:RadAjaxLoadingPanel ID="CatLoadingPanel1" runat="server"></telerik:RadAjaxLoadingPanel>
        <telerik:RadAjaxPanel ID="CatPanel1" runat="server" LoadingPanelID="CatLoadingPanel1">
               <telerik:RadGrid ID="grdCategory" runat="server" AutoGenerateColumns="false" CssClass="Gridheight4" 
                  Width="100%" AllowPaging="true" PageSize="10">
                     <ClientSettings> 
                              <Scrolling AllowScroll="true" UseStaticHeaders="true" />
                              <KeyboardNavigationSettings AllowSubmitOnEnter="true" />  
                              <ClientEvents OnBatchEditGetCellValue="GetCellValue" />
                               <ClientEvents OnBatchEditSetCellValue="SetCellValue" />
                                <ClientEvents OnBatchEditGetEditorValue="GetEditorValue" />
                                <ClientEvents OnBatchEditSetEditorValue="SetEditorValue" />
                                <ClientEvents OnBatchEditOpened="BatchEditOpened" />
                       </ClientSettings>
                      <MasterTableView DataKeyNames="Category" EditMode="Batch" HeaderStyle-Font-Size="8pt" 
                              HeaderStyle-Font-Bold="true" ItemStyle-Font-Size="8pt" PagerStyle-AlwaysVisible="true" 
                               CommandItemDisplay="Top" InsertItemDisplay="Top" BatchEditingSettings-EditType="Cell" 
                                BatchEditingSettings-OpenEditingEvent="Click">
                              <CommandItemSettings ShowSaveChangesButton="true" ShowCancelChangesButton="true" 
                                ShowRefreshButton="true"/>                                
                              <Columns>
                                  <telerik:GridBoundColumn DataField="Category" UniqueName="Category" HeaderText="Category" 
                                   DataType="System.String" ItemStyle-CssClass="maximize" HeaderStyle-Width="250px" ItemStyle- 
                                  Font-Size="8pt">
                                 </telerik:GridBoundColumn>
                                 <telerik:GridTemplateColumn DataField="Is_Active" UniqueName="Is_Active"  HeaderText="Active" 
                                  HeaderStyle-Width="80px">
                                       <ItemTemplate>
                                            <telerik:RadSwitch runat="server" ID="CheckBox1" AutoPostBack="true" Enabled="false" 
                                            CssClass="elasticSwitch" Checked='<%# Eval("Is_Active") %>' OnClientClicking="checkbox1Click"> 
                                           </telerik:RadSwitch>
                                         </ItemTemplate>
                                         <EditItemTemplate>
                                               <telerik:RadSwitch runat="server" ID="CheckBox2" AutoPostBack="false" 
                                                 CssClass="elasticSwitch">
                                                </telerik:RadSwitch>
                                           </EditItemTemplate>
                                    </telerik:GridTemplateColumn>
                          <telerik:GridCheckBoxColumn DataField="CCD_Only" UniqueName="CCD_Only" HeaderText="CCD Only" 
                                 HeaderTooltip="Show for CCD UMs Only.." DataType="System.Boolean">
                            </telerik:GridCheckBoxColumn>
                            <telerik:GridCheckBoxColumn DataField="MMS_Only" UniqueName="MMS_Only" HeaderText="MMS Only" 
                                  HeaderTooltip="Medication Management UMs Only.."  DataType="System.Boolean"> 
                             </telerik:GridCheckBoxColumn>
                             <telerik:GridBoundColumn DataField="Comments" UniqueName="Comments" 
                                     HeaderText="Comments" DataType="System.String"></telerik:GridBoundColumn>
                         </Columns>
              </MasterTableView>
       </telerik:RadGrid>
</telerik:RadAjaxPanel>

Client Script

<script type="text/javascript">
        function GetCellValue(sender, args) {
            if (args.get_columnUniqueName() == "Is_Active") {
                args.set_cancel(true);
                var container = args.get_container();
                var displaySwitch = $telerik.findControl(container, "CheckBox1");
                if (displaySwitch) {
                    args.set_value(displaySwitch.get_checked());
                }
               
            }
        }
        function SetCellValue(sender, args) {
            if (args.get_columnUniqueName() == "Is_Active") {
                args.set_cancel(true);
                var container = args.get_container();
                var displaySwitch = $telerik.findControl(container, "CheckBox1");
                if (displaySwitch) {
                    displaySwitch.set_checked(args.get_value());
                }
            }
        }
        function GetEditorValue(sender, args) {
            if (args.get_columnUniqueName() == "Is_Active") {
                args.set_cancel(true);
                var container = args.get_container();
                var editorSwitch = $telerik.findControl(container, "CheckBox2");
                if (editorSwitch) {
                    args.set_value(editorSwitch.get_checked());
                }
            }
        }
        function SetEditorValue(sender, args) {
            if (args.get_columnUniqueName() == "Is_Active") {
                args.set_cancel(true);
                var container = args.get_container();
                var editorSwitch = $telerik.findControl(container, "CheckBox2");
                if (editorSwitch) {
                    editorSwitch.set_checked(args.get_value());
                }
            }
        }
        function BatchEditOpened(sender, args) {
            var tblView = args.get_tableView();
            var dataIem = tblView.get_dataItems();
            var item = args.get_row().control;
            var index = item.get_itemIndex();
            var colCategory = tblView.getColumnByUniqueName("Category");
            var colelement = colCategory.get_element();
            if (index < 0) {
                colelement.setAttribute("readonly", false);
            }
            else {
                colelement.setAttribute("readonly", true);
            }
        }
        function checkbox1Click(sender, args) {
            args.set_cancel(true);
            var grid = $find("<%= grdCategory.ClientID %>");
            var batchEditingManager = grid.get_batchEditingManager();
            var parentCell = $telerik.$(sender.get_element()).closest("td")[0];
            var initialValue = sender.get_checked();
            batchEditingManager.changeCellValue(parentCell, initialValue);
        }
    </script>

VB Code Behind

Private Sub grdCategory_ItemDataBound(sender As Object, e As GridItemEventArgs) Handles grdCategory.ItemDataBound
        If TypeOf e.Item Is GridEditableItem Then
            If e.Item.IsInEditMode Then
                Dim itemIndex As Integer = e.Item.ItemIndex
                Dim CateGoryColumn As GridColumn = grdCategory.MasterTableView.GetColumn("Category")
                If itemIndex < 0 Then
                    CType(CateGoryColumn, GridEditableColumn).ReadOnly = False
                Else
                    CType(CateGoryColumn, GridEditableColumn).ReadOnly = False
                End If

            End If
        End If

    End Sub

Fred
Top achievements
Rank 2
Iron
Iron
commented on 07 Oct 2024, 06:02 PM

Thank you for your comment, Georgia, 

Do you have an example of how to set the column to read-only using the Client-Side event.  As in the code snippets provided, I've attempted this using the "BatchEditOPened" event.  There doesn't seem to be a Client-Side set read-only method on the grid column. As you can see, I tried on the column element instead.  

1 Answer, 1 is accepted

Sort by
0
Vasko
Telerik team
answered on 09 Oct 2024, 02:26 PM

Hello Fred,

Thank you for the provided code snippet.

Grid columns can be made read-only on the server-side only as this changes how they render - they don't go into edit mode to render editable controls, however, you can cancel the BatchEditOpening event for the  cells in the Category column when in EditMode:

function onBatchEditOpening(sender, args) {
    args.get_tableView().get_dataItems();

    let cell = args.get_cell();
    let columnUniqueName = args.get_columnUniqueName();
    let item = args.get_row().control;
    let itemIndex = item.get_itemIndex();

    if (itemIndex > -1 && columnUniqueName === "Category") { // if itemIndex is -1 it means this is a new row
        args.set_cancel(true);
    }
}

Try this approach and see if that will help you in your case.

Regards,
Vasko
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Telerik family, check out our getting started resources
Fred
Top achievements
Rank 2
Iron
Iron
commented on 09 Oct 2024, 04:21 PM

Thank you for your response, Vasko,

Unfortunately, that didn't work. The "set_cancle" method is undefined for this event argument.  If the server-side events do not fire when going into edit mode, I suppose it's not possible to change the column read-only/enabled state in batch edit mode.

I find it strange that there's a "get_readonly" client-side method on the column but not a "set_readonly" method. Perhaps this is a bug to something that be changed in a new release.

Vasko
Telerik team
commented on 10 Oct 2024, 01:01 PM

Hello Fred

The args.set_cancel(true) argument should work in the onBatchEditOpening event because the batch editing is still in the opening stage (i.e. hasn't opened yet), so then perhaps you misspelled it (referring to "set_cancle"). Nevertheless, you can test that with the below code sample:

<telerik:RadGrid ID="grdCategory" runat="server" AutoGenerateColumns="false" CssClass="Gridheight4" OnNeedDataSource="grdCategory_NeedDataSource"
    OnBatchEditCommand="grdCategory_BatchEditCommand"
    Width="100%" AllowPaging="true" PageSize="10">
    <ClientSettings>
        <Scrolling AllowScroll="true" UseStaticHeaders="true" />
        <KeyboardNavigationSettings AllowSubmitOnEnter="true" />
        <ClientEvents OnBatchEditOpening="onBatchEditOpening" />
    </ClientSettings>
    <MasterTableView DataKeyNames="Category" EditMode="Batch" HeaderStyle-Font-Size="8pt"
        HeaderStyle-Font-Bold="true" ItemStyle-Font-Size="8pt" PagerStyle-AlwaysVisible="true"
        CommandItemDisplay="Top" InsertItemDisplay="Top" BatchEditingSettings-EditType="Cell"
        BatchEditingSettings-OpenEditingEvent="Click">
        <CommandItemSettings ShowSaveChangesButton="true" ShowCancelChangesButton="true"
            ShowRefreshButton="true" />
        <Columns>
            <telerik:GridBoundColumn DataField="Category" UniqueName="Category" HeaderText="Category"
                DataType="System.String" ItemStyle-CssClass="maximize" HeaderStyle-Width="250px" ItemStyle-Font-Size="8pt">
            </telerik:GridBoundColumn>
            <telerik:GridTemplateColumn DataField="Is_Active" UniqueName="Is_Active" HeaderText="Active"
                HeaderStyle-Width="80px">
                <ItemTemplate>
                    <telerik:RadSwitch runat="server" ID="CheckBox1" AutoPostBack="true" Enabled="false"
                        CssClass="elasticSwitch" Checked='<%# Eval("Is_Active") %>'>
                    </telerik:RadSwitch>
                </ItemTemplate>
                <EditItemTemplate>
                    <telerik:RadSwitch runat="server" ID="CheckBox2" AutoPostBack="false"
                        CssClass="elasticSwitch">
                    </telerik:RadSwitch>
                </EditItemTemplate>
            </telerik:GridTemplateColumn>
            <telerik:GridCheckBoxColumn DataField="CCD_Only" UniqueName="CCD_Only" HeaderText="CCD Only"
                HeaderTooltip="Show for CCD UMs Only.." DataType="System.Boolean">
            </telerik:GridCheckBoxColumn>
            <telerik:GridCheckBoxColumn DataField="MMS_Only" UniqueName="MMS_Only" HeaderText="MMS Only"
                HeaderTooltip="Medication Management UMs Only.." DataType="System.Boolean">
            </telerik:GridCheckBoxColumn>
            <telerik:GridBoundColumn DataField="Comments" UniqueName="Comments"
                HeaderText="Comments" DataType="System.String">
            </telerik:GridBoundColumn>
        </Columns>
    </MasterTableView>
</telerik:RadGrid>

function onBatchEditOpening(sender, args) {
    args.get_tableView().get_dataItems();

    let cell = args.get_cell();
    let columnUniqueName = args.get_columnUniqueName();
    let item = args.get_row().control;
    let itemIndex = item.get_itemIndex();

    if (itemIndex > -1 && columnUniqueName === "Category") { // if itemIndex is -1 it means this is a new row
        args.set_cancel(true);
    }
}

protected void grdCategory_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
    // Set the grid's data source to the DataTable with dummy data
    grdCategory.DataSource = GetDummyDataTable();
}

// Method to generate a DataTable with dummy data
private DataTable GetDummyDataTable()
{
    // Create a new DataTable
    DataTable dt = new DataTable();

    // Define columns
    dt.Columns.Add("Category", typeof(string));
    dt.Columns.Add("Is_Active", typeof(bool));
    dt.Columns.Add("CCD_Only", typeof(bool));
    dt.Columns.Add("MMS_Only", typeof(bool));
    dt.Columns.Add("Comments", typeof(string));

    // Add dummy rows
    dt.Rows.Add("Category A", true, false, true, "Initial category for testing");
    dt.Rows.Add("Category B", false, true, false, "Inactive category for review");
    dt.Rows.Add("Category C", true, true, true, "Available for both CCD and MMS");
    dt.Rows.Add("Category D", false, false, true, "Medication Management only");
    dt.Rows.Add("Category E", true, false, false, "General category");
    dt.Rows.Add("Category F", false, true, false, "CCD restricted category");
    dt.Rows.Add("Category G", true, false, true, "MMS specific category");

    // Return the populated DataTable
    return dt;
}

 

As for a set_readOnly() client-side method, as mentioned in my reply, depending on whether the column has the ReadOnly property enabled or not, it will change how its content is rendered, therefore having a client-side method to set the column to ReadOnly is not a bug but the intended way of the Grid rendering logic (remember, the ASP.NET AJAX controls are first rendered on the server, and then on the client).

I hope this information helps you.

Regards,
Vasko
Progress Telerik
Fred
Top achievements
Rank 2
Iron
Iron
commented on 10 Oct 2024, 04:00 PM

Vasko,

please see attached image from my browser's source dev tools.  It shows that the set_cancel() function is not defined.

FYI: my apologies for the misspelling in my last comment. It was spelled correctly in the code.

Vasko
Telerik team
commented on 14 Oct 2024, 09:52 AM

Hi Fred,

Can you confirm the event handler is attached to the OnBatchEditOpening event, rather than the OnBatchEditOpened, because the args.set_cancel(true) will be unavailable in the second one.

I have also attached the sample project where I tested for you to take a look at.

Regards,
Author nickname
Progress Telerik

Fred
Top achievements
Rank 2
Iron
Iron
commented on 15 Oct 2024, 02:37 PM

Yeah, 

That was the problem. That you so much for your time on this. You can consider this as Answered.

 

DOH!

Tags
Grid
Asked by
Fred
Top achievements
Rank 2
Iron
Iron
Answers by
Vasko
Telerik team
Share this question
or