Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accordion : Work with dynamic CSS class #2262

Closed
Numalama opened this issue Mar 27, 2018 · 6 comments · Fixed by #3563
Closed

Accordion : Work with dynamic CSS class #2262

Numalama opened this issue Mar 27, 2018 · 6 comments · Fixed by #3563

Comments

@Numalama
Copy link

Bug description:

I want the panels to be clickable but without content.

The idea would be to retrieve the panel that I just click / select in order to pass it in active class and change its color to differentiate it from others.

And of course if I click on another panel, disable / deselect the one that was active before.

So I try to work with dynamic classes in a ngb panel selector but without the [disable] =" true " entry.

When I click on a panel, I print it in the console (example Plunker). Which allows me to identify it.

I tried a lot of things like:
[class.active]="true == this.tabSelected.indexOf(item.id) > -1"
[ngClass]="'selected'"
[class.first-item]="first" [class.last-item]="last"
Into following example:

                <!-- Example -->
                <ngb-accordion #acc="ngbAccordion" >
                <!--Dynamic class into this ngb-panel -->
                  <ngb-panel *ngFor=" let child of child.children; let k = index; let first = first; let last = last"  [disabled]="true"  id="test-{{child.id}}" >
                    <ng-template ngbPanelTitle >
                      <div (click)="setClickedRow(j,k)" style="float:left;">
                        {{ child.name }}
                      </div>
                      <button class="btn btn-sm btn-outline-light" style="float:right;">{{ child.price }} €</button>
                    </ng-template>
                    <ng-template ngbPanelContent> 
                    </ng-template>
                  </ngb-panel>
                </ngb-accordion>                  
                <!-- Example  -->

I tried to use [ngClass] = 'selected' in ngb-accordion selector and the css class was changed by "selected".

But nothing to do at the level of ngb-panel selector, the css class still the same.

I don't know if it's possible to do something like that.

You can fork a plunker from one of our demos and use it as a starting point.
Please note that we can not act on bug reports without a minimal reproduction scenario in plunker. Here is why:
http://plnkr.co/edit/agr9Oe3RN01sn9UeWJ3m?p=preview

Version of Angular, ng-bootstrap, and Bootstrap:

Angular: 5.2.5

ng-bootstrap: 1.0.4

@pkozlowski-opensource
Copy link
Member

The closest thing we've got is the type property on a panel level: https://ng-bootstrap.github.io/#/components/accordion/api#NgbPanel

@Numalama
Copy link
Author

Based on your indications, I try to set conditions in my loop in order to switch between two ngb-panel, one with a success type and another type of danger.

So when I click on the preselected item in green, the project reloaded.
And when i click on a red item (not preselected), the console is clean up.

This is when I want to splice a table of preselected item for the ngb-panel condition.

** Here is the Plunker for the demo: **

http://plnkr.co/edit/ypK891VsZ6CnGjWKe1ir?p=preview

              <!-- Example -->
                <ngb-accordion *ngFor=" let child of child.children; let k = index; let first = first; let last = last" #acc="ngbAccordion" [ngClass]="'test'">
                  <ngb-panel   *ngIf="true == this.tabSelected.indexOf(child.id) > -1" [disabled]="true"  id="test-{{child.id}}"  type="success">
                    <ng-template ngbPanelTitle >
                      <div (click)="setClickedRow(j,k)" style="float:left;">
                        {{ child.name }}
                      </div>
                      <button class="btn btn-sm btn-outline-light" style="float:right;">{{ child.price }} €</button>
                    </ng-template>
                    <ng-template ngbPanelContent> 
                    </ng-template>
                  </ngb-panel>
                  <ngb-panel   *ngIf="false == this.tabSelected.indexOf(child.id) > -1" [disabled]="true"  id="test-{{child.id}}"  type="danger">
                      <ng-template ngbPanelTitle >
                        <div (click)="setClickedRow(j,k)" style="float:left;">
                          {{ child.name }}
                        </div>
                        <button class="btn btn-sm btn-outline-light" style="float:right;">{{ child.price }} €</button>
                      </ng-template>
                      <ng-template ngbPanelContent> 
                      </ng-template>
                    </ngb-panel>
                </ngb-accordion>
              <!-- End Example -->

So I have functions that allow me to retrieve a list of preselected item

  setDefaultTabSelected() {
    
    this.tabSelected = [];

    for (let i in this.laptop.children) {
      console.log(this.laptop.children[i].name);
      if (this.laptop.children[i].name != "Accessories") {
        this.tabSelected.push(this.laptop.children[i].children[0].id);
        if (this.laptop.children[i].name != "None") {
          //this.OptionSelected.push(this.information[0].children[i].children[0]);
        }
      }
    }

    for (let i in this.tabSelected) {
      console.log(this.tabSelected[i]);
    }

  }

When I click on a panel, the function I call (click)="setClickedRow(j,k)".

This function splice the preselected item (example: id 0 became 1).

like that:

clearChildrensId(childrens, childChoose) {
   
    for (let i = 0; i < this.tabSelected.length; i++) {
      for (let j = 0; j < this.tabChild.length; j++) {
        if (this.tabSelected[i] === this.tabChild[j].id) {
          this.tabSelected.splice(i, 1, "" + childChoose.id + "");
          //this.OptionSelected.splice(i, 1, childChoose);
        }
        /*
        if(this.OptionSelected[i].id === this.tabChild[j].id){
           this.OptionSelected.splice(i, 1,  childChoose );
        }
        */

      }
    }

@Numalama
Copy link
Author

I have made some modifications on this Plunker: http://plnkr.co/edit/9ymXORzF63M67nNXy0xd?p=preview

So now when I click on an item, I trying to change the value of the preselected item list by id position.

  setClickedRow(j, k) {
    // Check if the id was in preselected list return true or false
    console.log(this.tabSelected.indexOf(this.laptop.children[j].children[k].id) > -1);
    //  Get the id of the current item click
    console.log(this.laptop.children[j].children[k].id);
    // For testing I replace the value per 1
    this.tabSelected[0] = 1;
    
  }

If u try the Plunker, when u clicking on the item at position 1 into Platform Upgrade Option (the second item on the view = Intel® Core™ i5-6300U vPro™ Processor 2.4GHz).
The projet the project reload.

Finally if u click on an other item (for example the third item of the list) all works fine, the item at position 1 going to be in green.

So if u change this.tabSelected[0] = 1; by this.tabSelected[0] = 2; and click on the second item same reaction, the projet reload.

@pkozlowski-opensource
Copy link
Member

I try to set conditions in my loop in order to switch between two ngb-panel, one with a success type and another type of danger.

It is a bit hard to investigate for me as I don't fully understand what you are trying to do exactly but I don't think you should have if / else around panels as this will re-create them and give the "reload" impression.

What you should be doing instead is to bind to panel properties and change their type / disabled flag based on your mode. In short - use bindings instead of if / else.

@Numalama
Copy link
Author

Here is an example of the result I want to optain but with Angular Material:
https://stackblitz.com/edit/angular-material2-issue-2262?file=app/app.component.ts

When I click on an item, I change the preselected id list and so the css class became active.

But with ngb how can we make something like that ?

@IT-CASADO
Copy link

I also want to use ngClass or ngStyle for the same reason. Add additional styles on opened tabs...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants