This is a migrated thread and some comments may be shown as answers.

Client Event OnBatchEditOpened bug?

1 Answer 75 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Cider
Top achievements
Rank 1
Cider asked on 12 Nov 2019, 08:40 PM

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

1 Answer, 1 is accepted

Sort by
0
Attila Antal
Telerik team
answered on 15 Nov 2019, 06:11 PM

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.
Tags
Grid
Asked by
Cider
Top achievements
Rank 1
Answers by
Attila Antal
Telerik team
Share this question
or