Topic: Set mdb-accordion-item collapsed programatically

declan.ward premium asked 3 years ago


*Expected behavior*Accordion should open if there is only one item in the list.

*Actual behavior*Accordion remains collapsed

Resources (screenshots, code snippets etc.)

<mdb-accordion-item  [collapsed]="true" *ngFor="let item of itemsList">

Changing value of collapsed from "true" to "false" works as expected.

I need to bind this to the length of the list - itemsList.length > 1

This, in my template, - Len:{{docTypes.length>1}} shows a value of true or false, as expected.

Using mdb-accordion-item [collapsed]="[collapsed]", I set collapsed = "true" or "false", in code, based on the length of the list but the accordion seems to ignore this. Is it binding too late?

As a test I added a button to toggle the value:

<button type="button"  (click)="toggle()">Toggle</button>

collapsed: string = "false";

toggle(): void {
if (this.collapsed == "true"){
  this.collapsed = "false";
}
else {
  this.collapsed = "true";
}

}

Toggle() changes the value as expected but the list item does not open/close. What am I missing?


Bartosz Termena staff answered 3 years ago


Dear @declan.ward

You can access your items via ViewChildren in you TS file.

Sample: @ViewChildren('SBItemComponent') SBItemComponent: QueryList<SBItemComponent>;

Below is a full example:

  @ViewChildren('SBItemComponent') SBItemComponent: QueryList<SBItemComponent>;
  title = 'Accordion Test';
  collapsed = false;
  items: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
  toggle() {
    if (this.collapsed === true) {
      this.collapsed = false;
      console.log('Set to false');
    } else {
      this.collapsed = true;
      console.log('Set to true');
    }
    this.SBItemComponent.forEach((item, index) => {
      if (index === 1) {
        item.toggle(this.collapsed);
      }
    });
  }

HTML

<mdb-accordion>
  <mdb-accordion-item [collapsed]="collapsed" #SBItemComponent *ngFor="let item of items">
    <mdb-accordion-item-head>Item Head</mdb-accordion-item-head>
    <mdb-accordion-item-body>

      <p>Item: {{item}}</p>

    </mdb-accordion-item-body>
  </mdb-accordion-item>
<button mdbBtn (click)="toggle()">toggle</button>

Hope it helps!

Best Regards, Bartosz.


dominic_ks premium answered 2 years ago


Was there any further update here, or has anyone managed to get this working with *ngFor? I am trying to get accordion items to open and close based on a child route. It is working if you navigate directly to the route, but if you change route while on the page I am experiencing the same issue where the arrow on the right of the header changes but the content is now hidden or shown.


Arkadiusz Idzikowski staff commented 2 years ago

Please create a new thread and provide more details about your configuration (MDB Angular version) and an example code on which we will be able to reproduce this problem.


Wojciech Marciniak free commented 1 year ago

Why applyToggle() has never been documented? That's the question. I lost a couple of hours.


Arkadiusz Idzikowski staff commented 1 year ago

We added this method to the accordion API page.


declan.ward premium answered 3 years ago


Excellent Bartosz, thank you. This gives me exactly what I need.

Brilliant support, I am really impressed :)


declan.ward premium answered 3 years ago


Hi Bartosz,

That works fine for static content. Unfortunately, as soon as I add

*ngFor="let item of items"

it stops working.

This does not work: (with *ngFor)

<mdb-accordion>
<mdb-accordion-item [collapsed]="collapsed" #SBItemComponent *ngFor="let item of items">
  <mdb-accordion-item-head>Item Head</mdb-accordion-item-head>
  <mdb-accordion-item-body>

    <p>Item: {{item}}</p>

  </mdb-accordion-item-body>
</mdb-accordion-item>

This does work (without *ngFor)

<mdb-accordion>
<mdb-accordion-item [collapsed]="collapsed" #SBItemComponent>
  <mdb-accordion-item-head>Collapsible Group Item #1</mdb-accordion-item-head>
  <mdb-accordion-item-body>
    Item 1
  </mdb-accordion-item-body>
</mdb-accordion-item>

<mdb-accordion-item>
  <mdb-accordion-item-head>Collapsible Group Item #2</mdb-accordion-item-head>
  <mdb-accordion-item-body>
    Item 2
  </mdb-accordion-item-body>
</mdb-accordion-item>

<mdb-accordion-item>
  <mdb-accordion-item-head>Collapsible Group Item #3</mdb-accordion-item-head>
  <mdb-accordion-item-body>
    Item 3
  </mdb-accordion-item-body>
</mdb-accordion-item>

Regards, Declan


Bartosz Termena staff answered 3 years ago


Dear @declan.ward

Use our toggle() method from here: https://mdbootstrap.com/docs/angular/advanced/accordion/#a-methods

change your TS code to this:

  import { SBItemComponent } from 'yourpath';

  @ViewChild('SBItemComponent', { static: true }) SBItemComponent: SBItemComponent;
  title = 'Accordion Test';
  collapsed = false;
  items: string[] = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];

  toggle() {
    if (this.collapsed === true) {
      this.collapsed = false;
      console.log('Set to false');
    } else {
      this.collapsed = true;
      console.log('Set to true');
    }
    this.SBItemComponent.toggle(this.collapsed);
  }

HTML

<mdb-accordion>
  <mdb-accordion-item [collapsed]="collapsed" #SBItemComponent>
    <mdb-accordion-item-head>Collapsible Group Item #1</mdb-accordion-item-head>
    <mdb-accordion-item-body>
      Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad
      squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa
      nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid
      single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer
      labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo.
      Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably
      haven't heard of them accusamus labore sustainable VHS.
    </mdb-accordion-item-body>
  </mdb-accordion-item>
</mdb-accordion>

For [multiple]="false" use :

this.SBItemComponent.applyToggle(this.collapsed);

Best Regards, Bartosz.


Alejandro Medero free commented 2 years ago

Why isn't the applyToggle documented? spent a couple of hours until i got to this post to know how to do it lol....


Konrad Stępień staff commented 2 years ago

hi @Alejandro Medero,

Sorry for problems, we will add this in the near future.

In case of further problems, we encourage to open new support forum post.

Best, Konrad.


wipro_ltd pro commented 2 years ago

hi @bartoz this will not work with *ngFor , @Konrad Stępień can you suggest a way to do with ngFor , only the first child should be opened and rest all should be collapsed ?


Arkadiusz Idzikowski staff commented 2 years ago

Please provide some code and more details about the problem. Which version of MDB Angular do you use?


declan.ward premium answered 3 years ago


Hi Bartoz,

I am afraid that does not work. All it does is toggle the arrow to the right of the first item-head to up or down based on the value of collapsed. It does not open/close the item.

What I am trying to achieve is - if there is only one item then it should be open.

See https://www.screencast.com/t/MeOYUB5T

I have built a test app to show this.

app.modules.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { MDBBootstrapModulesPro } from 'ng-uikit-pro-standard';
import { MDBSpinningPreloader } from 'ng-uikit-pro-standard';
import { BrowserAnimationsModule } from  '@angular/platform-browser/animations';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
        AppComponent
  ],
  imports: [
BrowserModule,
MDBBootstrapModulesPro.forRoot(),
BrowserAnimationsModule
  ],
providers: [
MDBSpinningPreloader
 ],
bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts:


import { Component } from '@angular/core';
import { MDBModalRef, MDBModalService, CollapseModule } from 'ng-uikit-pro-standard';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'Accordion Test';

  items: string[] = ["Item 1", "Item 2", "Item 3", "Item 4"];

  constructor(){

  }

  ngOnInit(){

  }

  collapsed: boolean = true;

  toggle(): void {
    if (this.collapsed === true){
      this.collapsed = false;
      console.log("Set to false");
    }
    else {
      this.collapsed = true;
      console.log("Set to true");
    }
    console.log("Collapsed:" + this.collapsed);
  }

}

app.component.html is a direct copy from: Basic Accordion at https://mdbootstrap.com/docs/angular/advanced/accordion/

The only change is on mdb-accordion-item [collapsed]="collapsed" to add "collapsed" instead of "false" and the addition of a button to toggle: button type="button" (click)="toggle()"


Bartosz Termena staff answered 3 years ago


Dear @declan.ward

Just change strings to booleans in your code, like below:

collapsed = false;

toggle(): void {
if (this.collapsed === true){
  this.collapsed = false;
}
else {
  this.collapsed = true;
}

and then in your HTML:

 <mdb-accordion-item [collapsed]="collapsed">

Hope it helps!

Best Regards, Bartosz.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • User: Premium
  • Premium support: Yes
  • Technology: MDB Angular
  • MDB Version: 8.3.1
  • Device: Desktop
  • Browser: Firefox
  • OS: Windows 10
  • Provided sample code: No
  • Provided link: No
Tags