OnBatchEditOpened | OnBatchEditClosed | getElementsByTagName

1 Answer 33 Views
Editor
Kyle
Top achievements
Rank 1
Kyle asked on 16 Oct 2024, 04:36 PM

Created js function to edit cells using OnBatchEditClosed and  OnBatchEditOpened. The cells appear to "update" fine in terms of numbers and get a little red icon on cell. Yet whenever click save or attempt to edit a second cell get an error that can't read null properties on getElementsByTagName. 

Basically anything that involves GridBatchEditing again seems to cause an issue. How to resolve?


 //new Object()
        class Step4Rec {
            constructor() {
                this.monthForecast_PreviousVal = "";
                this.safetyStock_PreviousVal = 0;
                this.qtyPlanned_PreviouisVal = 0
            }
        };

        var step4OriginalData = new Array();

        //var DatesStartToEnd = new Array();
        var dateHelp = "T00:00:00";//adding z at end means UTC/Greenwich

        
        const DatesToProcessRec = {
            processingDate : new Date()
            , theYear : 2024 
            , theMonthNotZeroBased : 1
            , theMonthZeroBased : 0
            , theDay : 1
        };


        //OnBatchEditClosed="Step4PlanningEditsClosed" OnBatchEditOpened="Step4PlanningItemOpened" 
        function Step4PlanningEditsClosed(sender, args) {
            
            let grid = sender;
            let masterTableView = grid.get_masterTableView();
            let dataItems = masterTableView.get_dataItems();

            let todayDate = new Date();
            let modMonth = todayDate.getMonth();
            let modDay = 1;
            let modYear = todayDate.getYear();

            try {
                for (var i = 0; i < dataItems.length; i++) {
                    let monthForecast = dataItems[i].get_cell("MonthForecast").innerText;
                    let safetyStock = parseInt(dataItems[i].get_cell("SafetyStock").innerText);
                    let qtyPlanned = parseInt(dataItems[i].get_cell("QtyPlanned").innerText);

                    if (i < dataItems.length - 3)
                        safetyStock = 2;    
                    else
                        safetyStock = 0;
                
                    if (safetyStock > 0) {

                        let getCurrentMthRecord = monthForecast.split("/");
                        let theYear = getCurrentMthRecord[1];
                        let theMonth = MonthConversion(getCurrentMthRecord[0]);
                        let theCurrentMthRecordDate = new DateConversion(theMonth, theYear);

                        let revert = false;

                        for (let j = 1; j <= safetyStock && safetyStock != 0 && revert == false; j++) {
                            //last month can't have a stock value other then 0 as there are no more records
                            if (j + i < dataItems.length - 1) {
                                let expectedMonth = new Date(theCurrentMthRecordDate.setMonth(theCurrentMthRecordDate.getMonth() + 1));

                                let nextMonthForecast = dataItems[i+j].get_cell("MonthForecast").innerText;
                                let getNextMthRecord = nextMonthForecast.split("/");
                                let theNextYearOfRec = getNextMthRecord[1];
                                let theNextMonthOfRec = MonthConversion(getNextMthRecord[0]);
                                theNextRecordMthRecordDate = new DateConversion(theNextMonthOfRec, theNextYearOfRec);

                                //console.log(theNextRecordMthRecordDate.toString() + "|" + expectedMonth.toString());
                                if (theNextRecordMthRecordDate.getTime() === expectedMonth.getTime()) {
                                    let safetyStockToAdd = parseInt(dataItems[j + i].get_cell("QtyPlanned").innerText);
                                    qtyPlanned += safetyStockToAdd;
                                }
                                else {
                                    revert = true;
                                }
                            }
                            else {
                                revert = true;
                            }                                                          
                        }

                        if (revert == true) {

                            for (let k = 0; k < step4OriginalData.length; k++) {
                                //console.log(dataItems[k].get_cell("MonthForecast").innerText .toString() + " | " + step4OriginalData[k].monthForecast.toString())
                                if (dataItems[k].get_cell("MonthForecast").innerText == step4OriginalData[k].monthForecast) {
                                    dataItems[k].get_cell("SafetyStock").innerText = step4OriginalData[k].safetyStock.toString();
                                    dataItems[k].get_cell("QtyPlanned").innerText = step4OriginalData[k].qtyPlanned.toString();
                                }                                    
                            }

                            throw new Error("Invalid number of safety stock months specified. If safety stock months is greater then 0, please be sure following months are included in previous forecast steps.");
                            //alert("Invalid number of safety stock months specified. If safety stock months is greater then 0, please be sure following months are included in previous forecast steps.");
                        }

                        dataItems[i].get_cell("QtyPlanned").innerText = qtyPlanned;       
                    }//end if
                        //else it should be 0 or less (technically only 0) and just keep the number that is in the box that was sent on close
                }//end for
                console.log("before save changes call");
                //saveChangesToGrid();
                //console.log("after save changes call");
            } catch (error) {
                console.log(error.toString());
                alert(error.toString());
            }
        }// end function

        function DateConversion(month, year) {      
            //console.log("month: " + month.toString() + " | year: " + year.toString());
            return new Date(year.toString() + "-" + ("0" + month.toString()).slice(-2) + "-01"  + dateHelp);
        }

        function MonthConversion(str3LtrMonth) {

            switch (str3LtrMonth.toLowerCase()) {
                case "jan": return 1;
                case "feb": return 2;
                case "mar": return 3;
                case "apr": return 4;
                case "may": return 5;
                case "jun": return 6;
                case "jul": return 7;
                case "aug": return 8;
                case "sep": return 9;
                case "oct": return 10;
                case "nov": return 11;
                case "dec": return 12;
                default: throw new Error("month value not found");
            }
        }

        
        function Step4PlanningItemOpened(sender, args) {
            step4OriginalData.length = 0;

            let grid = sender;
            let masterTableView = grid.get_masterTableView();
            let dataItems = masterTableView.get_dataItems();

            let itemCellQtyPlanned = args.get_cell("QtyPlanned");
            let itemCellValue = sender.get_batchEditingManager().getCellValue(itemCellQtyPlanned);

            let rowItem = args.get_row();
            //assuming monthfrecast is in column 1 (first column)
            let itemCellMonthForecast = rowItem.children[0].innerText.toString();
               
            //console.log("::setup::");

            for (let i = 0; i < dataItems.length; i++) {
                let recordStep4 = new Step4Rec();
                
                recordStep4.monthForecast = dataItems[i].get_cell("MonthForecast").innerText;
                recordStep4.safetyStock = dataItems[i].get_cell("SafetyStock").innerText;
                recordStep4.qtyPlanned = dataItems[i].get_cell("QtyPlanned").innerText;

                //attempt to input missing data another way
                if ((recordStep4.qtyPlanned == undefined || recordStep4.qtyPlanned == "") && recordStep4.monthForecast.toString() == itemCellMonthForecast.toString() ) {
                    recordStep4.qtyPlanned = itemCellValue;
                }

                step4OriginalData.push(recordStep4); 
                //console.log(recordStep4.monthForecast.toString() + " | " + recordStep4.safetyStock.toString() + " | " + recordStep4.qtyPlanned.toString());
            }

            /*
            console.log("::output::");
            for (var od = 0; od < step4OriginalData.length; od++) {
                console.log("od: " + od.toString());
                console.log(step4OriginalData[od].monthForecast.toString() + " | " + step4OriginalData[od].safetyStock.toString() + " | " + step4OriginalData[od].qtyPlanned.toString());
            }
            */
        }

 


<telerik:RadWizardStep 
                        ID="StepAggregateDemand" 
                        Title="4. Aggregate Demand" 
                        StepType="Step" 
                        Enabled="false" 
                        Active="false" 
                        runat="server">
                        <telerik:RadAjaxPanel ID="RadAjaxPanelAggregateDemand" runat="server" AsyncPostBackTimeout="20000"   LoadingPanelID="RadAjaxLoadingPanelAggregateDemand"> 
                        <div style="height:30px">
                            <span> 
                                <telerik:RadButton ID="RadButtonNextStepAggregateDemand" Skin="Default" Text="Next" CssClass="button_buttonNext" Width="80px" Height="22px" ToolTip="Click to see next destination"  runat="server" ButtonType="LinkButton" OnClientClicking="OnNextClicking"></telerik:RadButton>     
                                <telerik:RadButton ID="RadButtonPreviousStepAggregateDemand" Skin="Default" Text="Previous" CssClass="button_buttonPrevious" Width="80px" Height="22px" ToolTip="Click to see previous destination"  runat="server" ButtonType="LinkButton" OnClientClicking="OnPreviousClicking" ></telerik:RadButton>                                                    
                            </span>
                        </div>
                        <telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanelAggregateDemand" AsyncPostBackTimeout="1200"  runat="server" Skin="Default" Modal="true" /> 
                            <telerik:RadGrid 
                                AutoGenerateColumns="false" 
                                ID="RadGridAggregateDemand" 
                                CssClass="CenterAll"  
                                RenderMode="Lightweight"  
                                AllowFilteringByColumn="false" 
                                AllowSorting="false" 
                                OnItemDataBound="RadGridAggregateDemand_ItemDataBound" 
                                OnItemCommand="RadGridAggregateDemand_ItemCommand"
                                ShowFooter="true" 
                                runat="server" 
                                PageSize="100" 
                                OnBatchEditCommand="RadGridAggregateDemand_BatchEditCommand">
                                <ExportSettings>
                                    <Excel Format="Xlsx"  />
                                </ExportSettings>
                                <GroupingSettings  CaseSensitive="false" />
                                <ClientSettings  EnableRowHoverStyle="false" AllowKeyboardNavigation="true" >
                                    <ClientEvents OnBatchEditClosed="Step4PlanningEditsClosed" OnBatchEditOpened="Step4PlanningItemOpened" /> 
                                </ClientSettings>
                                <MasterTableView 
                                    AutoGenerateColumns="false" 
                                    EditMode="Batch"   
                                    CommandItemDisplay="TopAndBottom" 
                                    DataKeyNames="MonthForecast" 
                                    Name="MonthForecast"   
                                    AllowFilteringByColumn="false" 
                                    ShowFooter="true" 
                                    AllowSorting="false">
                                    <BatchEditingSettings EditType="Cell" OpenEditingEvent="Click"  />
                                    <CommandItemSettings  
                                        ShowAddNewRecordButton="false"  
                                        ShowRefreshButton="false" 
                                        ShowCancelChangesButton="true"                                      
                                        ShowSaveChangesButton="false" 
                                        /> 
                                    <CommandItemTemplate>
	                                    <telerik:RadButton runat="server" ID="ResetButton" autopostback="false"  Text="Reset to Last Save" ToolTip="Reset to Last Save" style="float: right;" OnClientClicked="cancelChangesToGrid" Width="170px"><Icon PrimaryIconCssClass="rgIcon rgCancelIcon" /></telerik:RadButton>
	                                    <telerik:RadButton runat="server" ID="SaveChangesButton" AutoPostBack="false" Text="Save Changes" ToolTip="Save Changes" style="float: right;" OnClientClicked="saveChangesToGrid" Width="145px"><Icon PrimaryIconCssClass="rgIcon rgSaveIcon" /></telerik:RadButton>  
                                    </CommandItemTemplate>
                                    <Columns>
                                        <telerik:GridBoundColumn UniqueName="MonthForecast" DataField="MonthForecast"  HeaderText="MonthForecast" ReadOnly="true" HeaderTooltip=""></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="PPPY_1Month" DataField="PPPY_1Month" HeaderText="PPPY_1Month" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip="" Aggregate="Sum"></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="PPY_1Month" DataField="PPY_1Month" HeaderText="PPY_1Month" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip=""  Aggregate="Sum" ></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="PY_1Month" DataField="PY_1Month" HeaderText="PY_1Month" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip=""  Aggregate="Sum" ></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="Composite" DataField="Composite" HeaderText="Composite" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip="This is the sum of the previous sales (from 12 months ago) of the Key Product Master and the Contributing Product Masters, based on the levels of contribution assigned in the Style Demand Composite."  Aggregate="Sum" ></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="Months1Perc" DataField="Months1Perc" HeaderText="∆ 1 Month %" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip="This measures the difference between the py 1 month (based on when this report is run) and the same 1 month 2 years ago. This is based on the Key Product Master and proportional contribution from the Contributing Product Masters."></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="Months3Perc" DataField="Months3Perc" HeaderText="∆ 3 Months %" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip="This measures the difference between the py 3 months (based on when this report is run) and the same 3 months 2 years ago. This is based on the Key Product Master and proportional contribution from the Contributing Product Masters."></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="Months6Perc" DataField="Months6Perc" HeaderText="∆ 6 Months %" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip="This measures the difference between the py 6 months (based on when this report is run) and the same 6 months 2 years ago. This is based on the Key Product Master and proportional contribution from the Contributing Product Masters."></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="PY_PPYPerc" DataField="PY_PPYPerc" HeaderText="∆ PY/PPY %" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip="This measures the difference between 2 year and 3 years rolling."></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="MPPY_MPPPYPerc" DataField="MPPY_MPPPYPerc" HeaderText="∆ 3MPPY/3MPPPY %" ReadOnly="true" DataFormatString="{0:N0}" HeaderTooltip="This measures the difference between a 2 year ago 3 months and 3 years ago 3 months."></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="PlannedPerc" DataField="PlannedPerc" HeaderText="∆ Planned %" ReadOnly="false" DataFormatString="{0:N0}" HeaderTooltip="The suggested value that appears in this field is the stored value else based on ∆ 6 Months % (default min 0, default max 50)"></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="SafetyStock" DataField="SafetyStock" HeaderText="Safety Stock %" ReadOnly="false" DataFormatString="{0:N0}" HeaderTooltip="Default to 10%"></telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn UniqueName="QtyPlanned" DataField="QtyPlanned" HeaderText="Qty Planned" ReadOnly="false" DataFormatString="{0:N0}" HeaderTooltip="This Is the aggregate forecasted demand for this product master For Each month."  Aggregate="Sum" ></telerik:GridBoundColumn>
                                    </Columns>
                                </MasterTableView>
                            </telerik:RadGrid>
                        </telerik:RadAjaxPanel>   
                        <br />
                        <asp:ImageButton ID="ImgExcelOutputAggregateDemand" ImageAlign="Left" ImageUrl="images/excel-2010-icon.gif" OnClick="ExcelOutputAggregateDemand" runat="server" CssClass="ImageButtons" Visible="True" />
                        <br />  
</telerik:RadWizardStep>

1 Answer, 1 is accepted

Sort by
0
Vasko
Telerik team
answered on 21 Oct 2024, 11:16 AM

Hello Kyle,

Thank you for the provided code snippet. I tested with it, however, I wasn't able to reproduce the issue you're experiencing, due to missing code logic (most likely the logic used in the SaveChanges button).

Below I have added a snippet for a sample Grid where I'd like to ask you to try and reproduce the issue with it, and then send the code for further analysis:  

<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" Width="800px"
    OnNeedDataSource="RadGrid1_NeedDataSource"
    OnInsertCommand="RadGrid1_InsertCommand"
    OnUpdateCommand="RadGrid1_UpdateCommand"
    OnDeleteCommand="RadGrid1_DeleteCommand">
    <MasterTableView AutoGenerateColumns="False" DataKeyNames="OrderID" EditMode="Batch" BatchEditingSettings-EditType="Cell" 
        CommandItemDisplay="Top" InsertItemDisplay="Top" InsertItemPageIndexAction="ShowItemOnLastPage">
        <Columns>
            <telerik:GridBoundColumn DataField="OrderID" DataType="System.Int32"
                FilterControlAltText="Filter OrderID column" HeaderText="OrderID"
                ReadOnly="True" SortExpression="OrderID" UniqueName="OrderID">
            </telerik:GridBoundColumn>
            <telerik:GridDateTimeColumn DataField="OrderDate" DataType="System.DateTime"
                FilterControlAltText="Filter OrderDate column" HeaderText="OrderDate"
                SortExpression="OrderDate" UniqueName="OrderDate">
            </telerik:GridDateTimeColumn>
            <telerik:GridNumericColumn DataField="Freight" DataType="System.Decimal"
                FilterControlAltText="Filter Freight column" HeaderText="Freight"
                SortExpression="Freight" UniqueName="Freight">
            </telerik:GridNumericColumn>
            <telerik:GridBoundColumn DataField="ShipName"
                FilterControlAltText="Filter ShipName column" HeaderText="ShipName"
                SortExpression="ShipName" UniqueName="ShipName">
            </telerik:GridBoundColumn>
            <telerik:GridBoundColumn DataField="ShipCountry"
                FilterControlAltText="Filter ShipCountry column" HeaderText="ShipCountry"
                SortExpression="ShipCountry" UniqueName="ShipCountry">
            </telerik:GridBoundColumn>
        </Columns>
    </MasterTableView>
</telerik:RadGrid>

    #region Properties for CRUD Operations
    public DataTable SessionDataSource
    {
        get
        {
            string sessionKey = "SessionDataSource";
    
            if (Session[sessionKey] == null || !IsPostBack)
            {
                Session[sessionKey] = OrdersTable();
            }
            return (DataTable)Session[sessionKey];
        }
    }
    #endregion
    
    #region RadGrid Events for CRUD Operations
    
    // CREATE (Add New Record)
    protected void RadGrid1_InsertCommand(object sender, GridCommandEventArgs e)
    {
        GridEditableItem editedItem = e.Item as GridEditableItem;
    
        DataRow newRow = SessionDataSource.NewRow();
    
        //As this example demonstrates only in-memory editing, a new primary key value should be generated
        //This should not be applied when updating directly the database
        DataRow[] allValues = SessionDataSource.Select("OrderID = MAX(OrderID)");
    
        if (allValues.Length > 0)
        {
            newRow["OrderID"] = int.Parse(allValues[0]["OrderID"].ToString()) + 1;
        }
        else
        {
            newRow["OrderID"] = 1; //the table is empty;
        }
    
        //Set new values
        Hashtable newValues = new Hashtable();
        //The GridTableView will fill the values from all editable columns in the hash
        e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem);
    
        try
        {
            foreach (DictionaryEntry entry in newValues)
            {
                newRow[(string)entry.Key] = entry.Value;
            }
        }
        catch (Exception ex)
        {
            e.Canceled = true;
            return;
        }
    
        SessionDataSource.Rows.Add(newRow);
    }
    
    // READ (data binding)
    protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
    {
        (sender as RadGrid).DataSource = SessionDataSource;
    }
    
    // UPDATE
    protected void RadGrid1_UpdateCommand(object sender, GridCommandEventArgs e)
    {
        GridEditableItem editedItem = e.Item as GridEditableItem;
    
        //Locate the changed row in the DataSource
        DataRow[] changedRows = SessionDataSource.Select(string.Format("OrderID = {0}", editedItem.GetDataKeyValue("OrderID")));
    
        if (changedRows.Length != 1)
        {
            e.Canceled = true;
            return;
        }
        //Update new values
        Hashtable newValues = new Hashtable();
        e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem);
        changedRows[0].BeginEdit();
        try
        {
            foreach (DictionaryEntry entry in newValues)
            {
                changedRows[0][(string)entry.Key] = entry.Value;
            }
            changedRows[0].EndEdit();
        }
        catch (Exception ex)
        {
            changedRows[0].CancelEdit();
            e.Canceled = true;
            return;
        }
    }
    
    // DELETE
    protected void RadGrid1_DeleteCommand(object sender, GridCommandEventArgs e)
    {
        GridDataItem dataItem = e.Item as GridDataItem;
        string ID = dataItem.GetDataKeyValue("OrderID").ToString();
    
        if (SessionDataSource.Rows.Find(ID) != null)
        {
            SessionDataSource.Rows.Find(ID).Delete();
        }
    }
    #endregion
    
    #region DataSource
    private DataTable OrdersTable()
    {
        DataTable dt = new DataTable();
    
        dt.Columns.Add(new DataColumn("OrderID", typeof(int)));
        dt.Columns.Add(new DataColumn("OrderDate", typeof(DateTime)));
        dt.Columns.Add(new DataColumn("Freight", typeof(decimal)));
        dt.Columns.Add(new DataColumn("ShipName", typeof(string)));
        dt.Columns.Add(new DataColumn("ShipCountry", typeof(string)));
    
        dt.PrimaryKey = new DataColumn[] { dt.Columns["OrderID"] };
    
        for (int i = 0; i < 70; i++)
        {
            int index = i + 1;
    
            DataRow row = dt.NewRow();
    
            row["OrderID"] = index;
            row["OrderDate"] = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0).AddHours(index);
            row["Freight"] = index * 0.1 + index * 0.01;
            row["ShipName"] = "Name " + index;
            row["ShipCountry"] = "Country " + index;
    
            dt.Rows.Add(row);
        }
    
        return dt;
    }
    #endregion
    

    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
    Kyle
    Top achievements
    Rank 1
    commented on 22 Oct 2024, 03:54 PM

    resolved
    Tags
    Editor
    Asked by
    Kyle
    Top achievements
    Rank 1
    Answers by
    Vasko
    Telerik team
    Share this question
    or