Treegrid rows collapsed after adding or deleting a new record

Hi team,

I am adding a node to root node in treegrid, after adding it is getting collapsed and making a server call to fetch the data again. i want to add a node to root without making collapse and the data should be saved on server and it should not make a call to fetch all the records again.

same issue for deleting as well.

I am using   ej2-angular-treegrid 20.1.55 version, my code looks like below.

component code

  this.dataManager = new DataManager({
        url: `${this.systemService.getTagsApiUrl()}/me/project/${this.project.id}`,
        adaptor: new CustomAdaptor(),
        crossDomain: true,
        headers: [{ Authorization: 'Bearer ' + this.authService.getIdToken() }]
      });


class CustomAdaptor extends UrlAdaptor {
  // TODO collapsing issue still exists after inserting or deleting a tag, contacting syncfusion support to fix this issue
  public insert(dm: DataManager, data: any, tableName?: string): Object {
    let tagArtefact: Tag = ObjectCreator.create(tagSchema, tagSchema.metadata.objectKind, parentData.root, parentData.ancestry);
    tagArtefact = ArtefactActions.addArchivedProperties(tagArtefact);
    tagArtefact = ArtefactActions.addCategoryProperties(tagArtefact);
    tagArtefact = ArtefactActions.addCreatedProperties(tagArtefact);
    tagArtefact = ArtefactActions.addUpdatedProperties(tagArtefact);
    tagArtefact.metadata = [];
    tagArtefact.name = data.name ? data.name : '';
    tagArtefact.code = data.code ? data.code : '';
    tagArtefact.description = data.description ? data.description : '';

    return {
      type: 'POST',
      url: `${crudBaseUrl}/view/${parentData.root}/master/true`,
      data: JSON.stringify([tagArtefact]),
      headers: dm.dataSource.headers
    };
  }

  public update(dm: DataManager, keyField: string, value: any, tableName?: string): Object {
    const tagArtefact: Tag = value.taskData;
    tagArtefact.name = value.name ? value.name : '';
    tagArtefact.code = value.code ? value.code : '';
    tagArtefact.description = value.description ? value.description : '';

    return {
      type: 'POST',
      url: `${crudBaseUrl}/batch/view/${tagArtefact.root}`,
      data: JSON.stringify([tagArtefact]),
      headers: dm.dataSource.headers
    };
  }

  public remove(dm: DataManager, keyField: string, value: number, tableName?: string): Object {
    return {
      type: 'PUT',
      url: `${crudBaseUrl}/archive/kind/${parentData.kind}/children/true`,
      data: JSON.stringify([parentData.id]),
      headers: dm.dataSource.headers
    };
  }
}


html code

 <ejs-treegrid #treeGrid [dataSource]='dataManager' [height]='gridHeight()' [allowPaging]='true'
            [pageSettings]='pageSettings' [editSettings]='editSettings' [toolbar]='treeGridToolbar'
            (actionBegin)="actionBegin($event)" (actionFailure)="onActionFailure($event)"
            (actionComplete)="actionComplete($event)" (rowSelected)="rowSelected($event)"
            (rowDeselected)="rowDeselected($event)" (expanded)="rowExpanded($event)" [treeColumnIndex]='1'
            idMapping='id' parentIdMapping='root' hasChildMapping='hasChildren' [contextMenuItems]='items'
            (contextMenuClick)='contextMenuClick($event)' (contextMenuOpen)='contextMenuOpen($event)'
            (load)='treeGridLoad($event)'>
            <e-columns>
              <e-column field='id' isPrimaryKey='true' [visible]='false' headerText='id'>
              </e-column>
              <e-column field='code' headerText='Code' width='200' clipMode="EllipsisWithTooltip">
                <ng-template #template let-rowData>
                  <span>
                    <i aria-hidden="true" class="fas fa-tags" *ngIf="rowData.kind==='tag'"></i>{{rowData.code}}
                  </span>
                </ng-template>
              </e-column>
              <e-column field='name' headerText='Name' width='200' clipMode="EllipsisWithTooltip"></e-column>
            </e-columns>
          </ejs-treegrid>

4 Replies

DR Dayakar Reddy September 13, 2022 06:20 AM UTC

And also even if i set LoadChildOnDemand="false" to the treegrid, it is making service call to the server when node is expanding,  ej2-angular-treegrid 20.1.55 version




PS Pon Selva Jeganathan Syncfusion Team September 13, 2022 04:54 PM UTC


Hi Dayakar


Thanks for contacting syncfusion forum.


Query:  i want to add a node to root without making collapse and the data should be saved on server and it should not make a call to fetch all the records again.


Using remoteData to TreeGrid, by default Tree Grid parent rows have been rendered with collapsed state.  After editing a row/cell, the parent row goes to the collapsed state event though you are expanding the record, which is the default behaviour. If you want to Tree Grid parent rows have been rendered with expanded state after editing a row, we suggest you use the LoadChildOnDemand property.  


Using LoadChildOnDemand you need to handle the children on server end.


Please check the below code snippet,

   <ejs-treegrid #treegrid [dataSource]='data' [editSettings]='editSettings' loadChildOnDemand="true" hasChildMapping='isParent' [toolbar]='toolbar' idMapping='TaskID' parentIdMapping='ParentID' (actionBegin)="Begin($event)" [treeColumnIndex]='1'>

  <e-columns>

    <e-column field='TaskID' headerText='Task ID' isPrimaryKey=true width='150'></e-column>

    <e-column field='TaskName' headerText='Task Name' width='150'></e-column>

    <e-column field='Duration' headerText='Duration' width='150' textAlign='Right'></e-column>

    <e-column field='Progress' headerText='Progress' width='150' textAlign='Right'></e-column>

  </e-columns>

</ejs-treegrid>

 

 

 

……..

 

 

ngOnInit(): void {

    this.data = new DataManager({

      url: "api/Tasks/DataSource",

      insertUrl: "api/Tasks/Insert",

      updateUrl: "api/Tasks/Update",

      removeUrl: "api/Tasks/Delete",

….})

 

public IActionResult DataSource([FromBody] DataManagerRequest dm)

        {

            IEnumerable DataSource = TreeData.GetSelfData();

            ….

            var count = TreeData.GetSelfData().Count();

            if (dm.Skip != 0)

            {

                DataSource = operation.PerformSkip(DataSource, dm.Skip);   //Paging

            }

            if (dm.Take != 0)

            {

                DataSource = operation.PerformTake(DataSource, dm.Take);

            }

            if (dm.Where != null)

            {

                DataSource = CollectChildRecords(DataSource, dm);   // method to collect child record

            }

 

            return dm.RequiresCounts ? Json(new { result = DataSource, count = count }) : Json(DataSource);

 

        }

        public IEnumerable CollectChildRecords(IEnumerable datasource, DataManagerRequest dm)

        {

            DataOperations operation = new DataOperations();

            IEnumerable DataSource = TreeData.GetSelfData();   // use the total DataSource here 

            string IdMapping = "TaskId";// define your IdMapping field name here 

            int[] Ids = new int[0];

            foreach (var rec in datasource)

            {

                int ID = (int)rec.GetType().GetProperty(IdMapping).GetValue(rec);

                Ids = Ids.Concat(new int[] { ID }).ToArray();

            }

            IEnumerable ChildRecords = null;

            foreach (int id in Ids)

            {

                dm.Where[0].value = id;

                IEnumerable records = operation.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator);

                ChildRecords = ChildRecords == null || (ChildRecords.AsQueryable().Count() == 0) ? records :

                 ((IEnumerable<object>)ChildRecords).Concat((IEnumerable<object>)records);

            }

            if (ChildRecords != null)

            {

                ChildRecords = CollectChildRecords(ChildRecords, dm);

                if (dm.Sorted != null && dm.Sorted.Count > 0)

                {

                    ChildRecords = operation.PerformSorting(ChildRecords, dm.Sorted);

                }

                datasource = ((IEnumerable<object>)datasource).Concat((IEnumerable<object>)ChildRecords);

            }

            return datasource;

        }

……

 

//For CRUD action

 [HttpPost]

 

        [Route("Update")]

        public ActionResult Update([FromBody] CRUDModel value)

        {

           var val = TreeData.tree.Where(ds => ds.TaskID == value.value.TaskID).FirstOrDefault();

           val.TaskName = value.value.TaskName;

           val.StartDate = value.value.StartDate;

           val.Duration = value.value.Duration;

           val.Priority = value.value.Priority;

           val.Progress = value.value.Progress;

           return Json(new { result=val });

        }

        insert the record

        [HttpPost]

 

        [Route("Insert")]

        public void Insert([FromBody] CRUDModel value)

        {

            TreeData.GetTree().Insert(0, value.value);

        }

 

        //Delete the record

        [HttpPost]

 

        [Route("Delete")]

        public Object Delete([FromBody] CRUDModel value)

        {

            TreeData.tree.Remove(TreeData.tree.Where(or => or.TaskID.Equals(value.key)).FirstOrDefault());

            return Json(value);

        }

 

 

       



Please refer to the below documentation for loadchildondemand,  

https://ej2.syncfusion.com/angular/documentation/treegrid/data-binding/remote-data/#loadchildondemand


Please refer to the below API documentation:

https://ej2.syncfusion.com/javascript/documentation/api/treegrid#loadchildondemand


Query: And also even if i set LoadChildOnDemand="false" to the treegrid, it is making service call to the server when node is expanding


Using remoteData to TreeGrid, by default Tree Grid parent rows have been rendered with collapsed stateWhen a root node is expanded, its child nodes are rendered and are cached locally, such that on consecutive expand/collapse actions on root node, the child nodes are loaded from the cache instead from the remote server


Please refer to the below documentation,

https://ej2.syncfusion.com/angular/documentation/treegrid/data-binding/remote-data/


Kindly get back to us for further assistance.


Regards,

Pon selva




DR Dayakar Reddy September 14, 2022 01:47 AM UTC

Thank you for the reply,


i set the loadChildOnDemand="true", still when i add a new node to parent node, tree grid collapsing after adding.

please find the attached recording.


  <ejs-treegrid #treeGrid [dataSource]='dataManager' [height]='gridHeight()' [allowPaging]='true'
            [pageSettings]='pageSettings' [editSettings]='editSettings' [toolbar]='treeGridToolbar'
            LoadChildOnDemand="true" (actionBegin)="actionBegin($event)" (actionFailure)="onActionFailure($event)"
            (actionComplete)="actionComplete($event)" (rowSelected)="rowSelected($event)"
            (rowDeselected)="rowDeselected($event)" (dataBound)="dataBound($event)" (collapsed)="collapsed($event)"
            (expanded)="rowExpanded($event)" [treeColumnIndex]='1' idMapping='id' parentIdMapping='root'
            hasChildMapping='hasChildren' [contextMenuItems]='items' (contextMenuClick)='contextMenuClick($event)'
            (contextMenuOpen)='contextMenuOpen($event)' (load)='treeGridLoad($event)'>
            <e-columns>
              <e-column field='id' isPrimaryKey='true' [visible]='false' headerText='id'>
              </e-column>
              <e-column field='code' headerText='Code' width='200' clipMode="EllipsisWithTooltip">
                <ng-template #template let-rowData>
                  <span>
                    <i aria-hidden="true" class="fas fa-tags" *ngIf="rowData.kind==='tag'"></i>{{rowData.code}}
                  </span>
                </ng-template>
              </e-column>
              <e-column field='name' headerText='Name' width='200' clipMode="EllipsisWithTooltip"></e-column>
            </e-columns>
          </ejs-treegrid>


 this.dataManager = new DataManager({
        url: `${this.systemService.getTagsApiUrl()}/me/project/${this.project.id}`,
        adaptor: new CustomAdaptor(),
        crossDomain: true,
        headers: [{ Authorization: 'Bearer ' + this.authService.getIdToken() }]
      });

Attachment: screencapture_8a704e6e.rar


PS Pon Selva Jeganathan Syncfusion Team September 14, 2022 03:33 PM UTC

Hi Dayakar


Thanks for the update.


Query: i set the loadChildOnDemand="true", still when i add a new node to parent node, tree grid collapsing after adding.


We checked your query by preparing sample, but we were unable to replicate the issue at our end.


Please refer to the sample,

https://www.syncfusion.com/downloads/support/directtrac/general/ze/crud-datamanager_Mine_treregrid1670180512


Please refer to the below video demo,

https://www.syncfusion.com/downloads/support/directtrac/general/ze/Add_demo1107954767


After following the above solution still faced issue, share us the following details.


  1. Share the complete treegrid code example.
  2. Share the video demo of the issue(Previously shared video demo is not open properly)
  3. Share us the issue reproducible sample or reproduce the issue in the above sample.


 The provided information will be helpful to provide you response as early as possible. 



Kindly get back to us for further assistance.


Regards,

Pon selva





Loader.
Up arrow icon