Timing issue with grid: Creating new row when click on bottom row

8 posts, 0 answers
  1. Jeremy Yoder
    Jeremy Yoder avatar
    131 posts
    Member since:
    Dec 2009

    Posted 31 Mar Link to this post

     

    In our grid (EditMode="Batch", InsertItemDisplay="Bottom", EditType="Cell", OpenEditingEvent="Click") we want to add a new row to the grid if the user clicks on any cell in the last row.

    I made a function to call for OnBatchEditOpened. If it finds you are in the bottom row, it creates a new row below it by running batchManager.addNewRecord(masterTable)

    That works, which triggers my OnRowCreated function, which I want. In there, it runs batchManager.changeCellValue for multiple columns in the new row to initialize their values.

    However, each of those initializing statements (done via changeCellValue) triggers my original function for OnBatchEditOpened, creating a loop. I try to avoid it by creating temp variables outside the functions that skip that function if OnRowCreated is running. It kind of works. But even so, afterwards, the original cell is no longer in edit mode, which we want.

    So now in the original call to OnBatchEditOpened, I'm storing a temp variable of the original cell, which I then try to re-open via batchManager.openCellForEdit(cellTemp), but it doesn't always work. And even when it does, the function now calls itself because a cell is being opened!

    Ugh!

    All that said, I must be going about this the wrong way. So back to the original issue...

    Without going through dodgy javascript acrobatics, how can I click on a cell to edit it, but if it's in the bottom row, create a new row below it, yet keep (or resume?) the original cell in edit mode. There must be an easier way than what I'm doing to avoid loops, temp vars, and with robust code, but I've no clue what it is. Please help.

     

  2. Jeremy Yoder
    Jeremy Yoder avatar
    131 posts
    Member since:
    Dec 2009

    Posted 01 Apr in reply to Jeremy Yoder Link to this post

     

    I kind of got around the situation described above by taking all the changeCellValue calls out of my OnRowCreated function. That way OnBatchEditOpened is no longer called. To instead set the values in OnRowCreated, I have this code...

     

    cell = newItem.get_cell('UnitPrice');
    cell.innerHTML = "<div>0.0000</div>"
    cell = newItem.get_cell('PurchaseOrderDetailAmount');
    cell.innerHTML = "<div>0.00</div>"
    cell = newItem.get_cell('PrintOnPurchaseOrder');
    cell.innerHTML = "<div><input id='chkPrintRead' onclick='changeEditor(this);' type='checkbox' checked='True'></div>";

     

    That seems really hokey, especially since I now have to maintain formatting in 2 different places (both grid and in this function) but by doing so, I'm able to avoid using temp vars to exit OnBatchEditOpened when OnRowCreated is running, and I get no funky errors later on.

    Another thing I had to add, is apparently when a new row is added, OnBatchEditOpened is called again. (Must want to open up a cell in the new row?) So now in that function, just before I call addNewRecord, I assign an outer var of cellTemp to args.get_cell(). Now when OnBatchEditOpened is called, it checks if cellTemp has a value, and if so, runs this code...

    if (cellTemp) {
        // reopen cell we were wanting to edit originally
        setTimeout(function () {
            batchManager.openCellForEdit(cellTemp);
            cellTemp = null;
        }, 100);
        return false;
    }

    Without the time delay, it doesn't work, and I get funky errors later. So while all this seems to work, I feel like I'm breaking Telerik rules and there should be an better way, which will also make the code more manageable.

    Is there an easier way? Also, I'm wondering if assigning to innerHTML in OnRowCreated is bad, because in those cells, there are no longer little red triangles in the upper left to indicate a change has been made, as there was with changeCellValue. Am I setting myself up for problems later on?

     

  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Eyup
    Admin
    Eyup avatar
    3015 posts

    Posted 05 Apr Link to this post

    Hi Jeremy,

    Yes, you are correct. You should only use the built-in editing API when executing Batch related logic. Otherwise, you are setting yourself for problems later on, as you've providently stated.

    I've created a sample RadGrid web site to demonstrate how you can achieve this requirement. The columns have their DefaultInsertValue properties set. Please run the attached application and let me know if it helps you.

    Regards,
    Eyup
    Telerik
    Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
  5. Jeremy Yoder
    Jeremy Yoder avatar
    131 posts
    Member since:
    Dec 2009

    Posted 05 Apr in reply to Eyup Link to this post

     

    That's definitely cleaner than my code! Thanks for the example. I modified it a bit to mimic mine (and copy-pasted below since I can't attach a zip file) to show 3 problems...

    1) If you click on the bottom row it works, but if you click on the new bottom row, it doesn't create another row, but it should.

    2) The checkbox shows "true" rather than a checkbox. (That's part of why I used innerHMTL in my earlier post, but there must be a better solution.)

    3) We also need it to populate with 2 blank rows if there's no data. So on the server-side, if you comment out the code that populates the dataset, my gridCreated code will execute the IF block. It creates 2 rows, but doesn't give default values. (I could create the 2 blank rows server-side, but that would require maintaining 2 places of default values -- on the grid and in code. But if that's the only way, then so be it.)

    Thanks for your help, and look forward to your answers.

     

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="RadGridEditBatchLastRowLogic.aspx.cs" Inherits="RadGridEditBatchLastRowLogic" %>
     
    <!DOCTYPE html>
     
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
                <Scripts>
                    <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
                    <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
                    <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js" />
                </Scripts>
            </telerik:RadScriptManager>
            <script type="text/javascript">
                //Put your JavaScript code here.
     
                function gridCreated(sender, args) {
                    var masterTable = sender.get_masterTableView();
                    var rows = masterTable.get_dataItems();
                    if (rows.length == 0) {
                        var batMan = sender.get_batchEditingManager();
                        batMan.addNewRecord(masterTable);
                        batMan.addNewRecord(masterTable);
                    }
                }
     
                function batchEditOpened(sender, args) {
                    var batMan = sender.get_batchEditingManager();
                    var tableView = args.get_tableView();
                    var items = tableView.get_dataItems();
                    var item = args.get_row().control;
     
                    if (items.length == (item.get_itemIndex() + 1)) {
                        setTimeout(function () {
                            batMan.addNewRecord(tableView);
                            batMan.openCellForEdit(args.get_cell());
                        }, 10);
                    }
                }
            </script>
            <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
            </telerik:RadAjaxManager>
            <telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="False" CellSpacing="0"
                GridLines="None" Width="800px" OnNeedDataSource="RadGrid1_NeedDataSource">
                <ClientSettings AllowKeyboardNavigation="true" >
                    <ClientEvents OnBatchEditOpened="batchEditOpened" OnGridCreated="gridCreated" />
                </ClientSettings>
                <MasterTableView AutoGenerateColumns="False" DataKeyNames="PurchaseOrderDetailKey"
                    EditMode="Batch" InsertItemDisplay="Bottom" CommandItemDisplay="Top">
                    <BatchEditingSettings EditType="Cell" OpenEditingEvent="Click" />
                    <Columns>
     
                        <telerik:GridNumericColumn DataField="PurchaseOrderDetailKey" HeaderText="PurchaseOrderDetailKey"
                            UniqueName="PurchaseOrderDetailKey" DataType="System.Int32" Visible="False" ReadOnly="True">
                        </telerik:GridNumericColumn>
     
                        <telerik:GridTemplateColumn DataField="PostToGeneralLedger" HeaderText="Post" UniqueName="PostToGeneralLedger" DataType="System.Boolean" DefaultInsertValue="true">
                            <HeaderStyle Width="40px" />
                            <ItemStyle Width="40px" />
                            <ItemTemplate>
                                <input id="chkPost" type="checkbox" checked='<%# Eval("PostToGeneralLedger") %>' onclick="changeEditor(this);" />
                            </ItemTemplate>
                            <EditItemTemplate>
                                <asp:CheckBox ID="chkPost" runat="server" Checked='<%# Bind("PostToGeneralLedger") %>' />
                            </EditItemTemplate>
                        </telerik:GridTemplateColumn>
     
                        <telerik:GridTemplateColumn DataField="UnitPrice" HeaderText="UnitPrice" UniqueName="UnitPrice" DataType="System.Double" DefaultInsertValue="0">
                            <ItemTemplate>
                                <asp:Label ID="lblUnitPrice" runat="server"
                                    Text='<%# Eval("UnitPrice") %>'>
                                </asp:Label>
                            </ItemTemplate>
                            <EditItemTemplate>
                                <telerik:RadNumericTextBox ID="txtUnitPrice" runat="server" DataType="System.Decimal" MaxLength="23" Width="100%"
                                    IncrementSettings-InterceptArrowKeys="false" Culture="English (United States)"
                                    DbValue='<%# Bind("UnitPrice") %>' Type="Number" NumberFormat-DecimalDigits="4" />
                            </EditItemTemplate>
                        </telerik:GridTemplateColumn>
     
                        <telerik:GridTemplateColumn DataField="UnitDescription" UniqueName="UnitDescription" HeaderText="Unit Desc" DataType="System.String" DefaultInsertValue="my default">
                            <ItemTemplate>
                                <asp:Label ID="lblUnitDescription" runat="server"
                                    Text='<%# Eval("UnitDescription") %>'>
                                </asp:Label>
                            </ItemTemplate>
                            <EditItemTemplate>
                                <telerik:RadTextBox ID="txtUnitDescription" runat="server" MaxLength="10" Width="100%"
                                Text='<%# Bind("UnitDescription") %>' >
                                </telerik:RadTextBox>
                            </EditItemTemplate>
                        </telerik:GridTemplateColumn>
     
                    </Columns>
                </MasterTableView>
            </telerik:RadGrid>
        </form>
    </body>
    </html>

     

    using System;
    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;
     
    public partial class RadGridEditBatchLastRowLogic : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
        {
            RadGrid1.DataSource = GetGridSource();
        }
        private DataTable GetGridSource()
        {
            DataTable dataTable = new DataTable();
     
            DataColumn column = new DataColumn();
            column.DataType = Type.GetType("System.Int32");
            column.ColumnName = "PurchaseOrderDetailKey";
            dataTable.Columns.Add(column);
     
            column = new DataColumn();
            column.DataType = Type.GetType("System.Boolean");
            column.ColumnName = "PostToGeneralLedger";
            dataTable.Columns.Add(column);
     
            column = new DataColumn();
            column.DataType = Type.GetType("System.Decimal");
            column.ColumnName = "UnitPrice";
            dataTable.Columns.Add(column);
     
            column = new DataColumn();
            column.DataType = Type.GetType("System.String");
            column.ColumnName = "UnitDescription";
            dataTable.Columns.Add(column);
     
            DataColumn[] PrimaryKeyColumns = new DataColumn[1];
            PrimaryKeyColumns[0] = dataTable.Columns["PurchaseOrderDetailKey"];
            dataTable.PrimaryKey = PrimaryKeyColumns;
     
            for (int i = 0; i <= 5; i++)
            {
                DataRow row = dataTable.NewRow();
     
                row["PurchaseOrderDetailKey"] = i + 1;
                row["PostToGeneralLedger"] = true;
                row["UnitPrice"] = (i + 1) + (i + 1) * 0.1 + (i + 1) * 0.01;
                row["UnitDescription"] = "Name " + (i + 1);
     
                dataTable.Rows.Add(row);
            }
     
            return dataTable;
        }
    }

     

  6. Jeremy Yoder
    Jeremy Yoder avatar
    131 posts
    Member since:
    Dec 2009

    Posted 05 Apr in reply to Jeremy Yoder Link to this post

     

    Also, I now get funky errors at times when navigating the grid. But those errors go away if I remove the DefaultInsertValues on my 3 columns. Does DefaultInsertValue not work with GridTemplateColumn?

    I'm really confused how to proceed and our deadline is looming. Any help you can give soon would be very appreciated.

  7. Jeremy Yoder
    Jeremy Yoder avatar
    131 posts
    Member since:
    Dec 2009

    Posted 06 Apr in reply to Jeremy Yoder Link to this post

     

    One more thing: If you put alert("batchEditOpened called"); as the first line in batchEditOpened and click on the bottom most row, you'll see that message pops up multiple times. This seems problematic to me, and goes back to the javascript acrobats I'm having to do, which is that calling addNewRecord within batchEditOpened calls itself.

  8. Jeremy Yoder
    Jeremy Yoder avatar
    131 posts
    Member since:
    Dec 2009

    Posted 06 Apr in reply to Jeremy Yoder Link to this post

     

    I'm backing up and posting a support ticket with the various issues I've been posting on the forum as they're quite intertwined, with the hope that turnaround is faster, so never mind. But thanks for the example as it's a nice springboard.

     

  9. Eyup
    Admin
    Eyup avatar
    3015 posts

    Posted 08 Apr Link to this post

    Hi Jeremy,

    I suggest that you continue the case in the new support ticket you've mentioned.

    Regards,
    Eyup
    Telerik
    Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017