简体   繁体   中英

Target Bootstrap HTML element with data-bs-target from another element in Angular

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM