OnBatchEditCellValueChanged change selected value of RadDropDownList in other Rows with Javascript

1 Answer 22 Views
DropDownList Grid
Jerry
Top achievements
Rank 2
Iron
Iron
Jerry asked on 20 Jan 2022, 05:24 PM

So in my RadGrid I have a template column that contains RadDropDownList in the EditItemTemplate.  When this is modified in a row I would like to loop through the RadGrid and modify the other RadDropDownList in the other rows.  I know how to loop through the grid but having trouble accessing the dropdown since the other rows are not in edit mode.   Using the changeCellValue(cellToUpdate, value) of the BatchEditingManager but not having any luck with updating the dropdown.  

<BatchEditingSettings EditType="Cell" />

<telerik:GridTemplateColumn HeaderText="IsBudget" UniqueName="IsBudget" SortExpression="IsBudget">
<ItemTemplate>
<asp:Label ID="lblIsBudget" runat="server" Text='<%# Eval("IsBudget") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<telerik:RadDropDownList ID="ddIsBudget" RenderMode="Lightweight" runat="server" DataValueField="IsBudget" >
<Items>
<telerik:DropDownListItem Text="False" Value="False" />
<telerik:DropDownListItem Text="True" Value="True" />
</Items>
</telerik:RadDropDownList>
</EditItemTemplate>
</telerik:GridTemplateColumn>

1 Answer, 1 is accepted

Sort by
0
Attila Antal
Telerik team
answered on 26 Jan 2022, 03:15 PM | edited on 26 Jan 2022, 03:18 PM

Hi Jerry,

The BatchEditing is delicate functionality that will require special handling. Since it is a Client-Side (JavaScript-based) functionality, everything needs to be done using JavaScript.

 

Important

Due to the nature of BatchEditing, when using the changeCellValue() method, it will not only change the Cell's value but will also change the DropDownList Value for that cell.

If using the OnClientSelectedIndexChanged event of the DropDownList, or the OnBatchEditCellValueChanged Client-Side event of the Grid, these will be triggered for each cell, then the logic will call the changeCellValue() again, resulting in an Endless Loop.

 

Solution

To avoid the infinite loop, you will need to create a Global Flag that you can use to distinguish whether the user selected a new item in the DropDownList or was the JavaScript logic.

Here are three (3) important steps to achieve that:

Step 1: Set a Global Flag when the DropDown element of the DropDownList is opened by the User. 

// This event only triggers if the user clicks on the DropDownList
// Set a Global Flag that will help us avoid the infinite loop
function OnClientDropDownOpened(sender, args) {
    window.__isUserSelecting = true;
}

 

Step 2: To avoid accidents, clear the Global Flag when the DropDown is Closing and the user did not make any selection

// This event only triggers if the user had opened the DropDownList by Clicking on it
// Do this to remove the Global Flag if the user did not select anything
function OnClientDropDownClosing(sender, args) {
    // Condition to check if the Global Flag is defined
    if (typeof window.__isUserSelecting != 'undefined') {
        // Delete/Remove the Global Flag
        window.__isUserSelecting = undefined;
    }
}

 

Step 3: In the SelectedIndexChanged event of the DropDownList

  1. loop through all rows (except the current one)
  2. open the desired cell for editing
  3. find the DropDownList in that cell
  4. Select an item in the DropDownList
  5. when all is done, close the Editing

 

// This event triggers when a Selection changes. Since the BatchEditing will change the selection, this will trigger multiple times
function OnClientSelectedIndexChanged(sender, args) {

    // Using the Global Flag as condition to only run the Logic if the Selection was done by the user and not by BatchEditing
    if (typeof window.__isUserSelecting != 'undefined' && window.__isUserSelecting == true) {

        // Remove/Delete the Global Flag
        window.__isUserSelecting = undefined;

        // Variables & references
        var currentDropDownList = sender; // Current DropDownList
        var grid = $find('<%= RadGrid1.ClientID %>'); // Grid
        var masterTable = grid.get_masterTableView(); // MasterTable 
        var batMan = grid.get_batchEditingManager(); // BatchEditing Manager
        var dataItems = masterTable.get_dataItems(); // Collection of Telerik.Web.UI.GridDataItem Objects
        var currentRowElement = $(currentDropDownList.get_element()).closest('tr')[0]; // Current row (TR) Element
        var currentDataItem = currentRowElement && currentRowElement.control ? currentRowElement.control : undefined; // Current Telerik.Web.UI.GridDataItem Object
        var newValue = currentDropDownList.get_selectedItem().get_value(); // DropDownList Selected Value
        var itemIndexToExclude = (currentDataItem ? currentDataItem.get_itemIndex() : undefined) || -1; // ItemIndex or Row Index of the current Row

        // Begin looping through all items
        for (var i = 0; i < dataItems.length; i++) {

            // Skip running the logic for the Current Row
            if (i == itemIndexToExclude) continue;

            // Target Row
            var rowToBeEdited = dataItems[i];

            // Target Cell
            var cellElement = rowToBeEdited.get_cell("MyTemplateColumn");

            // Open the Cell for Editing
            batMan.openCellForEdit(cellElement);

            // Find the DropDownList in the Cell
            var targetDropDown = $telerik.findControl(cellElement, "RadDropDownList1");

            // Find the DropDownList Item by Value
            var item = targetDropDown.findItemByValue(newValue);

            // Condition to check if Item exists
            if (item)
                item.select(); // Select the Item

            // Close all Edits
            batMan._tryCloseEdits(document.body);
        }
    }
}

 

Result

 

Complete Code Example

<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" Width="300px" OnNeedDataSource="RadGrid1_NeedDataSource">
    <MasterTableView AutoGenerateColumns="False" DataKeyNames="ID" EditMode="Batch">
        <BatchEditingSettings EditType="Cell" />
        <Columns>
            <telerik:GridTemplateColumn HeaderText="DropDownList" UniqueName="MyTemplateColumn">
                <ItemTemplate>
                    <%# Eval("MyItem") %>
                </ItemTemplate>
                <EditItemTemplate>
                    <telerik:RadDropDownList ID="RadDropDownList1" runat="server" RenderMode="Lightweight" AutoPostBack="false"
                        OnClientDropDownOpened="OnClientDropDownOpened"
                        OnClientDropDownClosing="OnClientDropDownClosing"
                        OnClientSelectedIndexChanged="OnClientSelectedIndexChanged">
                        <Items>
                            <telerik:DropDownListItem Text="Item 1" Value="Item 1" />
                            <telerik:DropDownListItem Text="Item 2" Value="Item 2" />
                            <telerik:DropDownListItem Text="Item 3" Value="Item 3" />
                            <telerik:DropDownListItem Text="Item 4" Value="Item 4" />
                        </Items>
                    </telerik:RadDropDownList>

                    <script>
                        // This event only triggers if the user clicks on the DropDownList
                        // Set a Global Flag that will help us avoid the infinite loop
                        function OnClientDropDownOpened(sender, args) {
                            window.__isUserSelecting = true;
                        }

                        // This event only triggers if the user had opened the DropDownList by Clicking on it
                        // Do this to remove the Global Flag if the user did not select anything
                        function OnClientDropDownClosing(sender, args) {
                            // Condition to check if the Global Flag is defined
                            if (typeof window.__isUserSelecting != 'undefined') {
                                // Delete/Remove the Global Flag
                                window.__isUserSelecting = undefined;
                            }
                        }

                        // This event triggers when a Selection changes. Since the BatchEditing will change the selection, this will trigger multiple times
                        function OnClientSelectedIndexChanged(sender, args) {

                            // Using the Global Flag as condition to only run the Logic if the Selection was done by the user and not by BatchEditing
                            if (typeof window.__isUserSelecting != 'undefined' && window.__isUserSelecting == true) {

                                // Remove/Delete the Global Flag
                                window.__isUserSelecting = undefined;

                                // Variables & references
                                var currentDropDownList = sender; // Current DropDownList
                                var grid = $find('<%= RadGrid1.ClientID %>'); // Grid
                                var masterTable = grid.get_masterTableView(); // MasterTable 
                                var batMan = grid.get_batchEditingManager(); // BatchEditing Manager
                                var dataItems = masterTable.get_dataItems(); // Collection of Telerik.Web.UI.GridDataItem Objects
                                var currentRowElement = $(currentDropDownList.get_element()).closest('tr')[0]; // Current row (TR) Element
                                var currentDataItem = currentRowElement && currentRowElement.control ? currentRowElement.control : undefined; // Current Telerik.Web.UI.GridDataItem Object
                                var newValue = currentDropDownList.get_selectedItem().get_value(); // DropDownList Selected Value
                                var itemIndexToExclude = (currentDataItem ? currentDataItem.get_itemIndex() : undefined) || -1; // ItemIndex or Row Index of the current Row

                                // Begin looping through all items
                                for (var i = 0; i < dataItems.length; i++) {

                                    // Skip running the logic for the Current Row
                                    if (i == itemIndexToExclude) continue;

                                    // Target Row
                                    var rowToBeEdited = dataItems[i];

                                    // Target Cell
                                    var cellElement = rowToBeEdited.get_cell("MyTemplateColumn");

                                    // Open the Cell for Editing
                                    batMan.openCellForEdit(cellElement);

                                    // Find the DropDownList in the Cell
                                    var targetDropDown = $telerik.findControl(cellElement, "RadDropDownList1");

                                    // Find the DropDownList Item by Value
                                    var item = targetDropDown.findItemByValue(newValue);

                                    // Condition to check if Item exists
                                    if (item)
                                        item.select(); // Select the Item

                                    // Close all Edits
                                    batMan._tryCloseEdits(document.body);
                                }
                            }
                        }
                    </script>
                </EditItemTemplate>
            </telerik:GridTemplateColumn>
        </Columns>
    </MasterTableView>
</telerik:RadGrid>

<script runat="server">
    protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
    {
        (sender as RadGrid).DataSource = Enumerable.Range(1, 3).Select(x => new
        {
            ID = x,
            MyItem = "Item " + x
        }).ToList();
    }
</script>

 

Please note that this scenario is a very custom solution that is not included out of the box and we can not provide support for it. You can use this as a base idea and adjust it to meet your reuquirements.

 

Regards,
Attila Antal
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/.

Tags
DropDownList Grid
Asked by
Jerry
Top achievements
Rank 2
Iron
Iron
Answers by
Attila Antal
Telerik team
Share this question
or