Grid in batch mode on a master details form

13 posts, 2 answers
  1. Ashraf Sabry
    Ashraf Sabry avatar
    88 posts
    Member since:
    Jan 2011

    Posted 19 Nov 2013 Link to this post

    Greetings,

    RadGrid, while in the batch mode, keeps items locally until saveChanges (or any of the other save methods) is called. It then serializes the items to a string and posts it to the server.

    What if I have other controls on the page that cause post backs?
    For example, on a master details form, the user will enter data in the header then add/edit/delete some records to the grid, then clicks the save button of the form. The grid won't raise any events then and the grid data will be lost as it wasn't sent as part of the request.
    Is my understanding right? Or there's a method to make batch mode grids participate in post backs like simple controls do?

    I ask this because I may have more complex forms with multi level of details and each level will have its batch mode grid, and I can't make any of the grids initiate the post back using saveChanges.
  2. Answer
    Antonio Stoilkov
    Admin
    Antonio Stoilkov avatar
    530 posts

    Posted 22 Nov 2013 Link to this post

    Hi Ashraf,

    You are correct in your observations. The RadGrid Batch editing functionality have been created to mimic the current RadGrid editing functionality. If you enter a item in edit mode it is required to click the Update button to update the data.

    In order to achieve your scenario you will need to call the saveTableChanges method for each GridTableView that you want to update and when the BatchEditCommand event is called execute the logic associated with your current Save button code as shown in the example below.
    function onSaveButtonClick() {
        var grid1 = $find("<%= RadGrid1.ClientID %>"),
            grid2 = $find("<%= RadGrid2.ClientID %>");
     
        grid1.get_batchEditingManager().saveTableChanges([grid1.get_masterTableView(), grid2.get_masterTableView()]);
    }

    bool firstTimeToCallBatchEditCommand = true;
    protected void RadGrid1_BatchEditCommand(object sender, Telerik.Web.UI.GridBatchEditingEventArgs e)
    {
        if (firstTimeToCallBatchEditCommand)
        {
            OnSaveButtonClick();
            firstTimeToCallBatchEditCommand = false;
        }
    }
     
    protected void OnSaveButtonClick()
    {
        // your logic for saving other form inputs
    }

    Regards,
    Antonio Stoilkov
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Ashraf Sabry
    Ashraf Sabry avatar
    88 posts
    Member since:
    Jan 2011

    Posted 24 Nov 2013 Link to this post

    Thanks for your reply,

    I thought about a solution like this for single detail forms. But, I didn't expect that I can do this with multiple separate grids, so this line
    grid1.get_batchEditingManager().saveTableChanges([grid1.get_masterTableView(), grid2.get_masterTableView()]);
    makes me amazed. Can the batch editing manager object of a grid save the data of other grids?
    It seems then that there's no coupling between batch editing managers and table views.
  5. Answer
    Antonio Stoilkov
    Admin
    Antonio Stoilkov avatar
    530 posts

    Posted 27 Nov 2013 Link to this post

    Hi Ashraf,

    RadGrid BatchEditingManager is partially detached from its RadGrid instance and its related GridTableView objects. What this means is - the manager will know which is his owner and when calling saveChanges and saveAllChanges methods it will call them for the appropriate GridTableView's. However, the implementation is designed to be decoupled enough in order to enable saving GridTableView's from different RadGrid's so complex scenarios like yours are possible.

    Regards,
    Antonio Stoilkov
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
  6. Ashraf Sabry
    Ashraf Sabry avatar
    88 posts
    Member since:
    Jan 2011

    Posted 27 Nov 2013 Link to this post

    Thank you for your replies. I'll try your suggestion when I face this scenario and give you feedback.
  7. Graham
    Graham avatar
    6 posts
    Member since:
    May 2014

    Posted 03 Jul 2014 Link to this post

    I am facing this same situation (submit entire form with RadGrid and other controls with single button click) and have wired up my button to run the client side code as you describe above.

    However I am finding that if the user doesn't changed anything in the RadGrid then the BatchEditCommand handler in the code behind is not called hence the "// your logic for saving other form inputs" is never reached.

    If the user does change some data in the RadGrid then all works as expected.

    How can make sure that the BatchEditCommand is called even if no data is changed in the RadGrid?

    Thanks


  8. Antonio Stoilkov
    Admin
    Antonio Stoilkov avatar
    530 posts

    Posted 04 Jul 2014 Link to this post

    Hello Graham,

    In order to resolve your issue you could use the new BatchEditing manager method hasChanges and check if there are any changes in the grid. If there are changes you could call the saveChanges otherwise you could trigger the button click in order to save the other data.
    function save(grid) {
        if (grid.get_batchEditingManager().hasChanges(grid.get_masterTableView())) {
            grid.get_batchEditingManager().saveChanges(grid.get_masterTableView());
        } else {
            // call button click
        }
    }

    Regards,
    Antonio Stoilkov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  9. Graham
    Graham avatar
    6 posts
    Member since:
    May 2014

    Posted 07 Jul 2014 Link to this post

    Thanks for your suggestion. It has enabled me to get a little further. I now have another problem.

    When I make a change to the RadGrid contents and click the outside button, the BatchEditCommand is called server side and all works well.

    But when I add a new row to the RadGrid and click the same button, the BatchEditCommand is called as before but this time the command.Newvalues is null and hence I cannot get the inserted values. I have left the command buttons showing in the RadGrid and when I click the "Save Changes" button in the Grid the BatchEditCommand method does receive the correct command.NewValues.

    See the code I'm using below. In the codebehind on the line marked //** the command.NewValues is null

    Thanks

    ASPX
    <asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server">
                <script type="text/javascript">               
                 function onSaveButtonClick() {
                        var grid1 = $find('<%=RadGrid1.ClientID%>');                    
                        var grid1changes = grid1.get_batchEditingManager().hasChanges(grid1.get_masterTableView());                    
                        if (grid1changes) {
                             grid1.get_batchEditingManager().saveChanges(grid1.get_masterTableView());
                         }
                     }
                </script>
                <telerik:RadGrid ID="RadGrid1" runat="server" ShowStatusBar="true" OnNeedDataSource="RadGrid1_NeedDataSource1"  OnBatchEditCommand="RadGrid1_BatchEditCommand"  >
            
                    <MasterTableView CommandItemDisplay="TopAndBottom" AutoGenerateColumns="false" EditMode="Batch" BatchEditingSettings-EditType="Row" CommandItemSettings-AddNewRecordText="Add new row" EnableNoRecordsTemplate="true">
                        <NoRecordsTemplate>
                        No Data Found.
                        </NoRecordsTemplate>
                        <BatchEditingSettings EditType="Cell" />
                        <Columns>
                            <telerik:GridTemplateColumn HeaderText="Title" UniqueName="Title" DataField="Title" ForceExtractValue="Always">
                                    <ItemTemplate>
                                        <asp:Label Text='<%# Eval("Title") %>' runat="server" /> 
                                    </ItemTemplate>
                                    <EditItemTemplate>
                                        <telerik:RadTextBox runat="server" ID="RadTextBox_Title" TextMode="SingleLine" ></telerik:RadTextBox>
                                        <span><asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ErrorMessage="*This field is required" ForeColor="red" ControlToValidate="RadTextBox_Title" Display="Dynamic"></asp:RequiredFieldValidator></span>
                                    </EditItemTemplate>
                            </telerik:GridTemplateColumn>
                            <telerik:GridBoundColumn HeaderText="Field1" UniqueName="Field1" ForceExtractValue="Always" DataField="Field1" />                        <telerik:GridClientDeleteColumn ConfirmText="Are you sure you want to delete the selected row?"  HeaderStyle-Width="35px" ButtonType="ImageButton"  />
                        </Columns>
                    </MasterTableView>
                </telerik:RadGrid>            
                <input type="button" value="SaveChangesClient" onclick="onSaveButtonClick();" />
    </asp:Content>
     
    Code Behind
    public partial class SimpleExample : LayoutsPageBase
        {        protected void Page_Load(object sender, EventArgs e)
            {
            }        protected void RadGrid1_NeedDataSource1(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
            {
                ArrayList planningConditions = new ArrayList();
                planningConditions.Add(new mydata("Value1","field1"));
                planningConditions.Add(new mydata("Value2","field2"));
                planningConditions.Add(new mydata("Value3","field3"));
                RadGrid1.DataSource = planningConditions;
            }        /// <summary>
            /// PreInit to set the masterpage to the current web site master page
            /// </summary>
            /// <param name="e"></param>
            protected override void OnPreInit(EventArgs e)
            {
                base.OnPreInit(e);
                this.MasterPageFile = SPContext.Current.Web.MasterUrl;
            }        protected void RadGrid1_BatchEditCommand(object sender, GridBatchEditingEventArgs e)
            {            foreach (GridBatchEditingCommand command in e.Commands)
                {
                        // fetch new values from the form
                        Hashtable newValues = command.NewValues; //** rhs is null even when a new row has been added.
                        Hashtable oldValues = command.OldValues;
                }
            }
        }    public class mydata
        {
            private string title;
            private string field1;        public mydata(string titleValue, string field1Value)
            {
                title = titleValue;
                field1 = field1Value;
            }        public string Title
            {
                get { return title; }
                set { title = value; }
            }        public string Field1
            {
                get { return field1; }
                set { Field1 = value; }
            }
        }

  10. Angel Petrov
    Admin
    Angel Petrov avatar
    1006 posts

    Posted 10 Jul 2014 Link to this post

    Hi Graham,

    We have already provided an answer regarding this problem in the official support ticket you have opened. In order to help other community members overcome this issue I am pasting the reply from the ticket.

    "I am afraid that after calling hasChanges property the logic behind that breaks the functionality which save the values. I already logged it in our system and our developers will try to fix it sooner. Meanwhile you could use the following workaround."
    Copy Code
    <script type="text/javascript">
        function onSaveButtonClick() {
            var grid1 = $find('<%=RadGrid1.ClientID%>');
            var grid1changes = grid1.get_batchEditingManager()._extractChangesString(grid1.get_masterTableView());
            if (grid1changes.length > 0) {
                grid1.get_masterTableView().fireCommand("BatchEdit", grid1changes);
            }
        }
    </script>


    Regards,
    Angel Petrov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  11. Graham
    Graham avatar
    6 posts
    Member since:
    May 2014

    Posted 14 Jul 2014 in reply to Angel Petrov Link to this post

    Hi Angel,
    Yes that really worked ... however ... I have another complex requirement.

    I have multiple RadGrids in my page and my code fires the "BatchEdit" command on each of them as in your example above. I am finding that only the last of these calls causes the BatchEditCommand on the server side to trigger for that RadGrid. All the RadGrid controls are in a single RadAjaxPanel.
    .
    Do you know how I can make each Grid post back correctly, have the BatchEditCommand  and NeedDataSource run on the back end and refresh on the browser in Ajax?

    Thanks for all your help.

    Graham
  12. Angel Petrov
    Admin
    Angel Petrov avatar
    1006 posts

    Posted 17 Jul 2014 Link to this post

    Hi Graham,

    In order to fire the OnBatchEditCommand for every grid one should call the saveTableChanges method of the batch editing manager and pass to it an array of GridTableView objects. Considering the aforementioned you can modify the code logic like demonstrated below.

    JavaScript:
    function onSaveButtonClick() {
                      var grid1 = $find('<%=RadGrid1.ClientID%>');
                var grid1changes = grid1.get_batchEditingManager()._extractChangesString(grid1.get_masterTableView());
                if (grid1changes.length > 0) {
     
                    var tableViews=[];
                    tableViews.push(grid1.get_masterTableView());
                    tableViews.push($find('<%=RadGrid2.ClientID%>').get_masterTableView());
                    grid1.get_batchEditingManager().saveTableChanges(tableViews);
                }
            }


    Regards,
    Angel Petrov
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  13. Emad
    Emad avatar
    16 posts
    Member since:
    Dec 2015

    Posted 05 Mar Link to this post

    Hi,
    I'm using external button to save two grids in batch edit mode, it's working fine.
    But I'm facing issue when required validation fires code still working where it should stop ?!!
    Please advice..


    function saveTowGrids() {
                try{
                    var grid1 = $find("<%= RadGrid1.ClientID %>");
                    var masterTable1 = grid1.get_masterTableView();
                    var grid2 = $find("<%= RadGrid2.ClientID %>");
                    var masterTable2 = grid2.get_masterTableView();
                    var batchEditManager = grid2.get_batchEditingManager();
                    var tables = [];
                    tables.push(masterTable1);
                    tables.push(masterTable2);
                    batchEditManager.saveTableChanges(tables);
                    alert("save completed");
                } catch (e) { alert(e);}
            }


    Thanks,
    Emad

  14. Angel Petrov
    Admin
    Angel Petrov avatar
    1006 posts

    Posted 09 Mar Link to this post

    Hi Emad,

    Could you please let us know what is the exact problem when required validation is used?

    As for the code the batchEditManager.saveTableChanges method should fire a postback meaning that the alert below should not be called. Is this the problem you are experiencing?

    If you have a complex scenario it would be best to share with us the problematic page contents(markup and code-behind) so we could examine the implementation.

    Regards,
    Angel Petrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017