Search code examples
ionic-frameworkionic3angular6ionic-tabsionic-popover

How to place Tabs inside Popover


I am having the requirement where the app is having tab view. The fourth tab is having popover and that popover contains more 3 menus which should act as a tab means it should open like other 3 tabs.

enter image description here

I have tried but the page is not displaying as it is not setting the popover page as root page inside tab view.

tabs.html

<ion-tabs #myTab>
  <ion-tab [root]="tab1Root" tabIcon="theme-business"></ion-tab>
  <ion-tab [root]="tab2Root" tabIcon="theme-table"></ion-tab>
  <ion-tab [root]="tab3Root" tabIcon="theme-like"></ion-tab>  
  <ion-tab (ionSelect)="presentPopover($event)" tabIcon="ios-apps-outline"></ion-tab>    
</ion-tabs>

tabs.ts

 presentPopover(event) {
    let popover = this.popoverCtrl.create(TabPopoverPage, {});
    popover.present({ ev: { target: event.btn._elementRef.nativeElement } });
  }

tabPopover.html

<ion-content padding>
  <ion-list>
    <button ion-item (click)="openPage('SalonDetailsPage')">
      <ion-icon name="theme-profile" item-left></ion-icon>
      Profile Page
    </button>
    <button ion-item (click)="openPage('SalesReportPage')">
      <ion-icon name="theme-wallet" item-left></ion-icon>
      Sales Report
    </button>
    <button ion-item (click)="openPage('SettingsPage')">
      <ion-icon name="theme-setting" item-left></ion-icon>
      Setting
    </button>
  </ion-list>
</ion-content>

tabPopover.ts

openPage(pageName: any) {
    // this.navCtrl.setRoot(pageName);    
    this.navCtrl.push(pageName);
  }

Help would be appreciated!


Solution

  • Please Note, while this implementation is not the best and there are probably a dozen other ways to solve this problem, this was the easiest. you can find a working example here: https://stackblitz.com/edit/ionic-v3-custom-tabs

    there may be a way to Programmatically add a new ion-tab item but i could not locate that on the ionic docs but here is my take of the implementation based on this question

    Step 1:

    we currently have 4 tab items, we add the extra tab items we need.

    <ion-tab [root]="tab4Root" show= "false"  tabIcon="person"></ion-tab>
    <ion-tab [root]="tab5Root" show= "false" tabIcon="cash"></ion-tab>
    <ion-tab [root]="tab6Root" show= "false" tabIcon="settings"></ion-tab> 
    

    NOTE the show attribute show: according to ionic docs hides the tab element . https://ionicframework.com/docs/api/components/tabs/Tab/#input-properties this creates the ion-tab elements but hides them.

    step 2:

    we need a reference to the ion-tabs element which was already define with <ion-tabs #myTab>

    page: tabs.ts

    // we are getting the ion-tabs using the template reference then assigning it to a local variable tabRef

    @ViewChild('myTab') tabRef: Tabs;

    presentPopover(event) {
        let popover = this.popoverCtrl.create(PopoverPage, {navpage: this}); // note the navpage: this
        popover.present({ ev: { target: event.btn._elementRef.nativeElement } });
    
      }
    

    we need a way to reference this component (TabsPage), so we are passing it as a nav params https://ionicframework.com/docs/api/components/popover/PopoverController/#create https://ionicframework.com/docs/api/navigation/NavParams/#get

    step 3:

    page: popover.html

    <button ion-item (click)="openPage(4)">
      <ion-icon name="person" item-left></ion-icon>
      Profile Page
    </button>
    <button ion-item (click)="openPage(5)">
      <ion-icon name="cash" item-left></ion-icon>
      Sales Report
    </button>
    <button ion-item (click)="openPage(6)">
      <ion-icon name="settings" item-left></ion-icon>
      Setting
    </button>
    

    // each of the number represent the tab index of the page we wish to navigate to see: https://ionicframework.com/docs/api/components/tabs/Tabs/#selecting-a-tab

    page: PopoverPage

    // the tabs page ref
    tabsPageRef: TabsPage;
    
    constructor(
        public navCtrl: NavController, 
        public navParams: NavParams
        ) {
        // recall the navpage: this from the TabsPage?
          this.tabsPageRef = this.navParams.get('navpage');
      }
    
    
      openPage(pageName: any) {
        // here, we are using the reference of the TabsPage to access the local variable tabref
        this.tabsPageRef.tabRef.select(pageName)
      }