Get selected tab to switch icons Ionic 5

Viewed 6619

I'm trying to change my tab icons from filled to outline when someone selects it (filled when selected, outline when not selected).

On the Ionic 5 Tabs Doc there's a getSelected() method but no examples on how to use this.

My idea was to use ionTabsDidChange to detect when someone clicked a tab, then use getSelected() and set the icon from 'home' to 'home-outline'.

Tabs.html

<ion-tabs>
  <ion-tab-bar slot="bottom">
    <ion-tab-button class="tab-btn" tab="home">
      <ion-icon name="{{ homeIcon }}"></ion-icon>
      <ion-label>Home</ion-label>
    </ion-tab-button>

    <ion-tab-button class="tab-btn" tab="price">
      <ion-icon name="{{ priceIcon }}"></ion-icon>
      <ion-label>Price Search</ion-label>
    </ion-tab-button>
<ion-tabs>

Tabs.ts

export class TabsPage {
  public homeIcon = 'home';
  private homeFilled = 'home';
  private homeOutline = 'home-outline'
  public priceIcon = 'search-outline';
  private priceFilled = 'search';
  private priceOutline = 'search-outline';

  ionTabsDidChange() {
    let selectedTabName = getSelected();
    // Stuff to switch icon from filled to outline and vice versa
  }

}

The issue is that I don't know how to use getSelected(), I've tried adding ViewChild like this stackoverflow, but getSelected() is not a function (Changed to IonTabs because Tabs don't exist in Ionic 5.

At this point, the only solution I can think of is saving the tabs state and adding click functions for everything.

5 Answers

You are heading the right direction, there are still few missing points. In the Ionic doc you are reading the "events" are not directly accessible in the page without binding them to the component itself and in order to use ViewChild you also need to give the component an id:

Tabs.html

<ion-tabs #tabs (ionTabsDidChange)="setCurrentTab()">

"tabs" will be the id of the component and whenever ionTabsDidChange event gets triggered it will call setCurrentTab method, it should be declared on your page.

Then in the page, as you have already mentioned you'll need to add a ViewChild (now possible with the id) and use getSelected() method.

Tabs.ts

export class TabsPage {
  @ViewChild('tabs', { static: false }) tabs: IonTabs;

...

  setCurrentTab() {
    this.selectedTab = this.tabs.getSelected();
  }

}

And voila, that should be it :-)

Inside the ion-tabs tag, ionTabsDidChange passes an event which has the selected tab. You can get that event by doing the following then it should give you the clicked tab:

tabs.html

<ion-tabs (ionTabsDidChange)="tabClicked($event)">

tabs.ts

tabClicked(e) {
    this.selectedTab = e.tab
}

There's another really easy way to do this. First add the ionTabsDidChange attribute to your ion-tabs element as @andriyleu suggests but this time make sure to pass $event details in.

<ion-tabs (ionTabsDidChange)="setCurrentTab($event)">

Then you can define the function in your ts file like this.

current_tab = "home"; // Set this as you default page name

setCurrentTab(ev: any){
  this.current_tab = ev.tab;
}

Finally, in your html you can use a very efficient piece of Javascript to determine which icon to show. Perhaps like me, you're switching between a filled and outline version.

<ion-icon [name]="current_tab == 'home' ? 'home' : 'home-outline'"></ion-icon>

Thanks to the everyone who answered this and helped me figure it out!

Doesn't work in React.

const log = (e: any): any => {
    console.log(e);
  }

 <IonTabs ionTabsDidChange={log}>

Type '{ children: Element[]; ionTabsDidChange: (e: any) => any; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<IonTabs> & Readonly<Props> & Readonly<{ children?: ReactNode; }>'.
[react-scripts]   Property 'ionTabsDidChange' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<IonTabs> & Readonly<Props> & Readonly<{ children?: ReactNode; }>'.  TS2322
[react-scripts]     47 |     <IonApp>

Any thoughts?

Ionic will add "tab-selected" class to the selected tab. You can use that class to style the tab icon.

Related