Grid Databinding from ICollection

Hi guys,
I am using EJ2, VisualStudio, EF6, MVC5. I am having problems to show/edit data from an ICollection in the data received.
Related models:
public partial class clientes
    {
        public clientes()
        {            
            this.contatos = new HashSet<contatos>();
        }    
        public int cliente_id { get; set; }
        public string nome ...      
        public virtual ICollection<contatos> contatos { get; set; }
    }
{

public partial class contatos
    {
        public int contato_id { get; set; }
        public string nome { get; set; }
        public string setor { get; set; }
        public ...
        public Nullable<int> cliente_id { get; set; }    
        public virtual clientes clientes { get; set; }
    }
}

Controller is working fine to retrieve data ondemand...
 public ActionResult UrlDatasource([FromBody]DataManagerRequest dm)
        {        
            IEnumerable DataSource = (from l in db.clientes
                                      select new
                                      {
                                          cliente_id = l.cliente_id,
                                          razao_social = l.razao_social,
                                          nome = l.nome,
                                          end_rua = l.end_rua,
                                          end_numero = l.end_numero,
                                          end_bairro = l.end_bairro,
                                          end_cidade = l.end_cidade,
                                          end_estado = l.end_estado,
                                          end_pais = l.end_pais,
                                          end_cep = l.end_cep,
                                          observacoes = l.observacoes,
                                          contatos = (from m in db.contatos
                                                      where m.cliente_id == l.cliente_id
                                                      select new {
                                                        cliente_id = m.cliente_id,
                                                        contato_id = m.contato_id,
                                                        nome = m.nome
                                                      })
                                      }).ToArray();
               ... all operations to search, sort, paging are working fine
            return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource);

Controller action for CRUD is working fine! PS. I'm updating few fields just for testing purposes...
public ActionResult CrudUpdate(clientes value, string action, int? key)
        {
            string msg;
            if (action == "update")
            {
                clientes clienteTemp = db.clientes.Where(x => x.cliente_id == value.cliente_id).First();
                
                foreach (var contato in value.contatos)
                {
                    contatos contatoTemp = db.contatos.Where(x => x.contato_id == contato.contato_id).First();
                    contatoTemp.cliente_id = contato.cliente_id;
                    contatoTemp.nome = contato.nome;
                    db.Entry(contatoTemp).State = EntityState.Modified;
                }
                clienteTemp.razao_social = value.razao_social;
                clienteTemp.nome = value.nome;
             
                db.Entry(clienteTemp).State = EntityState.Modified;
                db.SaveChanges();
                 msg = "Registro atualizado com sucesso!";
            }
            else if (action == "insert")
            {
                db.clientes.Add(value);
                db.SaveChanges();
                 msg = "Registro alterado com sucesso!";
            }
            else
            {
                var data = db.clientes.Find(key);
                db.clientes.Remove(data);
                db.SaveChanges();
                 msg = "Registro excluído com sucesso!";
            }
            return Json(value, JsonRequestBehavior.AllowGet);
        }

Client View:
<div>
    @Html.EJS().Grid("Clientes").DataSource(dataManager => { dataManager.Url("/Cliente/UrlDatasource").CrudUrl("/Cliente/CrudUpdate").Adaptor("UrlAdaptor"); }).AllowPdfExport(true).ToolbarClick("toolbarClick").DetailTemplate("#detailtemplate").Columns(col =>
{
    col.Field("cliente_id").HeaderText("Cliente ID").IsPrimaryKey(true).AllowEditing(false).Width("70").TextAlign(Syncfusion.EJ2.Grids.TextAlign.Right).Add();
    col.Field("razao_social").HeaderText("Razão social").Width("200").Add();
    col.Field("nome").HeaderText("Nome").Width("200").Add();
    col.HeaderText("Gerenciar").Width("60").Commands(commands).Add();
}).AllowPaging().EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true).ShowDeleteConfirmDialog(true).Mode(Syncfusion.EJ2.Grids.EditMode.Normal); }).AllowSorting().AllowFiltering().Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel", "PdfExport", "Print", "Search" }).DetailDataBound("detailDataBound").Render()
</div>

So I have folowing questions:
1 - How to show/add/edit data from "Contatos" (it's contained in "Clientes" as an ICollection) in the child grid? 


2 - How to show/add/edit selected "Clientes" data in a popup, even those columns not shown in the main grid?


3 - How to pass a message string from CRUD action and show it in a Badge component? 


Many thanks.

11 Replies

MF Mohammed Farook J Syncfusion Team October 25, 2018 11:20 AM UTC

Hi Vanderlei, 
 
Query #1: How to show/add/edit data from "Contatos" (it's contained in "Clientes" as an ICollection) in the child grid? 
 
We have analyzed your query and we suggest to use the childGrid property in the load event of the grid to achieve your requirement. Using queryString property of the childGrid we can show only related data in childGrid with respect to the parent grid. 
 
Code Example: 
 
[.cshtml]   
@Html.EJS().Grid("Grid").DataSource(dataManager => { dataManager.Url("/Home/UrlDatasource").UpdateUrl("/Home/Update").InsertUrl("/Home/Insert").RemoveUrl("/Home/Remove").Adaptor("UrlAdaptor"); }).Columns(col => 
{ 
    ... 
   col.Field("EmployeeID").HeaderText("Employee ID").AllowEditing(false).DefaultValue("1").Width("150").Add(); 
    ... 
}).AllowPaging().Load("load").EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render() 
 
<script> 
    function load(args) { 
        this.childGrid = { 
            queryString: 'EmployeeID', 
            dataSource: new ej.data.DataManager({ 
                url: "/Home/ChildDatasource/", 
                insertUrl: "/Home/ChildInsert/", 
                updateUrl: "/Home/ChildUpdate/", 
                removeUrl: "/Home/ChildDelete/", 
                adaptor: new ej.data.UrlAdaptor() 
            }), 
            query: new ej.data.Query().addParams("key", "1"), 
            toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'], 
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' }, 
            columns: [ 
                { field: 'EmployeeID', headerText: 'Employee ID',isPrimaryKey: true, width: 120 }, 
                { field: 'FirstName', headerText: 'FirstName', width: 120 }, 
                { field: 'LastName', headerText: 'LastName', width: 120 } 
            ] 
        }; 
    } 
</script> 
 
 
 
Query #2: How to show/add/edit selected "Clientes" data in a popup, even those columns not shown in the main grid 
 
You can do the crud operation in a popup by setting editMode of the childGrid to “Dialog”. Columns are also specifically defined for the childGrid from the childGrid dataSource. Please refer to the below code example and sample for your reference. 
 
[.cshtml]   
... 
<script> 
    function load(args) { 
        this.childGrid = { 
... 
            query: new ej.data.Query().addParams("key", "1"), 
            toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'], 
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' }, //crud operations in a dialog popup 
            columns: [ 
                { field: 'EmployeeID', headerText: 'Employee ID',isPrimaryKey: true, width: 120 },   //columns for childGrid 
                { field: 'FirstName', headerText: 'FirstName', width: 120 }, 
                { field: 'LastName', headerText: 'LastName', width: 120 } 
            ] 
        }; 
    } 
</script> 
 
 
Query #3: How to pass a message string from CRUD action and show it in a Badge component? 
 
Using query property with addParams  method, custom message can be passed to server side during CRUD actions. Please find the below documentation for your reference. 
 
[.cshtml]   
... 
<script> 
    function load(args) { 
        this.childGrid = { 
... 
            query: new ej.data.Query().addParams("key", "1"),   //any string can be passed to the server side 
            toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'], 
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Dialog' }, //crud operations in a dialog popup 
            columns: [ 
                { field: 'EmployeeID', headerText: 'Employee ID',isPrimaryKey: true, width: 120 },   //columns for childGrid 
                { field: 'FirstName', headerText: 'FirstName', width: 120 }, 
                { field: 'LastName', headerText: 'LastName', width: 120 } 
            ] 
        }; 
    } 
</script> 
 
 
 
This is not meet your requirement,  could you please share the more detail about your requirement. 
 
 
Regards, 
J Mohammed Farook 



VA Vanderlei October 25, 2018 02:53 PM UTC

Hi Farook, thanks for your answers!
Unfortunatelly the code you suggested is not what I expected. 
Please, let me explain a little more.

- I send all data (master and detail) to the grid in one json file from action urlDatasource as follow:


And the grid returns data to the controller for CRUD as below:


On the cliente side users will be able to change "Clientes" data and "Contatos" data. I wish they do that in the following way:

1 - For the question #1 the example you sent suggested to bind childGrid to other datasource and execute a new query from "Contatos" controller in order to get data. I think we don't need that because we already have all related "Contatos" data in the grid datamanager (UrlDatasource action returned "Contatos" in "Clientes"). The question is how to get "Contatos" data from "Clientes" and fill in the childGrid? Should fields access be like "clientes.contatos.nome" etc?


2 - Main grid is showing 3 out of 11 columns but I need to edit all 11 columns (even those not shown in grid). How to show/edit all 11 columns in a popup window? 


3 - I'd like to show messages coming from controller in Badge components for CRUD actions. How to do it?
public ActionResult CrudUpdate(clientes value, string action, int? key)
        {
            string msg;
            if (action == "update")
            {
               ... all operations here...
                db.SaveChanges();
                 msg = "Registro atualizado com sucesso!";
            }
            else if (action == "insert")
            {
                db.clientes.Add(value);
                db.SaveChanges();
                 msg = "Registro alterado com sucesso!";
            }
            else
            {
                var data = db.clientes.Find(key);
                db.clientes.Remove(data);
                db.SaveChanges();
                 msg = "Registro excluído com sucesso!";
            }
            return Json(value, JsonRequestBehavior.AllowGet);
        }
}

Thanks!



MF Mohammed Farook J Syncfusion Team October 26, 2018 01:33 PM UTC

Hi Vanderlei, 
 
Query #1: I think we don't need that because we already have all related "Contatos" data in the grid datamanager 
 
We have analyzed your query and we can access the complex data of the parent gird by below way in the child grid. 
 
Code Example: 
 
[.cshtml]   
... 
function load(args) { 
        this.childGrid = { 
            queryString: "EmployeeID", 
            toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'], 
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' }, 
            columns: [ 
                { field: 'contatos.name', headerText: 'name', isPrimaryKey: true, width: 120 }, 
                { field: 'contatos.age', headerText: 'age', width: 120 }, 
                { field: 'contatos.EmployeeID', headerText: 'ID', width: 120 } 
            ], 
            load: function () { 
                var data = [];  
                    data.push(this.parentDetails.parentRowData); 
                this.dataSource = new ej.data.DataManager({ 
                    json: data, 
                    insertUrl: "/Home/Insert/", 
                    updateUrl: "/Home/Update/", 
                    removeUrl: "/Home/Remove/", 
                    adaptor: new ej.data.RemoteSaveAdaptor() 
                }) 
            } 
 
        } 
    } 
... 
 
Query #2: Main grid is showing 3 out of 11 columns but I need to edit all 11 columns (even those not shown in grid). How to show/edit all 11 columns in a popup window?  
 
We can achieve your requirement by using  the actionBegin and actionComplete event of the grid. In the actionBegin event, we can show the hidden column by setting visible property to true. In the actionComplete event, we are setting back the visible properties. Please refer to the below documentation and code example. 
 
[.cshtml]   
... 
function begin(args) { 
if ((args.requestType === 'beginEdit' || args.requestType === 'add')) { 
            for (var i = 0; i < this.columns.length; i++) {  //based on your columns 
                if (this.columns[i].field == "EmployeeID" || this.columns[i].field == "Freight" || this.columns[i].field == "ShipCountry") { 
                    this.columns[i].visible = true; 
                } 
            } 
        } 
    } 
    function complete(args) { 
        if (args.requestType === 'save') { 
            for (var i = 0; i < this.columns.length; i++) { 
                if (this.columns[i].field == "EmployeeID" || this.columns[i].field == "Freight" || this.columns[i].field == "ShipCountry") { 
                    this.columns[i].visible = false; 
                } 
            } 
        } 
    } 
... 
 
 
Query #3: 'd like to show messages coming from controller in Badge components for CRUD actions. How to do it? 
 
Using viewBag in the crud method we can able to pass the required string by the below way. 
 
Code Example:  
 
[.cs] 
... 
reg = "Registro"; 
ViewBag.reg = reg; 
... 
[.cshtml]  
... 
var str = @Html.Raw(Json.Encode(ViewBag.reg)); 
console.log(str); 
... 
 
 
Regards, 
J Mohammed Farook 



VA Vanderlei October 30, 2018 05:15 PM UTC

Question #1: Sorry, it doesn't work:
I updated code like bellow:

I get no records, it should show 5 records

I get this error:

I'm really concerned about this solution because I planned to implement many others views using this approach.


Question #2: It worked!

Question #3: I can't get it to work. I tried:
 @Html.EJS().Toast("element").Content(@ViewBag.msg).Render()
 @Html.EJS().Toast("element").Content(ViewBag.msg).Render()
Both show empty toast.
Code bellow worked sometime but it stopped working just after building the app. Page doesn't load page after building...
 @Html.EJS().Toast("element").Content(TempData["Message"].toString()).Render()  

Thank you!!!


MF Mohammed Farook J Syncfusion Team October 31, 2018 12:39 PM UTC

Hi Vanderlei, 
 
Thanks for your update. 
 
Query #1: I get no records, it should show 5 records 
 
We have analyzed your query and we can achieve your requirement by using the detailTemplate and detailDataBound events of the grid. In the detailDataBound, we have rendered a new grid with customeAdaptor for passing message from CRUD to the Toast component. Since same dataSource is used for both parent and child grids, any CRUD operations such as adding a new record to childGrid will result in adding a new row to the parent grid as well after the grid refresh. So same primaryKey has to be used for both parent and child grid to perform delete operation. Please refer to the below sample for your reference. 
 
Code Example: 
 
[.cshtml] 
@Html.EJS().Grid("Grid").DataSource(dataManager => { dataManager.Url("/Home/UrlDatasource").UpdateUrl("/Home/Update").InsertUrl("/Home/Insert").RemoveUrl("/Home/Remove").Adaptor("UrlAdaptor"); }).Columns(col => 
{ 
    ... 
}).AllowPaging().DetailTemplate("#child").DetailDataBound("load").EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render() 
 
<script id="child" type="text/x-template"> 
    <div id="gridparent"></div> 
</script> 
 
<script> 
    class CustomAdaptor extends ej.data.UrlAdaptor { 
        processResponse(data, ds, query, xhr, request, changes) { 
            if (!ej.base.isNullOrUndefined(data.message)) { 
                alert(data.message); 
                ... 
           } 
            if (!ej.base.isNullOrUndefined(data.data)) 
                return data.data; 
            else 
                return data; 
        } 
    } 
 
    function load(args) { 
        var rowData = args.data; 
        var childGrid = new ej.grids.Grid({ 
            dataSource: new ej.data.DataManager({ 
                url: "/Home/UrlDatasource/", 
                insertUrl: "/Home/Insert/", 
                updateUrl: "/Home/Update/", 
                removeUrl: "/Home/Remove/", 
                adaptor: new CustomAdaptor() 
            }), 
            load: function (args) { 
                this.query = new ej.data.Query().where("EmployeeID", "equal", rowData['contatos']['EmployeeID']);  //filtering operation to show related data in childGrid 
            }, 
            actionBegin: function (args) { 
                if (args.requestType == 'save') { 
                    args.data.EmployeeID = args.data.contatos.EmployeeID;       
                } 
            }, 
            toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'], 
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' }, 
            columns: [ 
                { field: 'OrderID', headerText: 'Order ID', isPrimaryKey: true, width: 120 }, 
                { field: 'contatos.EmployeeID', headerText: 'Employee ID', width: 120 }, 
                { field: 'contatos.name', headerText: 'name', width: 120 }, 
                { field: 'contatos.age', headerText: 'age', width: 120 } 
            ] 
        }); 
        childGrid.appendTo(args.detailElement.querySelector('#gridparent')); 
    } 
</script> 
 
 
Query #3: I can't get it to work. I tried: 
 
We have used processResponse method of customAdaptor to get the message passed from the CRUD methods and given to the toast component. We have rendered the toast component when any CRUD operation is performed in the childGrid. Please refer to the below sample for your reference. 
 
Code Example: 
 
[.cs] 
... 
public ActionResult Update(CRUDModel myObject) 
        { 
            ... 
           var msg = "Updated"; 
            return Json(new { data = myObject.Value, message = msg }); 
 
        } 
        public ActionResult Insert(OrdersDetails value) 
        { 
            var msg = "Inserted"; 
            OrdersDetails.BindData().Insert(0, value); 
            return Json(new { data = value, message = msg }); 
        } 
        public ActionResult Remove(int key) 
        { 
            orddata.Remove(orddata.Where(or => or.OrderID == key).FirstOrDefault()); 
            var msg = "deleted"; 
            var dataa = new { result = orddata, count = orddata.Count }; 
            return Json(new { data = dataa, message = msg}); 
        } 
... 
[.cshtml] 
... 
class CustomAdaptor extends ej.data.UrlAdaptor { 
        processResponse(data, ds, query, xhr, request, changes) { 
            if (!ej.base.isNullOrUndefined(data.message)) { 
               setTimeout(() => { 
                    var toastObj = document.getElementById('element').ej2_instances[0]; 
                    toastObj.target = document.body; 
                    toastObj.content = data.message; 
                    toastObj.show(); 
                }, 500); 
            } 
            if (!ej.base.isNullOrUndefined(data.data)) 
                return data.data; 
            else 
                return data; 
        } 
    } 
... 
 
 
Please get back to us for further assistance. 
 
J Mohammed Farook 



VA Vanderlei October 31, 2018 08:17 PM UTC

Query #1: Hi Farook, 

I am still having the same problem. 
When using the code bellow I get no results from controller. 
load: function (args) { 
                this.query = new ej.data.Query().where("cliente_id""equal",rowData['contatos']['cliente_id']);

Looking at DataManagerRequest in UrlDatasource action I see a null value coming from rowData[...][...] always!

After changing that to Query().where("cliente_id", "equal", rowData['cliente_id']); the action receives parameters correctly and returns data correctly as well. In this case the child grid renders just one line and it doesn't show all 5 lines for contacts data. Remember that the structure's data received is the same as the main grid receives, client data contains all related contacts data (for the test bellow client id=3  contains five contacts). 


    function load(args) {
        var rowData = args.data;
        var childGrid = new ej.grids.Grid({
            dataSource: new ej.data.DataManager({
                url: "/Cliente/UrlDatasource",
                CrudUrl: "/Cliente/CrudUpdate",
                adaptor: new CustomAdaptor()
            }),
            load: function (args) {
                this.query = new ej.data.Query().where("cliente_id", "equal", rowData['cliente_id']);  //filtering operation to show related data in childGrid                
            },
            actionBegin: function (args) {
                if (args.requestType == 'save') {
                    args.data.cliente_id = args.data.contatos.cliente_id;
                }
            },
            toolbar: ['Add', 'Edit', 'Delete', 'Update', 'Cancel'],
            editSettings: { allowEditing: true, allowAdding: true, allowDeleting: true, mode: 'Normal' },
            columns: [
                { field: 'contatos.contato_id', headerText: 'Contato ID', isPrimaryKey: true, width: 120 },
                { field: 'cliente_id', headerText: 'Cliente ID', width: 120 },
                { field: 'contatos.nome', headerText: 'nome', width: 120 },
                { field: 'contatos.fone', headerText: 'fone', width: 120 }
            ]
        });
        childGrid.appendTo(args.detailElement.querySelector('#gridparent')); }

Farook: 
1 - As I mentioned before we already have all clients and contacts data when main grid loads its pages. Couldn't childgrid be filled by using already loaded data? clients.contacts.contactId or something like this...

Thank you.



MF Mohammed Farook J Syncfusion Team November 1, 2018 09:57 AM UTC

Hi Vanderlei, 
 
Thanks for your update. 
 
Query #1: After changing that to Query().where("cliente_id", "equal", rowData['cliente_id']); the action receives parameters correctly and returns data correctly as well. In this case the child grid renders just one line and it doesn't show all 5 lines for contacts data. 
 
We have analyzed your query and we have changed the query property according to your requirement. So please modify the query property as mentioned in the below line, 
 
this.query = new ej.data.Query().where("contatos.EmployeeID", "equal", rowData['EmployeeID']);” 
 
Code Example: 
 
[.cshtml] 
... 
<script> 
    ... 
    function load(args) { 
        var rowData = args.data; 
        var childGrid = new ej.grids.Grid({ 
            ... 
            load: function (args) {                     
                this.query = new ej.data.Query().where("contatos.EmployeeID", "equal", rowData['EmployeeID']);  //filtering operation to show related data in childGrid 
//contator.EmployeeID is the childGrid field name which shares identical data with the parent EmployeeID- “contatos.cliente_id” 
            }, 
            actionBegin: function (args) { 
                if (args.requestType == 'save') { 
                    args.data.EmployeeID = args.data.contatos.EmployeeID;       
                } 
            }, 
            ... 
        }); 
        childGrid.appendTo(args.detailElement.querySelector('#gridparent')); 
    } 
</script> 
 
Query #2: As I mentioned before we already have all clients and contacts data when main grid loads its pages. Couldn't childgrid be filled by using already loaded data?  
 
When using UrlAdaptor , the Grid behaves on-demand loading concept.  The Grid can fetch records based on its page size in each request.  for example by default page size is 12 So grid can fetch 12 records only in first page. After move to second page, it takes next 12 records . This is default behavior. 
 
In your case if we render the child grid with already loaded parent data,  child grid can fetch the records  when row key match within 12 records (1st page) of Grid data (not entire dataSource). So we suggest to use UrlAdaptor for both Grid dataSource. 
 
 
We have another one option for ‘RemoteSaveAdaptor’(it load at once in grid all data). It perform all Grid actions in client side except CRUD operations.  If you used RemoteSaveAdaptor , the Grid datasource must be set to Json Property and set adaptor type as RemoteSaveAdaptor to the Adaptor Property of Grid DataManager.  Please find the code example 
 
 
 
 
[Index.cshtml]  
  
@Html.EJS().Grid("Grid").DataSource(dataManager =>{dataManager.Json(ViewBag.dataSource)  
      .InsertUrl("/Home/Insert").RemoveUrl("/Home/Delete").UpdateUrl("/Home/Update").Adaptor("RemoteSaveAdaptor");})  
      .EditSettings(e => { e.AllowAdding(true).AllowEditing(true).AllowDeleting(true); })  
      .Columns(col =>  {  
           col.Field("OrderID").HeaderText("Order ID").IsPrimaryKey(true).Width("30%").Add();  
           ...  
      }).Render()  
  
[HomeController.cs]  
  
        //update the record  
        public ActionResult Update(OrdersDetails value)  
        {  
            ...  
           return Json(value);  
        }  
        //insert the record  
        public ActionResult Insert(OrdersDetails value)  
        {  
  
            ...  
            return Json(new { data = value });  
        }  
        //Delete the record  
        public ActionResult Delete(int key)  
        {  
            ...  
           return Json(data);  
        }  
 
 
 
Please get back to us for further assistance. 
 
Regards, 
J Mohammed Farook 
 
 



VA Vanderlei November 1, 2018 07:13 PM UTC

Hi Farook, many thanks for your replies. Unfortunatelly I couldn't get out of this simple problem so far. I'm sorry for my "not so clear" english because I speak portuguese and sometimes is hard to explain things using a foreign language ;). 

Query #1: Sorry but the piece of code you suggested doesn't work. 
this.query = new ej.data.Query().where("contatos.EmployeeID""equal", rowData['EmployeeID']);”
Farrok, I believe that here the problem is the sintax you suggest, it never worked to get data (contacts.cliente_id) or (rawData['contacts']['cliente_id']) or (clients.contact.contact_id). It didn't work as well as many others sintaxes I tried. I can't get or set any contacts data contained in the client already loaded. Is it really impossible to do it?   

Farook, I am trying to do things this way because I believe that the best approach is to get pages of clients and contacts together, make all changes/inserts needed and send them back together to CRUD.
Actually I never thought it could be so hard to show a really simple 1:n data in a grid. My project has many others views not implemented yet in which I need to show  many related data (even m:n!). Now I'm really concerned because I am not sure if your grid component is the best choice...

Because I can't get stuck in this problem I tried other solution. I've made some crud tests and all is working fine, please check if it could fail for any reason:
- 1) I implemented separated actions for load and crud data for contacts: 

2 - And changed childGrid script like bellow:


3 - Now I have the results rendered correctly:


4 - Do you think the above solution is a valid solution? 
5 - I tried to get childGrid Instance by its Id but I realize that its Id is null, how to set an Id to the childGrid?
6 - A new question: I am from Brazil so I need buttons, messages, etc in portuguese. For main grid I used the following:
  
And I needed to add a lot of translated messages to the script in page:

So the question: How to use it in chilGrid? Isn't there a better way to get mesages translated?

Query #2: Sorry but I can't believe that loading all data (lets say 100k records plus 100k * n contacts) is the best approach. I believe that the paging is the best solution for performance and optimizations, am I right?


MF Mohammed Farook J Syncfusion Team November 2, 2018 09:17 AM UTC

Hi Vanderlei, 
 
Thanks for your update. 
 
Query #1: Do you think the above solution is a valid solution?  
 
Yes, it is a valid solution to provide separate dataSource to the child grid as per your requirement. And we have used actionBegin event to set the parent grid filed value if same CRUD methods used in both parent and child grid. It will result in adding a new row with related child grid data. 
 
Query #2: I tried to get childGrid Instance by its Id but I realize that its Id is null, how to set an Id to the childGrid? 
 
ChildGrid id is already provided with the div element which is rendered in the detailTemplate property. The child grid id will be visible to the document only when anyone one of the child grid is loaded. Please refer to the below code example for your reference. 
 
Code Example: 
 
 
 
<script id="child" type="text/x-template"> 
    <div id="gridparent"></div>          //id of the child grid 
</script> 
 
 
 
After any one of the childGrid is loaded, you can use the below way to set unique id based on unique field and get the instance of the child grid based on those ids. 
 
Code Example:  
 
... 
function load(args) { 
        var rowData = args.data; 
        var childGrid = new ej.grids.Grid({ 
            dataSource: new ej.data.DataManager({ 
... 
            columns: [ 
                ... 
           ], 
            locale: "pt-BR" 
        }); 
        var elem = document.createElement('div'); 
        elem.id = "childGrid-" + args.data.EmployeeID;    //you can create div’s with unique ids and append the grid. 
        childGrid.appendTo(elem); 
        args.detailElement.querySelector('#gridparent').appendChild(elem); 
    } 
... 
 
 
 
Way to get a instance of a child grid:    
 
 
document.getElementById(“childGrid-1”).ej2_instances[0]; 
 
 
 
Query #3: How to use it in chilGrid? Isn't there a better way to get mesages translated?  
 
The locale property which is set the parent grid can be provided to the child grid as well without rewriting the translation again. By the below way, we can set the same locale property to the child grid. 
 
Code Example: 
 
 
...}).AllowPaging().Locale("pt-BR").DetailTemplate("#child").DetailDataBound("load").EditSettings(edit => { edit.AllowAdding(true).AllowEditing(true).AllowDeleting(true); }).Toolbar(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel" }).Render() 
 
... 
<script> 
    ej.base.setCulture("pt-BR") 
    ej.base.L10n.load({ 
        'pt-BR': { 
            grid: { 
                "Add": "adicionar" 
                 
            } 
        } 
    }); 
... 
    function load(args) { 
        var rowData = args.data; 
        var childGrid = new ej.grids.Grid({ 
            dataSource: new ej.data.DataManager({ 
... 
            }),   
... 
            columns: [ 
                ... 
           ], 
            locale: "pt-BR" 
        }); 
        childGrid.appendTo(args.detailElement.querySelector('#gridparent')); 
    } 
 
 
 
 
Query #4: I believe that the paging is the best solution for performance and optimizations, am I right? 
 
Yes, UrlAdaptor is the best solution for on-demand concept of data loading. 
 
Please get back to us for further assistance. 
 
Regards, 
J Mohammed Farook 
 



VA Vanderlei November 2, 2018 01:42 PM UTC

Hi Farook, now I have all working fine!



The custom column I added as follow:
1 - I created a list of custom columns;
2 - got the list in script

3 - added the list to the child grid column
 
It's working fine, do you suggest any modifications?

Thank you so much for your support. 


MF Mohammed Farook J Syncfusion Team November 5, 2018 06:06 AM UTC

Hi Vanderlei,  
 
Thanks for your update. 
 
We are happy to hear your problem has been resolved.  Yes this is write to enable command column in your grid. Field property is no need defined in command column. Please find the demo and documentation for your reference. 
 
 
 
Regards, 
J Mohammed Farook 


Loader.
Up arrow icon