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

Radgrid batch edit - get value from combobox and read only values code-behind

1 Answer 750 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Lars Erik
Top achievements
Rank 1
Lars Erik asked on 01 Oct 2019, 07:31 AM

Hi 

I have a problem with radgrid in batch edit mode. I am trying to find out how I can get all values from all columns/rows when saving. I have not bound this grid to a simple datasource. Based on all data from the grid I need to create and populate a new class and send it to the server (via other functions). So I need to get all values from the grid so I can build and populate the correct class (datatable). My grid consist of both normal editable fields, read-only fields and radcombo boxes. Based on the value in my combobox I make columns read-only or not. I am trying to achive a mass update of a list<class>.

I need to find all values in code-behind! I can find the new values for updated editable fields this example

foreach (GridBatchEditingCommand command in e.Commands)
            {
                if ((command.Type == GridBatchEditingCommandType.Update))
                {
                    Hashtable newValues = command.NewValues;
                    Hashtable oldValues = command.OldValues;

 

But I can not find out how I can get:

1. selected value from radcombobox (datasource for this combo is build on-click).

2. value from read-only columns in the grid.

<%@ Page Title="Mass update of requisition lines/Parts" Language="C#" MasterPageFile="~/SunFlower.Master" AutoEventWireup="true" CodeBehind="RequisitionLineMassUpdate.aspx.cs" Inherits="SunflowerWeb.RequisitionLineMassUpdate" %>
 
<%@ Register Assembly="Sunflower.Web.Controls" Namespace="Sunflower.Web.Controls" TagPrefix="sunflower" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
 
<asp:Content ID="MassUpdateContent" ContentPlaceHolderID="mcph"  runat="server">
     
   <telerik:RadAjaxManagerProxy ID="ManagerProxy" runat="server">
        <AjaxSettings>
            <telerik:AjaxSetting AjaxControlID="MasterAjaxManger">
                <UpdatedControls>
                </UpdatedControls>
            </telerik:AjaxSetting>
            <telerik:AjaxSetting AjaxControlID="gridMassUpdate">
                <UpdatedControls>
                </UpdatedControls>
            </telerik:AjaxSetting>
 
        </AjaxSettings>
    </telerik:RadAjaxManagerProxy>
 
     <telerik:RadCodeBlock ID="RadCodeBlock1" runat="server">
        <script type="text/javascript">
            var ReqLineFunctions = new Array();
 
            function saveAll() {
                var grid1 = $find("<%=gridMassUpdate.ClientID%>");
                var batchManager1 = grid1.get_batchEditingManager();
                var hasChanges = batchManager1.hasChanges(grid1.get_masterTableView());
                if (hasChanges) {
                    batchManager1.saveTableChanges([grid1.get_masterTableView()]);
                } else {
                    var ajaxPanel = $find("<%=RadAjaxPanel1.ClientID%>");
                    ajaxPanel.ajaxRequest("saveChanges");
                }
            }
 
            function GetSelectedFunction(sender, args) {
                var batchManager = sender.get_batchEditingManager();
                var masterTable = sender.get_masterTableView();
                masterTable.get_dataItems();
                var dataItem = $find(args.get_row().id);
                var combo = dataItem.findControl("cbFunction");
                var comboValue = combo.get_selectedItem().get_value();
                return comboValue;            
            }
 
            function GetReqLineId(sender, args) {
                var batchManager = sender.get_batchEditingManager();
                var masterTable = sender.get_masterTableView();
                masterTable.get_dataItems();
                var dataItem = $find(args.get_row().id);
                var reqLineId = dataItem.findElement("lblReqLineId");
                var reqLineIdValue = reqLineId.innerText;
                return reqLineIdValue;            
            }
 
            function batchEditOpening(sender, args) {
 
                var selectedFunc = GetSelectedFunction(sender, args);
                var reqLineId = GetReqLineId(sender, args);
 
                if (selectedFunc !== null && reqLineId !== null) {
                    if (ReqLineFunctions.length > 0) {
                        //Is partnumber updatable
                        for (let i = 0; i < ReqLineFunctions.length; i++) {
                            if (ReqLineFunctions[i].ReqLineId === reqLineId) {
                                var funcs = ReqLineFunctions[i].Functions;
 
                                for (let k = 0;k < funcs.length; k++) {
                                    if (funcs[k].FunctionName === selectedFunc) {
                                        if (!funcs[k].IsPartUpdatable) {
                                            args.set_cancel(true);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
 
            function SelectFunction(sender, eventArgs) {
                //todo: populate the rest of the columns based on the selected function
           
            }
 
            function GetFunctions(sender, args) {
                var text = args._text;
                itemsRequesting(sender, args);
 
                //Dummy collection of functions. todo: replace with functions from api-call
                var funcs = new Array();
                funcs.push({
                     FunctionName: "SuppToTecOk",
                     FunctionDescription : "Receive from supplier",  
                     IsPartUpdatable : true
                  });
 
                funcs.push({
                     FunctionName: "TecOkToCust",
                     FunctionDescription : "Deliver to customer",  
                     IsPartUpdatable : false
                  });
 
                //add to global array so i can lookup and find values later
                var reqlineid = sender.get_attributes().getAttribute("data-reqlineid");
                if (reqlineid !== null) {
                    ReqLineFunctions.push({
                        ReqLineId: reqlineid,
                        Functions: funcs
                    })
                }
 
                FillCombo(sender, funcs);
                sender.highlightAllMatches(sender.get_text());
            }
 
            // This cancels the default RadComboBox behavior
            function itemsRequesting(sender, args) {
                if (args.set_cancel != null) {
                    args.set_cancel(true);
                }
                if (sender.get_emptyMessage() == sender.get_text())
                    sender.set_text("");
            }
 
            function FillCombo(combo, functions) {
                combo.clearItems();
                combo.trackChanges();
                for (var i = 0; i < functions.length; i++) {
                    var comboItem = new Telerik.Web.UI.RadComboBoxItem();
                    comboItem.set_text(functions[i].FunctionDescription);
                    comboItem.set_value(functions[i].FunctionName);
                    combo.get_items().add(comboItem);
                }
            }
 
        </script>
    </telerik:RadCodeBlock>
 
    <telerik:RadAjaxPanel runat="server" ID="RadAjaxPanel1" OnAjaxRequest="RadAjaxPanel1_AjaxRequest">
        <h1>Mass update parts</h1>
        <h4><asp:Label ID="litTip" runat="server" Text=""></asp:Label></h4>
 
        <div class="buttonFormBorderXL">
            <div class="fltlft buttons tools">
                <telerik:RadButton runat="server" ID="RadButton1" AutoPostBack="false" Text="Save all"  OnClientClicked="saveAll"></telerik:RadButton>
            </div>
        </div>
        <div class="box fltlft formXL clft">
            <img src="fwimages/form_curve01.gif" class="curve01" alt="" />
            <img src="fwimages/form_curve02.gif" class="curve02" alt="" />
            <br />
 
            <div class="simpleList">
                <telerik:RadGrid ID="gridMassUpdate" renderMode="Lightweight" runat="server" OnNeedDataSource="gridMassUpdate_NeedDataSource" AllowAutomaticInserts="True" 
                        AllowPaging="false" AutoGenerateColumns="False" Skin="SunflowerSkin" EnableEmbeddedSkins="False"
                        OnBatchEditCommand="gridMassUpdate_BatchEditCommand" CellSpacing ="0" GridLines="None" Height="680px">
                <ClientSettings>
                    <Scrolling AllowScroll="true" UseStaticHeaders="true" />
                </ClientSettings>
                     
                <AlternatingItemStyle Font-Size="8pt" />
                <MasterTableView EditMode="Batch" PageSize="50" CommandItemDisplay="None" AllowPaging="false" DataKeyNames="SearchResultRowId" AutoGenerateColumns="false">
                    <BatchEditingSettings EditType="Cell"/>
                    <Columns>
                        <telerik:GridTemplateColumn Visible="true" ReadOnly="true" UniqueName="SearchResultRowId"  DataField="SearchResultRowId" HeaderText="id">
                            <ItemTemplate>
                                <telerik:RadLabel ID="lblReqLineId" runat="server" Text='<%# Eval("SearchResultRowId")%>'></telerik:RadLabel>
                            </ItemTemplate>
                        </telerik:GridTemplateColumn>
                         
                        <telerik:GridNumericColumn Visible="true" ReadOnly="true" DataField="RequisitionNumber" HeaderText="Requisition" AllowFiltering="false">
                        </telerik:GridNumericColumn>
 
                        <telerik:GridTemplateColumn DataField="PartNumber"  HeaderText="Part" UniqueName="PartNumber">
                            <ItemTemplate>
                                <telerik:RadLabel ID="lblPartNumber" runat="server" Text='<%# Eval("PartNumber")%>'></telerik:RadLabel>
                            </ItemTemplate>
                            <EditItemTemplate>
                                <telerik:RadTextBox ID="txtPartNumber" runat="server" Text='<%# Eval("PartNumber")%>'></telerik:RadTextBox>
                            </EditItemTemplate>
                        </telerik:GridTemplateColumn>
 
                        <telerik:GridBoundColumn DataField="PartDescription" ReadOnly="true" HeaderText="Description" UniqueName="PartDescription">
                        </telerik:GridBoundColumn>
 
                         <telerik:GridTemplateColumn HeaderText="Function" UniqueName="SelectedFunction">
                            <ItemTemplate>
                                <telerik:RadComboBox ID="cbFunction" RenderMode="Lightweight" runat="server" EnableLoadOnDemand="true" EmptyMessage="Select"
                                    data-reqlineid='<%# Eval("SearchResultRowId")%>' OnClientItemsRequesting="GetFunctions" OnClientSelectedIndexChanged="SelectFunction" Text="Select">
                                </telerik:RadComboBox>
                            </ItemTemplate>
                        </telerik:GridTemplateColumn>
 
                    </Columns>
                </MasterTableView>
                <ClientSettings>
                    <ClientEvents OnBatchEditOpening="batchEditOpening" />
                </ClientSettings>
                <ItemStyle Font-Size="8pt" />
            </telerik:RadGrid>
        </div>
    </div>
    </telerik:RadAjaxPanel>
</asp:Content>

 

and code-behind:

using Sunflower.Web.Controls;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
 
namespace SunflowerWeb
{
    public partial class RequisitionLineMassUpdate : System.Web.UI.Page
    {
        private bool saveChanges = false;
 
        private List<Sunflower.Business.RequisitionLineMassUpdate> ReqLines
        {
            get
            {
                return (List<Sunflower.Business.RequisitionLineMassUpdate>)Session["ReqLines" + MassUpdateId];
            }
        }
 
        public string MassUpdateId
        {
            get
            {
                return (string)ViewState["MassUpdateId"];
            }
            set
            {
                ViewState["MassUpdateId"] = value;
            }
        }
 
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if (Request.QueryString["MassUpdateId"] == null && string.IsNullOrEmpty(MassUpdateId))
                    MassUpdateId = Guid.NewGuid().ToString();
                else if (Request.QueryString["MassUpdateId"] != null)
                    MassUpdateId = Request.QueryString["MassUpdateId"];
            }
 
        }
 
        protected void gridMassUpdate_BatchEditCommand(object sender, GridBatchEditingEventArgs e)
        {
            saveChanges = true;
 
            //Trying to read all items....do not work!
            foreach (GridDataItem item in gridMassUpdate.Items)
            {
                string func = item.Cells[4].Text;  //radcombo
                string part = item.Cells[2].Text;  //radtexbox
            }
 
            foreach (GridBatchEditingCommand command in e.Commands)
            {
                if ((command.Type == GridBatchEditingCommandType.Update))
                {
                    Hashtable newValues = command.NewValues;
                    Hashtable oldValues = command.OldValues;
 
                    try
                    {
                        string combinedId = newValues["SearchResultRowId"].ToString();
                        string partNumber = newValues["PartNumber"].ToString();
 
                        //NONONO. Not possible to get value from radcombobox. Why ?
                        string function = newValues["SelectedFunction"].ToString();
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }
 
        protected void Page_PreRender(object sender, EventArgs e)
        {
            if (saveChanges)
            {
                //Save the values from the other controls
            }
        }
 
        protected void RadAjaxPanel1_AjaxRequest(object sender, AjaxRequestEventArgs e)
        {
            if (e.Argument == "saveChanges")
            {
                saveChanges = true;
            }
        }
 
        protected void gridMassUpdate_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
        {
            if (ReqLines.Count > 0)
            {
                gridMassUpdate.DataSource = ReqLines;
            }
        }
 
    }
}

 

Is it possible to get all values from an updated radgrid in batch mode ????

 

Best regards

Lars

 

 

 

 

 

 

1 Answer, 1 is accepted

Sort by
0
Eyup
Telerik team
answered on 03 Oct 2019, 11:32 AM

Hello Lars,

 

Generally, I am afraid having combo with individual binding or EnableLoadOnDemand in Batch editing scenario is not supported:
https://www.telerik.com/support/kb/aspnet-ajax/grid/details/radgrid-batch-editing-templates-and-specifics

However, since you are so close to the final implementation and have everything else working as expected, I will try to assist you in resolving this remaining problem.

So, to get the values from the ReadOnly fields, you can add the field names to the DataKeyNames collection of the MasterTableView tag. Then, you will be able to access these values any time using the GetDataKeyValue method:
https://docs.telerik.com/devtools/aspnet-ajax/controls/grid/rows/accessing-cells-and-rows#accessing-raw-field-data-and-key-values

This leaves only the combo value. This can be somewhat tricky, but nevertheless, we can achieve it. Basically, you can try these things to get the value on the server:

1. SelectedValue property of the combo

2. Text property of the combo

3. On selected index changed client-side event handler of the combo set the value to some HiddenField:
https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.webcontrols.hiddenfield?view=netframework-4.8

If you want to achieve that for multiple rows, you can also save the values in a JS object using their IDs:
https://docs.telerik.com/devtools/aspnet-ajax/controls/grid/rows/accessing-cells-and-rows#getdatakeyvalue

Then, you can pass this object to the HiddenField.value using JSON.stringify.

And finally, you can deserialize it to a Dictionary on server side to access the value, similar to this:

JavaScriptSerializer serializer = new JavaScriptSerializer();
            Dictionary<string, string> details = serializer.Deserialize<Dictionary<string, string>>(e.CommandArgument.ToString());

I hope this will prove helpful. Feel free to try out these solutions and keep us updated on the result.

 

Regards,
Eyup
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
Lars Erik
Top achievements
Rank 1
Answers by
Eyup
Telerik team
Share this question
or