How to combine tab navigation with side menu in Ionic

menu banner

With ionic CLI you can quickly and easy create a Side Menu app just by running the command

ionic start sidemenu

or create a tab application by running:

ionic start tab

Those are common navigation patterns used by a lot of mobile applications today:

In this short tutorial we are going to try to combine those different navigation patterns into one application.

We will keep things simple, we are going to make the transition from a login page (Taken from ionappFull4Pro starter) to our inside navigation, which combines side menu and tabs.

Login workflow

This is a module that is part of the ionappFull4Pro starter, and with it you’ll be able to:
– Login with Firebase username and password
– Login with Google (native) //for this the app must run on a device or an emulator
– Login with Facebook (native) //for this the app must run on a device or an emulator
– Login with Google (PWA mode) //this mean that you can login with google running the app on the browser
– Recover your password
– Register new user
– User editable profile

Prerequisites

We assume you are familiar with ionic, and you have set up your ionic environment, if not you can follow this tutorial: https://ionicframework.com/getting-started#cli

We are going to start creating a blank ionic template using the CLI commandand then we are going to create all the needed pages:

ionic start convinedNavigation blank
ionic g page menu
ionic g page tabs
ionic g page tab1
ionic g page tab2

Spoiler alert

We are going to use lazy loading, for load our pages, so after create the new project feel free to remove the home page generated by default.

Now use your favorite IDE to open the project (mine is Microsoft Code) and change the rootPage variable to a string “LoginPwaPage”, this will tells ionic LoginPwaPage is the entry point page.

ionic app component

Lest import the login component from ionappFull4Pro into our project. First, copy the login-workflow folder (which contains login, profile,recover and register pages) into our project (also you can follow the instructions on the instructions.txt file included in the folder).

import login from ionappfull4pro

This is how it should looks like:

login workflow in our local project

Follow the instructions on the instructions.txt file to complete the import of this component:

Instructions.txt

Instructions to import this component in your existing ionic app.

If you don't have an ionic app created, create one, by running the following command on the command console, on the folder you want your app to be created, 
once your app is created locate the pages folder and copy this component (folder) in the page folder:

$ ionic start MyAppName blank

for more info go to the ionic official documentation.


Once you have your app created Install the components dependencies (see what is imported on the ts files on this component):

On your firebase dashboard enable the email/password methods, see documentation: http://jomendez.com/ionAppFull4Pro-documentation/#!/firebase_configuration
	
Notes:
For this component to work you need to setup firebase and also import the DatabaseProvider from "/providers/database/database" included on the ionAppFull4Pro project.
Also import /providers/auth-data provided from ionAppFull4Pro to your app
Also copy src/config/config.ts from this project (ionAppFull4Pro) to your application, and enter your firebase information.

Remember to install the firebase dependencies and add the providers to the app.module.ts file:

npm i --save angularfire2 firebase

For this tutorial we are going to use the login-pwa component to keep it simple and be able to test the app in the browser without having to run it on a device or emulator. Login pwa component uses some “fancy” animation library called VegasJs (this is not required for the login component to work, you can easily remove it). In order to include it and make it work you’ll need to copy few thinks from ionappFull4Pro starter, first include the jquery library and vegas dependencies on index.thml and then copy the files into assets folder:

add jquery and vega index
images on the assets folder

This is how the app.modules should looks like after all the imports and declaration:

app modules dependencies

One last thing it we have to redirect to menu page after login, so we will have to modify the login() method, lets comment the code that redirects to the profile page and add the code that set the MenuPage as the root:

redirect to menupage

Build the menu navigation:

Add this menu code to your src/pages/menu/menu.html


<ion-menu [content]="content">
  <ion-header>
    <ion-toolbar>
      <ion-title>Menu</ion-title>
    </ion-toolbar>
  </ion-header>
 
  <ion-content>
    <ion-list>
      <button ion-item menuClose *ngFor="let p of pages" (click)="openPage(p)">
          <ion-icon item-start [name]="p.icon" [color]="isActive(p)"></ion-icon>
          {{ p.title }}
        </button>
    </ion-list>
  </ion-content>
</ion-menu>
 
<!-- main navigation -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>

Add this code to src/pages/menu/menu.ts
Notice that in page one of the pages that can be called is the Profile page that comes with the login component from ionappFull4Pro starter

 pages = [
    { title: 'Tab 1', pageName: 'TabsPage', tabComponent: 'Tab1Page', index: 0, icon: 'home' },
    { title: 'Tab 2', pageName: 'TabsPage', tabComponent: 'Tab2Page', index: 1, icon: 'shuffle' },
    { title: 'Profile', pageName: 'AfterLoginPage', icon: 'contacts' },,//notice we cal here the Profile that comes with the login workflow component on ionAppFull4Pro starter
  ];
import { Tab2Page } from './../tab2/tab2';
import { Tab1Page } from './../tab1/tab1';
import { TabsPage } from './../tabs/tabs';
import { Component, ViewChild } from '@angular/core';
import { IonicPage, NavController, Nav } from 'ionic-angular';
 

@IonicPage()
@Component({
  selector: 'page-menu',
  templateUrl: 'menu.html',
})
export class MenuPage {
  // Basic root for our content view
  rootPage = 'TabsPage';
 
  // Reference to the app's root nav
  @ViewChild(Nav) nav: Nav;
 
  pages = [
    { title: 'Tab 1', pageName: 'TabsPage', tabComponent: 'Tab1Page', index: 0, icon: 'home' },
    { title: 'Tab 2', pageName: 'TabsPage', tabComponent: 'Tab2Page', index: 1, icon: 'shuffle' },
    { title: 'Profile', pageName: 'AfterLoginPage', icon: 'contacts' },
  ];

  constructor(public navCtrl: NavController) { }
 
  openPage(page) {
    let params = {};
 
    // The index is equal to the order of our tabs inside tabs.ts
    if (page.index) {
      params = { tabIndex: page.index };
    }
 
    // The active child nav is our Tabs Navigation
    if (this.nav.getActiveChildNav() && page.index != undefined) {
      this.nav.getActiveChildNav().select(page.index);
    } else {
      // Tabs are not active, so reset the root page 
      // In this case: moving to or from SpecialPage
      this.nav.setRoot(page.pageName, params);
    }
  }
 
  isActive(page) {
    
    let childNav = this.nav.getActiveChildNav();
 
    if (childNav) {
      if (childNav.getSelected() && childNav.getSelected().root === page.tabComponent) {
        return 'primary';
      }
      return;
    }
 
    // Fallback needed when there is no active childnav (tabs not active)
    if (this.nav.getActive() && this.nav.getActive().name === page.pageName) {
      return 'primary';
    }
    return;
  }
 
}


Adding the Tab

Open your src/pages/tabs/tabs.html and change it to:

<ion-tabs [selectedIndex]="myIndex">
  <ion-tab [root]="tab1Root" tabTitle="Tab 1" tabIcon="home"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Tab 2" tabIcon="contacts"></ion-tab>
</ion-tabs>

This tab bar will be pointing to the 2 tabs pages we created at the beginning.
Now change your src/pages/tabs/tabs.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
 
@IonicPage()
@Component({
  selector: 'page-tabs',
  templateUrl: 'tabs.html',
})
export class TabsPage {
 
  tab1Root: any = 'Tab1Page';
  tab2Root: any = 'Tab2Page';
  myIndex: number;
 
  constructor(navParams: NavParams) {
    // Set the active tab based on the passed index from menu.ts
    this.myIndex = navParams.data.tabIndex || 0;
  }
}

Now we only need to add a menu button to all of our pages so we can toggle the menu from everywhere. Go through these 2 files (tab1, tab2) and change it, add the following html code:

Tab1

<ion-header>
  <ion-navbar>
      <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Tab1</ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  This is tab 1 content
</ion-content>

Tab2

<ion-header>
  <ion-navbar>
      <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>Tab2</ion-title>
  </ion-navbar>
</ion-header>
 
<ion-content padding>
  This is tab 2 content
</ion-content>

This is the result:

Try it yourself:

Conclusions

With this article we got two navigation pattern working together, it could be a little bit tricky, but it is possible, also we were able to integrate/import the login module very easy, from the ionAppFull4Pro ionic starter into our applications, saving us a lot of time and development effort, and just with that we were able to implement an app with firebase login, google login, recover password, register user, and profile page.

Cheers,
Jose

Leave a Reply