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
close icon

Dynamically add <ejs-treeview> component

Hello,

For my need, i have to dynamically add <ejs-treeview> component in a custom colum also dynamically added in the scheduler in order to drag&drop external items.

I'm using the angular ComponentFactoryResolver:

import { TreeViewComponent, DragAndDropEventArgs, TreeViewModel, TreeView } from '@syncfusion/ej2-angular-navigations';
...

const componentFactory = this._cfr.resolveComponentFactory(TreeViewComponent);
const componentRef = componentFactory.create(this.injector);

componentRef.instance.allowDragAndDrop = true;
componentRef.instance.cssClass = 'treeview-external-drag';
componentRef.instance.fields = this.fields;

this._appRef.attachView(componentRef.hostView);
const domElem = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
...appendChild(domElem);


It's working fine and the component is created with his bloc correspoinding to items in fields. But the problem is that these blocs are empty..

It's because i have to add <ng-template> in the component as in this example from external drag&drop:

<ejs-treeview #treeObj [fields]='field' cssClass='treeview-external-drag' [allowDragAndDrop]='allowDragAndDrop' (nodeDragStop)="onTreeDragStop($event)" (nodeDragging)="onItemDrag($event)">
<ng-template #nodeTemplate="" let-data="">
<div id="waiting">
<div id="waitdetails">
<div id="waitlist">{{data.Name}}</div>
<div id="waitcategory">{{data.DepartmentName}} - {{data.Description}}</div>
</div>
</div>
</ng-template>
</ejs-treeview>

But i don't know how ?? i've tried this but not seems to work..

componentRef.instance.nodeTemplate(divWaiting);
OR
componentRef.instance.appendTo(divWaiting);

Here is the result i'd like to obtain (with text inside of the empty blocs):



Thanks for your help !

12 Replies

NR Nevitha Ravi Syncfusion Team September 2, 2019 07:56 AM UTC

Hi Chevron, 

Greetings from Syncfusion Support. 

We have shared a sample for external drag and drop in which template has been used for treeview component which can be available from the following link. 

Kindly share more details whether you have used treeview component within resource header template or try to reproduce the issue in a sample to check the issue at our end. 

Regards, 
Nevitha 



CH chevron September 2, 2019 08:41 AM UTC

Hi,

Thanks for you answer, but i'm already aware of the example that you gave me (it's the same one from which i'm inspired) 

Now what i want is to DYNAMICALLY generate it because i can't write it directly in the hml page.

I thought that my first post was enough clear with code samples.

Below is another samples of what i'd like to do :

GENERATED RESULT IN HTML (green part is OKAY, red part is the question asking currently in this post):

<ejs-treeview #treeObj [fields]='lstItvDisplay' cssClass='treeview-external-drag' [allowDragAndDrop]='allowDragAndDrop' (nodeDragStop)="onTreeDragStop($event)" (nodeDragStart)="onItemDragStart($event)">

        <ng-template #nodeTemplate="" let-data="">

        <div id="waiting">

            <div id="waitdetails">

                <div id="waitlist">{{data.Id}}</div>

                <div id="waitcategory">{{data.Libelle}} - {{data.Statut}}</div>

            </div>

        </div>   

        </ng-template>

  </ejs-treeview>


DYNAMICALLY CODE WHICH GENERATE HTML ABOVE

// CREATING TREEVIEW

const componentFactory = this._cfr.resolveComponentFactory(TreeViewComponent);

 const componentRef = componentFactory.create(this.injector);

componentRef.instance.allowDragAndDrop = true;

componentRef.instance.cssClass = 'treeview-external-drag treeview-generated';

componentRef.instance.NG-TEMPLATE( ?????

const domElem = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;

// PART I DON’T KNOW HOW TO IMPLEMENT : ????????

// Integration of treeview in the page

….appendChild(domElem);


Hope it's enough clear this time and that you could help me ?

Thanks anyway.



VM Vengatesh Maniraj Syncfusion Team September 3, 2019 01:51 PM UTC

Hi Chevron, 
  
We have prepared the sample based on your requirement which is available in below link 
 
 
Kindly check the above sample and revert us if you have any further assistance. 
 
Regards, 
Vengatesh 



CH chevron September 3, 2019 03:56 PM UTC

That still not answer my request...

I think however that my description can not be more explicit..

If it's not possible tell it to me rather than giving an innapropriate answer !


VM Vengatesh Maniraj Syncfusion Team September 4, 2019 03:44 PM UTC

Hi Chevron, 
  
We have prepared a sample for loading Treeview in a button click based on the code snippet shared. To render TreeView via nodeTemplate dynamically, we can use string template instead of ng-template. Please refer to the following code snippet 
public  NodeTemplate = "<div id='Waiting'><div id='waitdetails'><div id='waitlist'>${Name}</div><div id='waitcategory'>${DepartmentName}-${Description}</div></div></div>"; 

  
createComponent() { 
        this.entry.clear(); 
        const factory = this.resolver.resolveComponentFactory(TreeViewComponent); 
        this.componentRef = this.entry.createComponent(factory); 
        this.componentRef.instance.allowDragAndDrop = true; 
        this.componentRef.instance.cssClass = 'treeview-external-drag'; 
        this.componentRef.instance.fields = this.field 
       this.componentRef.instance.nodeTemplate = this.NodeTemplate 
    } 


  
 
Kindly check the above sample and revert us if you have any queries.  
  
Regards, 
Vengatesh 



CH chevron September 5, 2019 07:52 AM UTC

Hello Vengatesh,

Thanks a lot !!

It's exactly what i wanted :)


CH chevron September 5, 2019 01:55 PM UTC

I still have another question about generated element when creating treeview Dynamically.

As in the example below, i'd like to have different classe's name fo each of the <li> element, in order to apply different style for each of them :





Is it possible ?

Thanks by advance !




VM Vengatesh Maniraj Syncfusion Team September 6, 2019 03:14 PM UTC

Hi Chevron,  
  
Thanks for the update. 
 
You can achieve this requirement in the drawNode event of treeview. But it is not recommended to overwrite the e-fullrow  class name. if you do so, the style would not be applied to the corresponding elements. Instead of this, you can add a custom class for each  li  in the drawNode event using the following code snippet. 
  
this.componentRef.instance.drawNode.subscribe(evt => {
let newClass = 'myClass' + '-' + this.count;
evt.node.classList.add(newClass)
this.count = this.count + 1;
});
  
CSS  
  
.treeview-external-drag .myClass-1 .e-list-text
{
background: greenyellow;
border: 0.5px solid #E1E7EC;
height: 50px;
line-height: 15px;
padding: 0 5px;
width: 220px;
}

.treeview-external-drag .myClass-2 .e-list-text
{
background: pink;
border: 0.5px solid #E1E7EC;
height: 50px;
line-height: 15px;
padding: 0 5px;
width: 220px;
}
  

Kindly check the above sample and revert us for further assistance. 

Regards, 
Vengatesh 



CH chevron September 11, 2019 01:14 PM UTC

Thanks again for your answer !

I have still another question, it's about modifying [fields] of the treeview once it's generated.

Based on your example, i've tried this, but not seems to work :

HTML Part:
</template>
<button (click)="createComponent()">Click me to load TreeView</button>
<button (click)="modifyComponent()">Click me to modify TreeView</button> // ADDED


TS Part:
modifyComponent() {
this.field = { dataSource: this.hierarchicalData2, id: 'id', text: 'name', child: 'subChild' };
}

public hierarchicalData2: Object[] = [
{
Id: 1,
Name: 'Steven2',
StartTime: new Date(2018, 8, 3, 7, 30),
EndTime: new Date(2018, 8, 3, 9, 30),
Description: 'Consulting',
DepartmentName: 'GENERAL'
}
];



The result (after click on modifyComponent) should be:



Have you got an idea ?


AB Ashokkumar Balasubramanian Syncfusion Team September 12, 2019 09:21 AM UTC

Hi Chevron, 
 
We have checked the code snippet shared. In that, you have set the modified dataSource for the private variable field instead of the Treeview component’s fields. So that while changing the data source the changes are not updated. We have modified the code snippet as required. Please refer to the below. 
 
modifyComponent() { 
        this.componentRef.instance.fields = { dataSource: this.hierarchicalData2, id: 'id', text: 'name', child: 'subChild' }; 
    } 
 
 
Note: Could you please ensure whether all the mapping fields(id,text,child) are properly mapped in fields property of TreeView component?  
 
Kindly check the above sample and get back to us if you need any further assistance. 
 
Regards, 
Ashokkumar B. 



CH chevron October 17, 2019 03:49 PM UTC

Hello,

I'd like to know how to catch the click event on the arrow Group/Project (the one that collapse group), as in this image, is it possible ? Thanks !




KM Kanagambigai Murugan Syncfusion Team October 18, 2019 05:49 AM UTC

Hi Chevron, 

Thanks for the update. 

We have validated your requirement. You can achieve this either in the nodeClicked event or in nodeExpanded/nodeCollapsed event of the TreeView component. 

You can use the following code snippet for the nodeClicked event. 

 // Triggers when node is clicked 
    onClick(args){ 
      var icon = args.event.target; 
      if(icon.classList.contains('e-icon-expandable')){ 
         alert("Node collapsed") 
      } 
         else if(icon.classList.contains('e-icon-collapsible')){ 
        alert("Node Expanded") 
      } 
    } 



You can use the following code snippet for the nodeExpanded/nodeCollapsed event. 

// Triggers when node is Expanded 
    onExpand(args){ 
      alert("NodeExpanded"); 
    } 
 
    //Triggers when node is collapsed 
    onCollapse(args){ 
      alert("NodeCollapsed"); 
    } 



Please check the above samples and get back to us if you need any further assistance. 

Regards, 
Kanagambigai M. 


Loader.
Live Chat Icon For mobile
Up arrow icon