In my quest to develop an intricate breadcrumbs system paired with dropdown navigation, I've encountered a challenge:
https://i.sstatic.net/RZUDr.png
The issue revolves around handling outside clicks: specifically, closing dropdowns when clicking outside the element. However, if another navigation item is clicked, it should remain open as only one breadcrumb is active at a time.
My approach involves:
1) Detecting outside clicks by containing an event target within the parent element
2) Switching occurs by closing all breadcrumbs and opening the required one.
View a simple example of the breadcrumbs on Plunker here
Template:
<ul #simpleBreadcrumbs>
<li *ngFor="let breadcrumb of breadcrumbs"
class="bread_item"
(click)="toggleStateOfSubparagraphs(breadcrumb)">
<div>
<span>{{breadcrumb.label}}</span>
<i class="icon-arrows-glyph-1_bold-down"
*ngIf="!breadcrumb.isOpen"></i>
<i class="icon-arrows-glyph-1_bold-up"
*ngIf="breadcrumb.isOpen"></i>
</div>
<ul class="switcher__list dropdown__list"
*ngIf="breadcrumb.isOpen">
<li class="switcher__item dropdown__item" *ngFor="let subparagraph of breadcrumb.subparagraphs">
<a class="switcher__item-href">{{subparagraph.label}}</a>
</li>
</ul>
</li>
</ul>
Component Class:
export class App {
breadcrumbs:any[];
@ViewChild('simpleBreadcrumbs') private _breadcrumbsTemplate: ElementRef;
_currentOpenedBreadcrumb:any;
constructor() {
this.breadcrumbs = [
{
label: 'First',
isOpen: false,
subparagraphs: [
{label: '1.1'},
{label: '1.2'}
]
},
{
label: 'Second',
isOpen: false,
subparagraphs: [
{label: '2.1'},
{label: '2.2'}
]
}
];
}
toggleStateOfSubparagraphs(breadcrumb) {
if (this._currentOpenedBreadcrumb === breadcrumb) {
this._closeSubparagraphs();
this._currentOpenedBreadcrumb = null;
return;
}
this.breadcrumbs.forEach((bread: IBreadcrumb) => {
bread.isOpen = false;
if (bread === breadcrumb) {
bread.isOpen = true;
}
});
this._currentOpenedBreadcrumb = breadcrumb;
}
_closeSubparagraphs() {
this.breadcrumbs.map((bread) => {
bread.isOpen = false;
return bread;
});
}
@HostListener('window:keydown', ['$event'])
public onEscapeClick(event: KeyboardEvent): void {
if (event.which === 27 && !this._breadcrumbsTemplate.nativeElement.contains(event.target as Node)) {
this._closeSubparagraphs();
}
}
@HostListener('document:click', ['$event'])
public onOutsideClick(event: Event): void {
if (!this._breadcrumbsTemplate.nativeElement.contains(event.target as Node)) {
this._closeSubparagraphs();
}
}
}