Search code examples
angulartwitter-bootstraptypescriptng-bootstrap

trigger ng-bootstrap accordion component with typescript(javascript)?


Im using ng-bootstrap framework in my Angular 4 project.

I have 'accordion' components in multiple places in my application and in some cases I need to trigger accordion open state in typescript.

From the accordion component API documentation I found following method, but as far as I have tried it only works when called in html file (tried calling from constructor).

//Programmatically toggle a panel with a given id.
toggle(panelId: string) => void

Should it also be possible to trigger in typescript? If anybody has experience with it I would be really thankful. Otherwise I need to build my own custom accordions.


Solution

  • For this you have to use ViewChild strong typed with NgbAccordion component.

    You can do same thing with any components of ng-boostrap and any public method of any child Component.

    Step to follow :

    1/ add #someIdentifier to your component tag in html side.

    2/ Use @ViewChild('someIdentifier') to make reference on your component.ts

    3/ StrongCast your attribute by the ComponentType.

    4/ Enjoy any public method from your Child Component.

    Following example :

    import {Component, ViewChild} from '@angular/core';
    import {NgbAccordion} from '@ng-bootstrap/ng-bootstrap';
    @Component({
      selector: 'ngbd-accordion-toggle',
      templateUrl: './accordion-toggle.html'
    })
    export class NgbdAccordionToggle {
      @ViewChild('acc') accordionComponent: NgbAccordion;
    
      // Method call on click.
      toggle(id:string): void {
      //Here you have access to AccordionComponent as discribe on documentation.    
        this.accordionComponent.toggle(id);
      }
    }
    

    Html side :

    <ngb-accordion #acc="ngbAccordion">
    // [...]
    </ngb-accordion>
    

    Live example : https://stackblitz.com/edit/angular-szhpdw?file=app%2Faccordion-toggle.ts


    Since version 14.1.0 of this library, API have moved from component to directive. Approach is almost the same.

    import { Component, ViewChild } from '@angular/core';
    import {
      NgbAccordionModule,
      NgbAccordionDirective,
    } from '@ng-bootstrap/ng-bootstrap';
    
    @Component({
      selector: 'ngbd-accordion-basic',
      standalone: true,
      imports: [NgbAccordionModule],
      templateUrl: './accordion-basic.html',
    })
    export class NgbdAccordionBasic {
      @ViewChild(NgbAccordionDirective) accordion: NgbAccordionDirective; // here we create the reference to the directive
    
      public toggle(i: number): void {
        this.accordion.toggle(i.toString());
      }
    }
    

    and them on your html template

    <div ngbAccordion accordion="NgbAccordion">
        <div ngbAccordionItem="0">
        </div>
        <div ngbAccordionItem="1">
        </div>
    </div>
    

    Where you link your ViewChild by using accordion="NgbAccordion" And you name your Accordion item by giving as input.

    Live example : https://stackblitz.com/edit/angular-dmtgkh API Reference : https://ng-bootstrap.github.io/#/components/accordion/overview