I am trying to open a Bootstrap (5) Offcanvas menu from an icon click event in Angular 12. I have tried many methods including wrapping it in a button (this works with one icon but I have an <fa-stack></fa-stack>
element and this doesn't work for that for some reason), targeting the element id
of a hidden button such as below:
<button #menuOpen [hidden]="true" class="btn" data-bs-toggle="offcanvas" data-bs-target="#slide-out-menu"
type="button" aria-controls="slide-out-menu">
</button>
<fa-stack (click)="menuOpen.click()">
<fa-icon [icon]="faCircle" stackItemSize="2x"></fa-icon>
<fa-icon [icon]="icon" [inverse]="true" stackItemSize="1x"></fa-icon>
</fa-stack>
<div #slideOutMenu class="offcanvas offcanvas-end" id="slide-out-menu" aria-labelledby="menu-label">
<div class="offcanvas-header">
</div>
<div class="offcanvas-body">
</div>
</div>
and also adding an [ngClass]="{'show', showMenu}"
directive as well which doesn't work.
Is there a way to target this element and show it from a click event (not directly on the button)?
SOLUTION 1
If the hidden button and the <fa-stack>
element are in the same component, you can use ViewChild
to target the hidden button. And then use its nativeElement
to alter the DOM with Renderer2:
@Component({
selector: 'my-app',
template : `
<button #menuOpen [hidden]="true" class="btn" data-bs-toggle="offcanvas" data-bs-target="#slide-out-menu"
type="button" aria-controls="slide-out-menu">
</button>
<fa-stack (click)="toggleMenuButton()">
<fa-icon [icon]="faCircle" stackItemSize="2x"></fa-icon>
<fa-icon [icon]="icon" [inverse]="true" stackItemSize="1x"></fa-icon>
</fa-stack>
`
})
export class App {
@ViewChild('menuOpen') menuButton: ElementRef;
constructor(private renderer: Renderer2) { }
toggleMenuButton() {
// Add "show" CSS-class to button
this.renderer.addClass(this.menuButton.nativeElement, 'show');
// Remove "show" CSS-class from button
this.renderer.removeClass(this.menuButton.nativeElement, 'show');
// Add "hide" CSS-class to button
this.renderer.addClass(this.menuButton.nativeElement, 'hide');
// Remove "hide" CSS-class from button
this.renderer.removeClass(this.menuButton.nativeElement, 'hide');
}
}
SOLUTION 2
If they're not in the same component, you can alternatively achieve this by using the querySelector()
with pure javascript and search for an element with a certain attribute and value. So in your case, use this code to get a button
that has attribute data-bs-target
with value #slide-out-menu
:
var targetElement = document.querySelector("button[data-bs-target='#slide-out-menu']"); console.log(targetElement);
<button #menuOpen [hidden]="true" class="btn" data-bs-toggle="offcanvas" data-bs-target="#slide-out-menu" type="button" aria-controls="slide-out-menu"> I am the button </button>
And then alter the CSS or classes of the targetElement
const showMenu = () => {
targetElement.classList.add("show");
targetElement.classList.remove("hide");
}
const hideMenu = () => {
targetElement.classList.remove("show");
targetElement.classList.add("hide");
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.