LIDOR SYSTEMS

Advanced User Interface Controls and Components

Prevent Expand/Collapse of Items in Angular TreeView

Created: 15 Nov 2017

By default, all items in IntegralUI TreeView component for Angular are expandable and collapsible. Although you can initially set, which items are expanded, in some cases you may need to prevent expanding or collapsing of specific items.

TreeView component is part of IntegralUI Web
a suite of UI Components for development of web apps

If you have any questions, don't hesitate to contact us at support@lidorsystems.com

In this example, we have two items that are locked. One is expanded and locked, while the other is collapsed and locked. For visual representation, a lock icon on item right side is used.

How to Lock Items and Prevent them from Expanding or Collapsing

Initially, if a value to the expanded field of item object is not specified, it is presumed that the item is expanded. If you want to set some items as collapsed when TreeView is populated for the first time, just set the item object expanded value to false.

private items: Array;
private hoverItem: any = null;

private ctrlStyle: any = {
    general: {
        normal: 'treeview-pec-normal'
    }
}

constructor(){
    this.items = [
        { id: 1, text: "Solution 'Application1' (1 project)", icon: "project-icons solution" },
        { 
            id: 2,
            text: "Application1",
            icon: "project-icons documents",
            items: [
                { 
                    id: 21,
                    pid: 2,
                    text: "Properties",
                    icon: "project-icons properties",
                    locked: true,
                    items: [
                        { id: 211, pid: 21, text: "AssemblyInfo.cs", icon: "project-icons assembly" },
                        { id: 212, pid: 21, text: "licenses.licx", icon: "project-icons notes" },
                        { 
                            id: 213,
                            pid: 21,
                            text: "Resources.resx",
                            expanded: false,
                            icon: "project-icons resources",
                            items: [
                                { id: 2131, pid: 213, text: "Resources.Designer.cs" }
                            ]
                        },
                        { 
                            id: 214,
                            pid: 21,
                            text: "Settings.settings",
                            icon: "project-icons documents",  
                            expanded: false,
                            items: [
                                { id: 2141, pid: 214, text: "Settings.Designer.cs", checkState: 'checked' }
                            ]
                        }
                    ]
                },
                { 
                    id: 22,
                    pid: 2,
                    text: "References",
                    icon: "project-icons references",  
                    expanded: false,
                    locked: true,
                    items: [
                        { id: 221, pid: 22, text: "System" },
                        { id: 222, pid: 22, text: "System.Data" },
                        { id: 223, pid: 22, text: "System.Deployment" },
                        { id: 224, pid: 22, text: "System.Drawing" },
                        { id: 225, pid: 22, text: "System.Xml" }
                    ]
                },
                { 
                    id: 23,
                    pid: 2,
                    text: "Form1.cs",
                    icon: "project-icons form",
                    items: [
                        { id: 231, pid: 23, text: "Form1.Designer.cs" },
                        { id: 232, pid: 23, text: "Form1.resx", checkState: 'checked' }
                    ]
                },
                { id: 24, pid: 2, text: "Program.cs", icon: "project-icons new" }
            ]
        }
    ];

}                             
<iui-treeview [items]="items" [controlStyle]="ctrlStyle">
    <ng-template let-item>
        <div (mouseenter)="hoverItem=item" (mouseleave)="hoverItem=null">
            <span [ngClass]="item.icon"></span>
            <span class="treeview-pec-item-content">{{item.text}}</span>
            <div class="treeview-pec-toolbar" *ngIf="item.locked || item==hoverItem">
                <span class="treeview-pec-item-button treeview-pec-item-button-lock" [ngClass]="{ 'treeview-pec-item-button-lock': item.locked, 'treeview-pec-item-button-unlock': !item.locked && item.items && item.items.length > 0 }" (click)="lock(item)"></span>
            </div>
        </div>
    </ng-template>
</iui-treeview>      
.treeview-pec-normal
{
    width: 400px;
    height: 400px;
}
.treeview-pec-normal .iui-treeitem-content
{
    margin: 1px 0 !important;
    padding: 5px !important;
}
.treeview-pec-normal .iui-treeitem-expand-box
{
    margin-top: 4px !important;
}
.project-icons
{
    background-image: url(app/integralui/resources/project.png);
    background-repeat: no-repeat;
    display: inline-block;
    overflow: hidden;
    padding: 0 !important;
    margin: 0 2px 0 0;
    width: 24px;
    height: 24px;
}
.empty
{
    background-position: 0px 0px;
}
.solution
{
    background-position: -24px 0px;
}
.documents
{
    background-position: -48px 0px;
}
.references
{
    background-position: -72px 0px;
}
.notes
{
    background-position: -96px 0px;
}
.assembly
{
    background-position: -120px 0px;
}
.resources
{
    background-position: -144px 0px;
}
.properties
{
    background-position: -168px 0px;
}
.new
{
    background-position: -192px 0px;
}
.form
{
    background-position: -216px 0px;
}
.empty-doc
{
    background-position: -240px 0px;
}
.treeview-pec-item-content
{
    display: inline-block;
    margin-top: 4px;
    vertical-align: top;
}                            

Now, when there is some data into the TreeView, to prevent or lock some item from expanding, you need to handle the beforeExpand event, set a condition and cancel the event. For example:

treeBeforeExpand(e: any){
    if (e.item && e.item.locked)
        e.cancel = true;
}                            
<iui-treeview [items]="items" [controlStyle]="ctrlStyle" (beforeExpand)="treeBeforeExpand($event)">
    <ng-template let-item>
        <div (mouseenter)="hoverItem=item" (mouseleave)="hoverItem=null">
            <span [ngClass]="item.icon"></span>
            <span class="treeview-pec-item-content">{{item.text}}</span>
            <div class="treeview-pec-toolbar" *ngIf="item.locked || item==hoverItem">
                <span class="treeview-pec-item-button treeview-pec-item-button-lock" [ngClass]="{ 'treeview-pec-item-button-lock': item.locked, 'treeview-pec-item-button-unlock': !item.locked && item.items && item.items.length > 0 }" (click)="lock(item)"></span>
            </div>
        </div>
    </ng-template>
</iui-treeview>
                          

In similar way, to prevent or lock some item from collapsing, you need to handle the beforeCollapse event, set a condition and cancel the event. For example:

treeBeforeCollapse(e: any){
    if (e.item && e.item.locked)
        e.cancel = true;
}                            
<iui-treeview [items]="items" [controlStyle]="ctrlStyle" (beforeCollapse)="treeBeforeCollapse($event)" (beforeExpand)="treeBeforeExpand($event)">
    <ng-template let-item>
        <div (mouseenter)="hoverItem=item" (mouseleave)="hoverItem=null">
            <span [ngClass]="item.icon"></span>
            <span class="treeview-pec-item-content">{{item.text}}</span>
            <div class="treeview-pec-toolbar" *ngIf="item.locked || item==hoverItem">
                <span class="treeview-pec-item-button treeview-pec-item-button-lock" [ngClass]="{ 'treeview-pec-item-button-lock': item.locked, 'treeview-pec-item-button-unlock': !item.locked && item.items && item.items.length > 0 }" (click)="lock(item)"></span>
            </div>
        </div>
    </ng-template>
</iui-treeview>
                          

For visual representation, to distinguish items that have expand or collapse disabled, a lock icon is used. You can position this icon anywhere within the item space; it is customizable within the item template. For this example, the lock icon is set on the right side.

lock(item: any){
    item.locked = item.locked != undefined ? !item.locked : true;
}
                             
<iui-treeview [items]="items" [controlStyle]="ctrlStyle" (beforeCollapse)="treeBeforeCollapse($event)" (beforeExpand)="treeBeforeExpand($event)">
    <ng-template let-item>
        <div (mouseenter)="hoverItem=item" (mouseleave)="hoverItem=null">
            <span [ngClass]="item.icon"></span>
            <span class="treeview-pec-item-content">{{item.text}}</span>
            <div class="treeview-pec-toolbar" *ngIf="item.locked || item==hoverItem">
                <span class="treeview-pec-item-button treeview-pec-item-button-lock" [ngClass]="{ 'treeview-pec-item-button-lock': item.locked, 'treeview-pec-item-button-unlock': !item.locked && item.items && item.items.length > 0 }" (click)="lock(item)"></span>
            </div>
        </div>
    </ng-template>
</iui-treeview>
                          
.treeview-pec-toolbar
{
    display: inline-block;
    position: absolute;
    right: 0;
    top: 7px;
    padding-left: 5px;
}
.treeview-pec-item-button
{
    background-image: url(app/integralui/resources/icons.png);
    background-repeat: no-repeat;
    display: inline-block;
    overflow: hidden;
    padding: 0;
    margin: 3px 4px 0 4px;
    width: 16px;
    height: 16px;
    float: right;
    opacity: 0.5;
}
.treeview-pec-item-button:hover
{
    opacity: 1;
}
.treeview-pec-item-button-lock
{
    background-position: -64px -112px;
}
.treeview-pec-item-button-unlock
{
    background-position: -80px -112px;
}
                            

Note When item is not locked, during hovering over item space, an unlock icon will appear for items with children.

Conclusion

You can disable or prevent items from expanding or collapsing in Angular TreeView, by handling an event that is fired before the expand or collapse process takes action. In your event handler, you only need to set a condition which when met will cancel the process.

The TreeView component is part of IntegralUI Web.

Did you Like this Article?


Enter your e-mail address below and you will receive latest articles as well as news on upcoming events and special offers.