Combining batch editing with master/details filtering

Hi,

Iet's say we have two grids, the first is for orders and the second is for order details. What I'm trying to accomplish is to allow the user to select an order row from the first grid and get the corresponding details in the second one, I could do that easily with DataManager but that would disable the batch editing functionalities of the second grid, for example:

dataManager.executeQuery(query).done(function (e) { 
              
               $scope.dataSource = e.result; //bind the Grid data source  
 
            }); 

After updating the dataSource of the second grid with filtered data like in previous code, the original dataAdapter with batch editing settings will be overwritten by the new data source, and that will disable the editing features.

How can I overcome this limitation?

5 Replies

TS Thavasianand Sankaranarayanan Syncfusion Team May 29, 2018 12:43 PM UTC

Hi Islam, 

Thanks for contacting Syncfusion support. 

According to your query we suspect that batch editing get disabled after dataSource get updated to the second Grid. We are unable to reproduce the reported issue from our end.  

We have prepared a video demonstration of not reproduction of the issue. 


We have prepared a simple JsPlayground sample in the following link. 


Based on your given code example we suspect that you may using adaptor for Grid rendering(remote data) and also performed CRUD operations in server side. Based on your given code examples CRUD operations were done in locally not in server end.  

Because you have set the dataSource in locally to the Grid. So, we suggest you to redefine the adaptors for the second Grid dataSource as we using in initial render. 

For an example we have using remote save adaptor for second Grid dataSource and we have redefine the adaptor while updating the dataSource in the below code example. 

 
<script> 
 
    angular.module("GridCtrl", ["ejangular"]) 
        .controller("bodyCtrl", function ($scope) { 
 
        //Provide the second Grid datasource in the initial rendering.  
        $scope.data = ej.DataManager({json: obj, 
            batchUrl: "BatchUpdate", 
            adaptor: new ej.remoteSaveAdaptor() 
}); 
 
        $scope.DetailGridLoad = function (args) { // rowSelected event 
                 
                ---                
 
                var detaildata = dataManager.executeQuery(query).done(function (e) {  
               
               $scope.data = ej.DataManager({url: e.result, 
                    batchUrl: "BatchUpdate", 
                    adaptor: new ej.remoteSaveAdaptor() 
               }); 
//bind the second Grid data source while updating 
  
                  } 
       });            
       
        ---- 
        
        }); 
 
</script> 

  
If you still facing the same issue then please provide the following details for better assistance. 

  1. Share screenshot or video demonstration of the issue.  
  2. Share full Grid code example both client and server end.
  3. Is batch editing working only in locally instead of working at server end? Or Is batch editing is fully disabled (Not able to edit a record) for ejGrid control?
  4. Share Essential Studio version details.

Regards, 
Thavasianand S. 



IY Islam yahia May 30, 2018 10:46 AM UTC

Hi Thavasianand,

I've tried setting the json to the query result like in the code snippet that you've provided:

 $scope.data = ej.DataManager({url: e.result, 
                    batchUrl: "BatchUpdate", 
                    adaptor: new ej.remoteSaveAdaptor() 
               }); 

Here is how I wrote the DataManager definition and I suspect it's somehow incorrect and I can't find how to define it correctly  in the documentation: (Please note that I'm using WebApiAdapter)

            ej.DataManager({ url: "/api/OrderDetail", adaptor: new ej.WebApiAdaptor() }).executeQuery($scope.detailsQuery)
                .done(function (e) {
                    $scope.detailsData = ej.DataManager({
                        json: e.result,
                        adaptor: new ej.WebApiAdaptor(),
                        batchUrl: "/api/batch",
                        insertUrl: "/postOrderDetail",
                        updateUrl: "/putOrderDetail",
                        removeUrl: "/deleteOrderDetail"
                    });
                });

This gave me the following error:

TypeError: Cannot read property 'indexOf' of undefined
    at i.processQuery (ej.web.all.min.js:10)
    at t.DataManager.executeLocal (ej.web.all.min.js:10)
    at Object._ensureDataSource (ej.web.all.min.js:10)
    at Object._processBindings (ej.web.all.min.js:10)
    at Object.refreshContent (ej.web.all.min.js:10)
    at Object._refreshDataSource (ej.web.all.min.js:10)
    at Object._setModel (ej.web.all.min.js:10)
    at Object.setModel (ej.web.all.min.js:10)
    at Object.option (ej.web.all.min.js:10)
    at b.raise (ej.widget.angular.min.js:10)


TS Thavasianand Sankaranarayanan Syncfusion Team May 30, 2018 01:58 PM UTC

Hi Islam, 

As per your previous update that you want to maintain the CRUD operations in server end once we update the second Grid data. So, we suggest you pass the query parameter in the query property of ejGrid control and update the Grid dataSource using the dataSource method of ejGrid control. 

In the below code example we have pass filter query to the server end for the second Grid dataSource. 


<script>  
  
    angular.module("GridCtrl", ["ejangular"])  
        .controller("bodyCtrl"function ($scope) {  
  
        //Provide the second Grid datasource in the initial rendering.   
        $scope.data = ej.DataManager({ 
            url: "/api/Employee", 
            batchUrl: "/api/batch", 
            updateUrl: "/Grid/UrlUpdate", 
            insertUrl: "/Grid/UrlInsert", 
            removeUrl: "/Grid/UrlDelete", 
            adaptor: new ej.WebApiAdaptor(), 
        }); 
  
        $scope.DetailGridLoad = function (args) { // rowSelected event  
                  
                ---                 
            
        var employeeID = args.data.EmployeeID; 
 
        var query = ej.Query().where("EmployeeID", ej.FilterOperators.equal, employeeID, false); 
      
        grid.option("query", query); 
 
        var dataManager = ej.DataManager({ 
            url: "/api/Employee", 
            batchUrl: "/api/batch", 
            updateUrl: "/Grid/UrlUpdate", 
            insertUrl: "/Grid/UrlInsert", 
            removeUrl: "/Grid/UrlDelete", 
            adaptor: new ej.WebApiAdaptor(), 
        }); 
 
        grid.dataSource(dataManager) //bind the second Grid data source with adaptor enabled  
   
                  }  
       });             
        
        ----  
         
        });  
  
</script>  



Refer the help documentation. 




Regards, 
Thavasianand S. 



IY Islam yahia May 31, 2018 09:39 AM UTC

Hi Thavasianand,

I managed to resolve the issue by following your approach, but with little tweaks.

One more query: how can I access the grid element from the controller without using jQuery, I've tried using $scope.Grid but that returns undefined.

Regards,


TS Thavasianand Sankaranarayanan Syncfusion Team June 1, 2018 12:15 PM UTC

  
Hi Islam, 

We have analyzed your query and we suspect that you want to get the Grid element in the controller. 

In the below code example we have get the second Grid instance in the rowSelected event of first Grid to apply the query API in setModel. 


<div class="content-container-fluid"> 
        <div class="row"> 
            <div class="cols-sample-area"> 
 
                <div class="label1">Master Grid </div> 
 
                <div id="MasterGrid" ej-grid e-datasource="empData" e-allowselection='true' e-rowselected="DetailGridLoad"> 
                    <div e-columns> 
 
                       ---- 
 
                    </div> 
                </div> 
 
                <div class="label1">Detail Grid</div> 
 
                <div id="DetailGrid" ej-grid e-datasource="data" e-allowpaging="false" e-editsettings="editSettings" e-toolbarsettings="toolbarItems"> 
                    <div e-columns> 
 
                         ---- 
 
                    </div> 
                </div> 
            </div> 
 
        </div> 
    </div> 
 
    <script> 
         
 
         
        angular.module('listCtrl', ['ejangular']) 
        .controller('PhoneListCtrl', function ($scope) { 
             
            --- 
 
            //Provide the second Grid datasource in the initial rendering.    
        $scope.data = ej.DataManager({  
            url: "/api/Employee",  
            batchUrl: "/api/batch",  
            updateUrl: "/Grid/UrlUpdate",  
            insertUrl: "/Grid/UrlInsert",  
            removeUrl: "/Grid/UrlDelete",  
            adaptor: new ej.WebApiAdaptor(),  
        });  
 
             
        $scope.DetailGridLoad = function (args) { // rowSelected event for first Grid 
 
                var employeeID = args.data.EmployeeID; 
 
                var query = ej.Query().where("EmployeeID", ej.FilterOperators.equal, employeeID,false);  
 
                 
                $('#DetailGrid).ejGrid('instance').option({query: query}); // Apply the Grid query in setmodel 
 
                $scope.data = ej.DataManager({  
            url: "/api/Employee",  
            batchUrl: "/api/batch",  
            updateUrl: "/Grid/UrlUpdate",  
            insertUrl: "/Grid/UrlInsert",  
            removeUrl: "/Grid/UrlDelete",  
            adaptor: new ej.WebApiAdaptor(),  
        });   //bind the second Grid data source with adaptor enabled   
                 
                --- 
 
    } 
  }); 
 
</script> 

 

Note: We can get the second Grid instances using jQuery only.  

If we misunderstood your query then please get back to us.  

Regards 
Thavasianand S. 


Loader.
Up arrow icon