17 Aug

Ionic 4 | App from Scratch – Adding Content

In this blog, we will discus the steps to add additional content (pages, components) to your existing app. We will start with the App From Scratch we create here.

Preparation

Configure Visual Studio Code

First, we will configure Visual Studio Code to show only the desired folders for this tutorial.

We will hide the folders node_modles, e2e and .env

To do this, select Code / Prefecences / Settings

Visual Studio Code will open the settings in a editor window. You will see the default uer settings on te left, and the current user settings on the right.

Look for the lines unter „files.exclude“ and add or edit the desired content.

Setting to true means exclude (remember the title of the group: files.exclude)

Open required windows

As we add some content, we want to see immediately the results.

So,  i opened three windows

  • Visual Studio Code
  • Browser Windows
  • Console, where we start the ionic server

Change directory structure

Now we can start: Lets add some pages we will use to contain Ionic Components (Buttons, Text, Switches, Lists, Grids, …)

Out app have 3 pages. You will find them in them explorer window

First, i want to change the directory structure.

For each component type, we will add, i want to a a separate folder.

So, first: create a folder pages for our pages

Next, move the pages folders home, list and about into the newly create folder

After that, go into the console, stop the running ionic serve command and restart it to force a new compilation of our app

$ ionic serve
> ng run app:serve --host=0.0.0.0 --port=8100

In the console window, we will see an error

[ng] ERROR in Could not resolve module ./home/home.module relative to .../app_from_scratch/src/app/app-routing.module.ts

This is, because we changes the directory path of the pages. We had to adjust the new path in out app: in app-routing.module.ts

const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: 'home', loadChildren: './pages/home/home.module#HomePageModule' },
  { path: 'list', loadChildren: './pages/list/list.module#ListPageModule' },
  { path: 'about', loadChildren: './pages/about/about.module#AboutPageModule' }
];

Add page: ActionSheet

Ionic offers a huge amount of amazing components. So, we will demonstrate the use of this components step by step. We will take the inspiration from here.

Starting with Action Sheets.

  • Documentation is here
ionic generate page ActionSheet
> ng generate page ActionSheet
CREATE src/app/action-sheet/action-sheet.module.ts (569 bytes)
CREATE src/app/action-sheet/action-sheet.page.scss (0 bytes)
CREATE src/app/action-sheet/action-sheet.page.html (138 bytes)
CREATE src/app/action-sheet/action-sheet.page.spec.ts (727 bytes)
CREATE src/app/action-sheet/action-sheet.page.ts (279 bytes)
UPDATE src/app/app-routing.module.ts (736 bytes)
[OK] Generated page!

To add the new page to the sidemenu, change the AppPages array in app.component.ts

public appPages = [
  { title: 'Home', url: '/home', icon: 'home' },
  { title: 'List', url: '/list', icon: 'list' },
  { title: 'About', url: '/about', icon: '' },
  { title: 'ActionSheet', url: '/ActionSheet', icon: 'list' }
];

Notice the different spelling of the url (different case of letters). Whatever spelling you choose, it has to fit to the path value in the app-routing.module.ts

Next, move the page to the pages folder and change the path in app-routing.modules.ts

Add the sidemenu button to the actionSheet Page (in action-sheet.page.html)

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>ActionSheet</ion-title>
  </ion-toolbar>
</ion-header>

Ok, well done

Next, add a button and the code for displaying the action sheet. The source is here.

Change your html page: action-sheet.page.html

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-menu-button></ion-menu-button>
    </ion-buttons>
    <ion-title>ActionSheet</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content padding fullscreen>
  <ion-button expand="block" id="basic" (click)="presentBasic()">Basic</ion-button>
  <ion-button expand="block" id="noBackdropDismiss" (click)="presentNoBackdropDismiss()">No Backdrop Dismiss</ion-button>
  <ion-button expand="block" id="alertFromActionSheet" (click)="presentAlert()">Alert from Action Sheet</ion-button>
  <ion-button expand="block" id="scrollableOptions" (click)="presentScroll()">Scrollable Options</ion-button>
  <ion-button expand="block" id="scrollWithoutCancel" (click)="presentScrollNoCancel()">Scroll Without Cancel</ion-button>
  <ion-button expand="block" id="cancelOnly" (click)="presentCancelOnly()">Cancel Only</ion-button>
  <ion-button expand="block" id="icons" (click)="presentIcons()">Icons</ion-button>
  <ion-button expand="block" id="cssClass" (click)="presentWithCssClass()">Custom CSS Class</ion-button>
</ion-content>

Change your Style: action-sheet.page-scss

app-action-sheet {
}

Change the Code: action-sheet.page.ts. Source is here

import { Component, OnInit } from "@angular/core";
import { Platform, ActionSheetController } from "@ionic/angular";

@Component({
  selector: "app-action-sheet",
  templateUrl: "./action-sheet.page.html",
  styleUrls: ["./action-sheet.page.scss"]
})
export class ActionSheetPage implements OnInit {
  constructor(
    public platform: Platform,
    public actionSheetController: ActionSheetController
  ) {}

  ngOnInit() {}


  public changeColor(ev) {

  }

  async presentActionSheet() {
    const actionSheet = await this.actionSheetController.create({
      header: "Albums",
      buttons: [{
        text: 'Delete',
        role: 'destructive',
        icon: 'trash',
        handler: () => {
          console.log('Delete clicked');
        }
      }, {
        text: 'Share',
        icon: 'share',
        handler: () => {
          console.log('Share clicked');
        }
      }, {
        text: 'Play (open modal)',
        icon: 'arrow-dropright-circle',
        handler: () => {
          console.log('Play clicked');
        }
      }, {
        text: 'Favorite',
        icon: 'heart',
        handler: () => {
          console.log('Favorite clicked');
        }
      }, {
        text: 'Cancel',
        icon: 'close',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheet.present();
  }

  async presentBasic() {
    console.log('ActionSheetPage:presentBasic');

    const actionSheet = await this.actionSheetController.create({
      header: "Albums",
      buttons: [{
        text: 'Delete',
        role: 'destructive',
        icon: 'trash',
        handler: () => {
          console.log('Delete clicked');
        }
      }, {
        text: 'Share',
        icon: 'share',
        handler: () => {
          console.log('Share clicked');
        }
      }, {
        text: 'Play (open modal)',
        icon: 'arrow-dropright-circle',
        handler: () => {
          console.log('Play clicked');
        }
      }, {
        text: 'Favorite',
        icon: 'heart',
        handler: () => {
          console.log('Favorite clicked');
        }
      }, {
        text: 'Cancel',
        icon: 'close',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheet.present();
  }
  
  async presentIcons() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      header: "Albums",
      buttons: [{
        text: 'Delete',
        role: 'destructive',
        icon: 'trash',
        handler: () => {
          console.log('Delete clicked');
        }
      }, {
        text: 'Share',
        icon: 'share',
        handler: () => {
          console.log('Share clicked');
        }
      }, {
        text: 'Play (open modal)',
        icon: 'arrow-dropright-circle',
        handler: () => {
          console.log('Play clicked');
        }
      }, {
        text: 'Favorite',
        icon: 'heart',
        role: 'selected',
        handler: () => {
          console.log('Favorite clicked');
        }
      }, {
        text: 'Cancel',
        role: 'cancel',
        icon: 'close',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    })
    await actionSheetElement.present();
  }
  
  async presentNoBackdropDismiss() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      backdropDismiss: false,
      buttons: [{
        text: 'Archive',
        handler: () => {
          console.log('Archive clicked');
        }
      }, {
        text: 'Destructive',
        role: 'destructive',
        handler: () => {
          console.log('Destructive clicked');
        }
      }, {
        text: 'Cancel',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheetElement.present();
  }
  
  async presentAlert() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [{
        text: 'Open Alert',
        handler: () => {
          console.log('Open Alert clicked');
        }
      }, {
        text: 'Cancel',
        role: 'cancel',
        handler: () => {
          console.log('Cancel clicked');
        }
      }]
    });
    await actionSheetElement.present();
  }
  
  async presentScroll() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [
        {
          text: 'Add Reaction',
          handler: () => {
            console.log('Add Reaction clicked');
          }
        }, {
          text: 'Copy Text',
          handler: () => {
            console.log('Copy Text clicked');
          }
        }, {
          text: 'Share Text',
          handler: () => {
            console.log('Share Text clicked');
          }
        }, {
          text: 'Copy Link to Message',
          handler: () => {
            console.log('Copy Link to Message clicked');
          }
        }, {
          text: 'Remind Me',
          handler: () => {
            console.log('Remind Me clicked');
          }
        }, {
          text: 'Pin File',
          handler: () => {
            console.log('Pin File clicked');
          }
        }, {
          text: 'Star File',
          handler: () => {
            console.log('Star File clicked');
          }
        }, {
          text: 'Mark Unread',
          handler: () => {
            console.log('Mark Unread clicked');
          }
        }, {
          text: 'Edit Title',
          handler: () => {
            console.log('Edit Title clicked');
          }
        }, {
          text: 'Save Image',
          handler: () => {
            console.log('Save Image clicked');
          }
        }, {
          text: 'Copy Image',
          handler: () => {
            console.log('Copy Image clicked');
          }
        }, {
          text: 'Delete File',
          role: 'destructive',
          handler: () => {
            console.log('Delete File clicked');
          }
        }, {
          text: 'Cancel',
          role: 'cancel', // will always sort to be on the bottom
          handler: () => {
            console.log('Cancel clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
  
  async presentScrollNoCancel() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [
        {
          text: 'Add Reaction',
          handler: () => {
            console.log('Add Reaction clicked');
          }
        }, {
          text: 'Copy Text',
          handler: () => {
            console.log('Copy Text clicked');
          }
        }, {
          text: 'Share Text',
          handler: () => {
            console.log('Share Text clicked');
          }
        }, {
          text: 'Copy Link to Message',
          handler: () => {
            console.log('Copy Link to Message clicked');
          }
        }, {
          text: 'Remind Me',
          handler: () => {
            console.log('Remind Me clicked');
          }
        }, {
          text: 'Pin File',
          handler: () => {
            console.log('Pin File clicked');
          }
        }, {
          text: 'Star File',
          handler: () => {
            console.log('Star File clicked');
          }
        }, {
          text: 'Mark Unread',
          handler: () => {
            console.log('Mark Unread clicked');
          }
        }, {
          text: 'Edit Title',
          handler: () => {
            console.log('Edit Title clicked');
          }
        }, {
          text: 'Save Image',
          handler: () => {
            console.log('Save Image clicked');
          }
        }, {
          text: 'Copy Image',
          handler: () => {
            console.log('Copy Image clicked');
          }
        }, {
          text: 'Delete File',
          role: 'destructive',
          handler: () => {
            console.log('Delete File clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
  
  async presentCancelOnly() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel', // will always sort to be on the bottom
          handler: () => {
            console.log('Cancel clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
  
  async presentWithCssClass() {
    const actionSheetController = document.querySelector('ion-action-sheet-controller');
    await actionSheetController.componentOnReady();
    const actionSheetElement = await actionSheetController.create({
      header: "Custom Css Class",
      cssClass: "my-class my-custom-class",
      buttons: [
        {
          text: 'Test',
          role: 'test',
          cssClass: 'my-cancel-button my-custom-button customClass',
          handler: () => {
            console.log('Cancel clicked');
          }
        }
      ]
    });
    await actionSheetElement.present();
  }
}

Done. Now look at the result

Add page: Buttons

Add page: Toolbar Buttons