Client Event OnBatchEditOpened bug?

2 posts, 0 answers
  1. Cider
    Cider avatar
    1 posts
    Member since:
    Nov 2019

    Posted 12 Nov 2019 Link to this post

    A client wanted text selected by default when entering edit mode, so I did some research and applied the solution noted below.

    Using RadGrid with VB.NET, Batch Edit Mode with GridTemplateColumns. 

    When clicking a cell that has a RadComboBox, the BatchEditOpened function doesn't return the correct reference to the control when clicking a cell on the same row that is INPUT only.

    Here is a link to a sample App that replicates the pattern described:
    https://1drv.ms/u/s!AtPkHVExQn29bhZgXpAMSX2LKgQ

    All you need to do is add the latest Telerik DLLs to the project and it should compile.  Excluded them from the ZIP file at the above link.

     

    The real page is wired up to a SQL Server database, but I was able to use the XML Data Source from the Sample Applications to replicate the issue.

     

    Here is the page design:

    <telerik:RadCodeBlock runat="server">
        <script type="text/javascript">
     
            function BatchEditOpened(sender, args) {
                var batchManager = sender.get_batchEditingManager();
                var theCell = batchManager._getDataControl(args.get_row(), args.get_columnUniqueName());
     
                if (theCell.tagName == "INPUT") {
                    setTimeout(function () {
                        theCell.select();
                    }, 30)
                }
            }
     
        </script>
    </telerik:RadCodeBlock>
     
    <telerik:RadGrid RenderMode="Lightweight" ID="RadGrid2" runat="server" ShowStatusBar="true" OnNeedDataSource="RadGrid2_NeedDataSource"
        OnInsertCommand="RadGrid2_InsertCommand" OnUpdateCommand="RadGrid2_UpdateCommand"
        OnDeleteCommand="RadGrid2_DeleteCommand">
     
        <MasterTableView AutoGenerateColumns="false" DataKeyNames="CustomerID" EditMode="Batch" CommandItemDisplay="Top">
            <Columns>
     
                <telerik:GridTemplateColumn HeaderStyle-Width="50px" AllowSorting="true" SortExpression="CustomerID" ItemStyle-BorderColor="Black" ItemStyle-BorderStyle="Solid" ItemStyle-BorderWidth="0.5px" HeaderText="L3" UniqueName="L3" ItemStyle-CssClass="rgRightItem" HeaderStyle-CssClass="rgCenterHeader">
                    <ItemTemplate>
                        <asp:Label runat="server" ID="lblCustomerId" Text='<%# Eval("CustomerID") %>'></asp:Label>
                    </ItemTemplate>
                    <EditItemTemplate>
                        <asp:TextBox runat="server" ID="txtCustomerId" Text='<%# Eval("CustomerID") %>'></asp:TextBox>
                    </EditItemTemplate>
                </telerik:GridTemplateColumn>
     
                <telerik:GridTemplateColumn HeaderStyle-Width="175px" AllowSorting="true" SortExpression="ContactName" HeaderText="Contact Name Header" UniqueName="ContactName" SortedBackColor="LemonChiffon" ItemStyle-CssClass="rgLeftItem" HeaderStyle-CssClass="rgLeftHeader">
                    <ItemTemplate>
                        <asp:Label runat="server" ID="lblContactName" Text='<%# Eval("ContactName") %>'></asp:Label>
                         
                    </ItemTemplate>
                    <EditItemTemplate>
                        <telerik:RadComboBox runat="server" ID="editContactName" EnableLoadOnDemand="True" DataTextField="ContactName"
                            OnItemsRequested="editContactName_ItemsRequested" DataValueField="ID"
                            HighlightTemplatedItems="true" Height="140px" DropDownAutoWidth="Enabled" Sort="Ascending">
                        </telerik:RadComboBox>
                    </EditItemTemplate>
                </telerik:GridTemplateColumn>
     
     
            </Columns>
        </MasterTableView>
        <ClientSettings>
            <ClientEvents OnBatchEditOpened="BatchEditOpened" />
        </ClientSettings>
    </telerik:RadGrid>

     

    Here is the code behind:

    Imports System
     
    Imports Telerik.Web.UI
    Imports System.Collections
     
    Public Class test1
        Inherits System.Web.UI.Page
     
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
     
        End Sub
     
        Private Const FILE_PATH As String = "~/App_Data/Xml/XmlDataSourceExampleTemp.xml"
     
        Protected Sub RadGrid2_NeedDataSource(sender As Object, e As GridNeedDataSourceEventArgs)
     
            Dim sourceDocument = LoadDocument(FILE_PATH)
            Dim customers = GetCustomersEnumeration(sourceDocument, "Customers", "Customer")
            Dim gridSource = From customer In customers
                             Select New With {.CustomerID = customer.Attribute("CustomerID").Value, .ContactName = customer.Attribute("ContactName").Value, .CompanyName = customer.Attribute("CompanyName").Value}
            CType(sender, RadGrid).DataSource = gridSource
     
        End Sub
     
        Private Function LoadDocument(path As String) As XDocument
     
            Dim sourceDocument As XDocument = XDocument.Load(Me.Server.MapPath(path))
            Return sourceDocument
     
        End Function
     
        Private Function GetCustomersEnumeration(sourceDocument As XDocument, rootNode As XName, childNode As XName) As IEnumerable(Of XElement)
     
            Dim customers = sourceDocument.Element(rootNode).Elements(childNode)
            Return customers
     
        End Function
     
        Protected Sub RadGrid2_UpdateCommand(source As Object, e As GridCommandEventArgs)
     
        End Sub
     
        Protected Sub RadGrid2_InsertCommand(source As Object, e As GridCommandEventArgs)
     
        End Sub
     
        Protected Sub RadGrid2_DeleteCommand(source As Object, e As GridCommandEventArgs)
     
        End Sub
     
        Protected Sub editContactName_ItemsRequested(ByVal sender As Object, ByVal e As Telerik.Web.UI.RadComboBoxItemsRequestedEventArgs)
            Dim combo As RadComboBox = TryCast(sender, RadComboBox)
            combo.Items.Add(New RadComboBoxItem("Alfreds Futterkiste", "0"))
            combo.Items.Add(New RadComboBoxItem("Antonio Moreno Taqueria", "1"))
            combo.Items.Add(New RadComboBoxItem("Around the Horn", "2"))
        End Sub
     
     
    End Class
  2. Attila Antal
    Admin
    Attila Antal avatar
    440 posts

    Posted 15 Nov 2019 Link to this post

    Hi Cider, 

    Thank you for the sample project. It helped me spot the problem quickly and I can confirm this is not a bug.

    The Telerik function "_getDataControl" is designed to find and return Telerik controls.

    When this function is used, it will loop through the child elements of the HTML element passed to it. The function will look for Telerik Objects and return the Object as soon it found it. Since the only Telerik object in the row elements you passed to it is the RadComboBox, it will return this every time. See the yellow marking in the code below:

    _getDataControl: function (editorControlsContainer)
    {
    	var children = editorControlsContainer.getElementsByTagName("*");
    	var inputs = editorControlsContainer.getElementsByTagName("input");
    	var control;
    
    	for (var i = 0; i < children.length; i++)
    	{
    		control = $find(children[i].id);
    		if (control)
    		{
    			return control;
    		}
    	}
    			
    	if (inputs.length > 0)
    	{
    		return inputs[0];
    	}
    
    	return editorControlsContainer.children[0] ? editorControlsContainer.children[0] : editorControlsContainer;
    }

     

    If you want the function return you a control in every cell you will need to use a RadTextBox instead of the ASP TextBox:

    <%--<asp:TextBox runat="server" ID="txtCustomerId" Text='<%# Eval("CustomerID") %>'></asp:TextBox>--%>
    <telerik:RadTextBox ID="txtCustomerId" runat="server" Text='<%# Eval("CustomerID") %>'>
    </telerik:RadTextBox>

     

    However, by replacing the TextBox will only allow you to find it using this method, but if the HTML element you pass to it has more than one Telerik Control, always the first one will be returned. With that said, if you are trying to access the second control when in second cell, the first control will be returned.

    In your case, I believe you want to access the control for the current cell for which the BatchEditOpened event is fired. If that is the case, try passing only the cell element (TD) instead of passing the entire row.

    batchManager._getDataControl(args.get_cell());

     

    Here is the final JavaScript code that you can try:

    <script type="text/javascript">
        function BatchEditOpened(sender, args) {
            var batchManager = sender.get_batchEditingManager();
    
            // telerik controls are JavaScript Objects
            var TelerikControl = batchManager._getDataControl(args.get_cell());
    
            // The following logic is working with HTML elements
            // Get the HTML of the Telerik object
    
            var telerikControlHtmlElement = TelerikControl.get_element();
    
            if (telerikControlHtmlElement.tagName == "INPUT") {
                setTimeout(function () {
                    theCell.select();
                }, 30)
            }
        }
    </script>

     

    Here is a screenshot taken while debugging the function. This will show you which variable has what value.

     

    I hope this will help clarify your concern.

     

    Kind regards,
    Attila Antal
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top