We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Missing expand icon for Child data in treegrid

Hi,

I am binding child data for treegrid using dataStateChange event of treegrid but Missing expand icon in child nodes even though it hasChildMapping property isParent is true,

please add hasChildData: true to childData array objects in the below link in index.ts file and please check the UI expand icon is missing for child node.

https://codesandbox.io/s/bitter-snowflake-jf550

Please provide solution for this

Thanks,
Dayakar.

7 Replies

PK Padmavathy Kamalanathan Syncfusion Team November 12, 2019 04:22 PM UTC

Hi Dayakar,

Thanks for contacting Syncfusion Forums.

QUERY1: Missing expand icon for child data in TreeGrid

From your code we can see that you are using Custom Binding(using dataStateChage) to bind data to TreeGrid. Since you are using our DataManager, you need not to use the Custom Binding. Custom Binding is meant for custom logic data. In our data manager, we have did everything needed for binding child node by inbuilt.

So we suggest you use our dataManager with webApi Adaptor. 

Please check the below sample,


If you have further queries, please get back to us.

Regards,
Padmavathy Kamalanathan






DR Dayakar Reddy November 12, 2019 04:32 PM UTC

Hi Padmavathy Thank you for the reply.

I am following the below approach 

But i want to use Custom Binding(using dataStateChage) based on my requirement we need to display large number of records in treegrid, can you suggest me how to display expand icon for child nodes when we use custom binding?

though the isParent is set to true the expand is missing for child nodes.

Thanks,
Dayakar.


DR Dinesh Rajendiran Syncfusion Team November 13, 2019 05:51 PM UTC

Hi Dayakar, 

Query : though the isParent is set to true the expand is missing for child nodes. 

We were also able to replicate the issue on our side. We have confirmed that the reported issue is a bug and have logged a defect report for the same. The fix for this issue will be in the patch release which is expected to be rolled out on November 27 2019. 

Till then we appreciate your patience. You can track the status of the reported issue from the below link. 



Regards, 
Dinesh Rajendiran 



DR Dayakar Reddy November 14, 2019 08:20 AM UTC

Hi Dinesh Thank you for the reply.

Instead of custom binding now i am using syncfusion dataManager. expand icon is now getting displayed. your sample code helped me.

I have below query

1)  i am doing CRUD operations on treegrid,  how to add additional params to  rest api request when we add record in treegrid.  my requirement is when we add record in treegrid i need to pass the selected row primary key to the post request  .


  // POST: api/Orders
        [HttpPost]
        public object Post([FromBody]SelfReferenceData value)
        {
            SelfReferenceData.tree.Insert(0, value);
            var data = SelfReferenceData.tree.ToList();
            return Json(new { result = data, count = data.Count });
        }


SE Sathyanarayanamoorthy Eswararao Syncfusion Team November 16, 2019 04:56 AM UTC

Hi Dayakar, 

We have achieved your requirement by using the Custom Adaptor concept and overriding the insert method of the WebApiAdaptor. Please refer the below code example. 

Please refer the below documentations for more details. 



import { Component, ViewChild, ViewEncapsulation, OnInit, Inject } from '@angular/core'; 
import { DataManager, WebApiAdaptor, Query, DataUtil } from '@syncfusion/ej2-data'; 
import { TreeGridComponent } from '@syncfusion/ej2-angular-treegrid'; 
 
 
let primaryKey: any; 
 
let selectedRecord: any; 
 
@Component({ 
    selector: 'fetchdata', 
    templateUrl: './fetchdata.component.html', 
    encapsulation: ViewEncapsulation.Emulated 
}) 
 
export class FetchDataComponent { 
    public data: any; 
    public toolbarOptions: string[] | undefined; 
    public editSettings: Object | undefined; 
    @ViewChild('treegrid') 
    public treegrid: TreeGridComponent; 
 
    ngOnInit(): void { 
 
        this.editSettings = { allowEditing: true, allowAdding: true, allowDeleting: true, mode: "Row", newRowPosition:"Below" }; 
        this.toolbarOptions = ['Add', 'Delete', 'Update', 'Cancel']; 
        this.data = new DataManager({ 
            url: 'api/SelfReferenceData', 
            adaptor: new CustomAdaptor() 
        }); 
    } 
 
    actionBegin(args: any): void { 
        if (args.requestType == "save" && args.action == "add") { 
            primaryKey = selectedRecord.TaskID; 
        } 
    } 
 
    rowSelected(args: any): void { 
        selectedRecord = args.data; 
    } 
     
 
}                    
 
//////   Extending the WebApiAdaptor and overriding the insert method. 
 
class CustomAdaptor extends WebApiAdaptor { 
    public insert(dm: DataManager, data: Object, tableName?: string): Object { 
        dm.dataSource.url = dm.dataSource.url + "?$key=" + primaryKey   ////  sending the primary key of selected record in query string 
        return {  
            type: 'POST', 
            url: dm.dataSource.url, 
            data: JSON.stringify(data),            
        }; 
    } 
 
} 
 

[Controller.cs] 


[HttpPost] 
        public object Post([FromBody]SelfReferenceData value) 
        { 
            var queryString = Request.Query; 
            StringValues keys; 
            queryString.TryGetValue("$key", out keys);   /// retrieving the key value from querystring 
            int key = Int32.Parse(keys[0]);     
            SelfReferenceData.tree.Insert(0, value); 
            var data = SelfReferenceData.tree.ToList(); 
            return Json(new { result = data, count = data.Count }); 
        } 



If you need any  further assistance please get back to us. We will be happy to assist you. 

Regards, 
Sathyanarayanamoorthy 



DR Dayakar Reddy November 16, 2019 01:50 PM UTC

Hi Sathyanarayanamoorthy ,

Thank you, your code helped me alot. it solved me my issue. but i am facing below issue after adding new record 

but after adding child record under parent node, all parent nodes gets collapsed, how to prevent this and i want the treegrid to be in whatever the state it was with newly added child record.




DR Dinesh Rajendiran Syncfusion Team November 19, 2019 01:03 PM UTC

Hi Dayakar, 
  
To edit the records in the expanded state set loadChildOnDemand property as true. Please find the code snippet below. 
  
fetchdata.Component.html 
  
<ejs-treegrid #treegrid [dataSource]='data' [allowPaging]="true" [loadChildOnDemand] ="true" hasChildMapping="isParent" [toolbar]='toolbarOptions' [treeColumnIndex]='1' height='270' [editSettings]='editSettings' idMapping='TaskID' parentIdMapping='ParentIDs' (actionBegin)='actionBegin($event)' (rowSelected)='rowSelected($event)'> 
  
We have expanded child records while rendering by handling all the child records with current page data of TreeGrid at the server side . Please refer the code snippet below. 
  
OrdersController.cs 
  
public object Get() 
        { 
            . . . . . . . . . . . . . . . . . .  
  
            if (queryString.Keys.Contains("$inlinecount")) 
            { 
                StringValues Skip; 
                StringValues Take; 
                int skip = (queryString.TryGetValue("$skip", out Skip)) ? Convert.ToInt32(Skip[0]) : 0; 
                int top = (queryString.TryGetValue("$top", out Take)) ? Convert.ToInt32(Take[0]) : data.Count(); 
                data = data.Skip(skip).Take(top); 
                data = CollectChildRecords(data, queryString); 
                return new { result = data, count = count }; 
                 
            } 
            else 
            { 
                return SelfReferenceData.GetTree(); 
            } 
        } 
  
  
public IEnumerable<SelfReferenceData> CollectChildRecords(IEnumerable<SelfReferenceData> DataSource, IQueryCollection Queries) 
        { 
            StringValues IdMapping; 
            Queries.TryGetValue("IdMapping", out IdMapping); 
            int[] TaskIds = new int[0]; 
            foreach (var rec in DataSource) 
            { 
                int taskid = (int)rec.GetType().GetProperty(IdMapping).GetValue(rec); 
                TaskIds = TaskIds.Concat(new int[] { taskid }).ToArray(); 
            } 
            IEnumerable<SelfReferenceData> ChildRecords = null; 
            foreach (int id in TaskIds) 
            { 
                IEnumerable<SelfReferenceData> records = SelfReferenceData.tree.Where(ds => ds.ParentIDs == id); 
                ChildRecords = ChildRecords == null || (ChildRecords.AsQueryable().Count() == 0) ? records : ((IEnumerable<SelfReferenceData>)ChildRecords).Concat((IEnumerable<SelfReferenceData>)records); 
            } 
            if (ChildRecords != null && ChildRecords.Count() > 0) 
            { 
                ChildRecords = CollectChildRecords(ChildRecords, Queries); 
                
                DataSource = ((IEnumerable<SelfReferenceData>)DataSource).Concat((IEnumerable<SelfReferenceData>)ChildRecords); 
            } 
  
  
            return DataSource; 
        } 
 
Also We have made changes in the Custom Adaptor for selecting the record and pass its primary key value as additional parameter. Please find the updated code below. 
  
fetchdata.Component.ts 
  
class CustomAdaptor extends WebApiAdaptor { 
    public insert(dm: DataManager, data: object, tableName?: string): Object { 
        var returnValue = super.insert(dm, data, tableName); 
        setValue("url", dm.dataSource.url + "?$key=" + primaryKey, returnValue); 
        return returnValue; 
    } 
  
} 
  
OrdersController.cs 
  
   public object Post([FromBody]SelfReferenceData value) 
        { 
            var queryString = Request.Query; 
            StringValues keys; 
            queryString.TryGetValue("$key", out keys);   /// retrieving the key value from querystring  
            int index; 
            Int32.TryParse(keys[0],out index); 
            var i = 0; 
            for (; i < SelfReferenceData.tree.Count; i++) 
            { 
                if (SelfReferenceData.tree[i].TaskID == index) 
                { 
                    break; 
                } 
            } 
            i += FindChildRecords(index); 
            SelfReferenceData.tree.Insert(i+1, value); 
            var data = SelfReferenceData.tree.ToList(); 
            return Json(new { result = data, count = data.Count }); 
        } 
        public int FindChildRecords(int? id) 
        { 
            var count = 0; 
            for (var i = 0; i < SelfReferenceData.tree.Count; i++) 
            { 
                if (SelfReferenceData.tree[i].ParentIDs == id) 
                { 
                    count++; 
                    count += FindChildRecords(SelfReferenceData.tree[i].TaskID); 
                } 
            } 
            return count; 
        } 
  
For your convenience we have included a sample. Please refer the link below. 
  
  
If you need further assistance please get back to us. 
  
Regards, 
Dinesh Rajendiran 


Loader.
Live Chat Icon For mobile
Up arrow icon