Search code examples
angulartypescriptionic4

Change the color/Fill of an ion-button dynamically


To start ineed to mention that I am new to ionic/angular…I have un api service call that returns a json full of data. as u see in the capture i have list of regions and sousRegions… after choosing (regions and sous regions) i have to display a MAP of number as Keys and and list of numbers as values as buttons. i need to change the ion-button color/fill of the selected key and its values. Example; If user chooses the First button of level 1 i need to make the first button’s fill attribute to “Solid” and the other buttons of same level to “outline” and the buttons of the level 2 same to choosen button of level 1 (outline).

capture

<!--Transport Names-->

  <ion-grid>

    <ion-row>

       <ion-label>

         Transports

       </ion-label>

    </ion-row>

    <ion-row>

      <ion-col size="3"  *ngFor="let tr of transports">

        <ion-list>

          <ion-button size="small" color="dark" mode="md" (click)="getSelectedTransport(tr)">

            <ion-label>{{tr.name}}</ion-label>

          </ion-button>

        </ion-list>

      </ion-col>

    </ion-row>

  </ion-grid>

  <ion-item-divider mode="ios"[hidden]=hideTrKeys>

  </ion-item-divider>

<!-- Transport Keys-->

level 1 

  <ion-grid>

    <ion-row>

      <ion-col size="3" *ngFor="let t of trmap | keyvalue">

          <ion-button size="small" fill="{{btFill}}"  mode="md" (click)="getSelectedTrKey(t.key)">

            <ion-label>{{t.key}}</ion-label>

          </ion-button>

      </ion-col>

    </ion-row>

  </ion-grid>

  <ion-item-divider mode="ios" [hidden]=hideTrValues >

  </ion-item-divider>

  level 2

  <!-- transport Values  -->

  <ion-grid>

    <ion-row>

      <ion-col size="3" *ngFor="let v of trValues">

          <ion-button size="small" mode="md" (click)="getSelectedTrValue(v)">

            <ion-label>{{v}}</ion-label>

          </ion-button>

      </ion-col>

    </ion-row>

  </ion-grid>

this is the functions that i use to display the buttons of level 1 and 2

getSelectedTransport(t :Transport) {
      console.log(t)
      this.trmap=t.trMap
      this.trValues=null
      console.log(this.trmap)
      this.hideTrKeys=false

  }
  getSelectedTrKey(key :number) {
    console.log(key)
    this. trValues=this.trmap[key] ;
    console.log(this.trValues)
    this.hideTrValues=false
    this.myButtonFills[key]='outline'  
}
getSelectedTrValue(v:number){
  console.log(v)
}

Solution

  • You can do it very easy with a one-way binding. So, in my-class.page.ts you create a class variable to store your button fill properties:

    export class MyClass {
       public myButtonFills: string[];
    }
    

    Then change your button fills as desired: myButtonFills[myButtonIndex] = 'solid'. You do this in your code whenever you need it (in my-class.page.ts). To link it with your user interface just use bracket to create a one-way binding:

    <ion-button [fill]="myButtonFills[thisButtonIndex]">Button</ion-button>
    

    The modification (refresh) of the array myButtonFills is something you have to take care in your code.

    Alternatively you could call a function (maybe a getter) in the binding like this:

    <ion-button [fill]="getButtonFill(thisButtonId)">Button</ion-button>
    

    So in your myClass.page.ts there would be a function public getButtonFill(buttonId: any): string that calculates the appropriate button fill for the given button id. This might be easy to make but sometimes lead to loop calls to the functions due to the Angular's change detector.

    Hope it helps.