angulartypescriptionic-frameworkionic2ionic3

Ionic2: sidemenu submenu (dropdown)


I don't do ionic, and it's not my question, it's my friend's question who's afraid of asking on StackOverflow since she doesn't really know how to ask.

She just would like to know how to create a submenu in ionic 2 side menu starter project.

The HTML

<ion-menu [content]="content" side="left" id="menu1">
  <ion-content class="outer-content" no-border-top>
    <ion-list lines (click)="openSubCat($event,category)">
      <ion-list-header>
        Shop For
      </ion-list-header>
      <ion-item *ngFor="let item of categoryArray" let idx=index (click)="openSubCat(item.value)">
        <ion-icon [name]="item.icon" item-left></ion-icon>
          {{ item.value }}
        <ion-icon [name]="item.icon2" item-right ></ion-icon>
     </ion-item>
    </ion-list>
 </ion-content>
</ion-menu>
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>`

the app-components.ts

import { Component, ViewChild } from '@angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar, Splashscreen } from 'ionic-native';

import { TutorialPage } from '../pages/tutorial/tutorial';


@Component({
  templateUrl: 'app.html'
})
export class MyApp {
  @ViewChild(Nav) nav: Nav;

  rootPage: any = TutorialPage;

  pages: Array<{title: string, component: any}>;

  categoryArray: Array<any> = [{
      value:'Men',
      icon: 'man',
      icon2:'ios-arrow-forward-outline',
      view:'viewToGoTo'
   },{
      value:'Woman',
      icon: 'woman',
      icon2:'ios-arrow-forward-outline',
      view:'viewToGoTo'
   },{
      value:'Kids',
      icon: '',
      icon2:'ios-arrow-forward-outline',
      view:'viewToGoTo'
   }
   ];
  constructor(public platform: Platform) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      // Okay, so the platform is ready and our plugins are available.
      // Here you can do any higher level native things you might need.
      StatusBar.styleDefault();
      Splashscreen.hide();
    });
  }

  openPage(page) {
    // Reset the content nav to have just this page
    // we wouldn't want the back button to show in this scenario
    this.nav.setRoot(page.component);
  }

openSubCat(category){
  console.log(category)

}

}

I sent her this link but couldn't really explain much, since I don't do ionic, but it seems to be that to create a dropdown you just need to create a 2d array, is that correct? Could you please edit the code in this question to include a submenu as an example for her to learn from?


Solution

  • About the repository (btw thanks for sharing my demo lol), that's just one way to create a side menu in Ionic. Just like you can see in the README.md file, first copy the content of the side-menu-content folder (the .ts, .html and .scss files) to your project.

    Then add it to declarations array of your NgModule, in the app.module.ts file:

    // The path could be different on your end
    import { SideMenuContentComponent } from '../side-menu-content/side-menu-content.component';
    
    @NgModule({
      declarations: [
        MyApp,
        // ...
        SideMenuContentComponent // <- Here!
      ],
      imports: [
        BrowserModule,
        IonicModule.forRoot(MyApp)
      ],
      bootstrap: [IonicApp],
      entryComponents: [
        MyApp,
        // ...
      ],
      providers: [
        StatusBar,
        SplashScreen,
        { provide: ErrorHandler, useClass: IonicErrorHandler }
      ]
    })
    export class AppModule { }
    

    Now we just need to add some code to initialize the side menu, and also to handle what to do when an option is selected. So in the app.component.ts file, add this code:

    @Component({
        templateUrl: 'app.html'
    })
    export class MyApp {
        @ViewChild(Nav) navCtrl: Nav;
    
        // Get the instance to call the public methods
        @ViewChild(SideMenuContentComponent) sideMenu: SideMenuContentComponent;
    
        public rootPage: any = HomePage;
        public options: Array<MenuOptionModel>;
    
        constructor(private platform: Platform,
                    private statusBar: StatusBar,
                    private splashScreen: SplashScreen,
                    private menuCtrl: MenuController) {
            this.initializeApp();
        }
    
        initializeApp() {
            this.platform.ready().then(() => {          
                this.statusBar.styleDefault();
                this.splashScreen.hide();
    
                // Create the options
                this.options = this.getSideMenuOptions();
            });
        }
    
        // Initialize the side menu options
        private getSideMenuOptions(): Array<MenuOptionModel> {
            let menuOptions = new Array<MenuOptionModel>();
    
            // Shop for (header)
            //  - Man
            //  - Woman
            //  - Kids
    
            menuOptions.push({
                iconName: 'ios-arrow-down',
                displayName: `Shop for`,
                component: null,    // This is just the header
                isLogin: false,     // It's not the login
                isLogout: false,    // It's not the logout
                subItems: [
                    {
                        iconName: 'man',
                        displayName: `Men`,
                        component: viewToGoTo,
                        isLogin: false,
                        isLogout: false
                    },
                    {
                        iconName: 'woman',
                        displayName: `Woman`,
                        component: viewToGoTo,
                        isLogin: false,
                        isLogout: false
                    },
                    {
                        iconName: 'happy',
                        displayName: `Kids`,
                        component: viewToGoTo,
                        isLogin: false,
                        isLogout: false
                    }
                ]
            });
    
            return menuOptions;
    
        }
    
        // Redirect the user to the selected page
        public selectOption(option: MenuOptionModel): void {
            this.menuCtrl.close().then(() => {
    
                // Collapse all the options
                this.sideMenu.collapseAllOptions();
    
                // Redirect to the selected page
                this.navCtrl.push(option.component);
            });
        }
    
        public collapseMenuOptions(): void {
            // Collapse all the options
            this.sideMenu.collapseAllOptions();
        }
    }
    

    Now the last thing to do is to add the side menu in the view. So put this in the app.html file:

    <ion-menu persistent="true" [content]="content" (ionClose)="collapseMenuOptions()">
        <ion-header>
            <ion-toolbar color="secondary">
                <ion-title>Menu</ion-title>
            </ion-toolbar>
        </ion-header>
    
        <ion-content>
    
            <!-- Side Menu -->
            <side-menu-content [accordionMode]="true" [options]="options" (selectOption)="selectOption($event)"></side-menu-content>
    
        </ion-content>
    </ion-menu>
    
    <!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
    <ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>