Ionic 3 - Extract the side menu in it's own component - ionic2

I need to build a scalable menu for an ionic 2/3 app (preferably using ion-menu). Following the guides on the docs the menu should be a sibling of the main content and they suggest to keep it inside app.html, which is a very high place inside the app that doesn't have to be crowded too much.
If we have a big menu or if we need to use several different menus, triggered by actions inside app, this place is not appropriate for this purpose.
I want to hide the complexity of the menu in it's own container/component and handle the logic outside app.component.ts.
app.html should stay slim and a construction like the one below may be useful.
<app-menu></app-menu> // this should be the enclosing container of the menu logic
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
If I do this, the following error comes up:
Menu: must have a [content] element to listen for drag events on. Example:
<ion-menu [content]="content"></ion-menu>
<ion-nav #content></ion-nav>
Any thoughts on how to implement this, avoiding to add code directly to app.html and app.component.ts?
Tks

error code just tells you to write <ion-nav #content></ion-nav> if you use <ion-menu [content]="content"></ion-menu>...
example toggle menu code below ...
<ion-header>
<ion-navbar color="danger">
<ion-buttons start>
<button ion-button icon-only menuToggle>
<ion-icon name="menu">
</ion-icon>
</button>
</ion-buttons>
</ion-navbar>
<ion-menu [content]="content">
<ion-content padding>
this is awkmal
</ion-content>
</ion-menu>
</ion-header>
<ion-nav #content></ion-nav>

Related

Ionic ion-list-header with icon. Is it possible?

I'm trying to add an icon to ionic ion-list-header element in order to manage list item addition.
I tried the following code and it doesn't work. I start believing this is not admitted, but it looks quite silly at my eyes that it is not possible to add icons to a list header.
I appreciate your help.
Thanks in advance.
<ion-list-header color="primary">
<ion-icon name="add" slot="end"></ion-icon>
<ion-label>Header text</ion-label>
</ion-list-header>
Yes it is possible just put you icon and label in ion-item like this.
<ion-list-header color="primary">
<ion-item>
<ion-icon name="add" slot="end"></ion-icon>
<ion-label>Header text</ion-label>
</ion-item>
</ion-list-header>
For list-header, We can add an icon inside a button. Example:
<ion-list-header>
<ion-label>Header text</ion-label>
<ion-button>
<ion-icon name="add"></ion-icon>
</ion-button>
</ion-list-header>

Ionic2 custom components in Pages

I am using Ionic as a PWA. I use pages for navigation and I developed a component called common-header which displays the username and page name. It accepts an input called HeaderTitle and it displays the title. The component is declared in components.module.ts and I have imported the componentmodule in my PageModule. When I use the component in my page the component css styles does not work as expected.
If I remove the declaration of CommonHeader component in componentmodule and define in pagemodule the UI looks good.
This is the html code of CommonHeader.
<ion-navbar hideBackButton>
<ion-title>
{{UserName}}
</ion-title>
<ion-title>
{{HeaderTitle}}
</ion-title>
</ion-navbar>
Below is the Html code of my page
<ion-header>
<tr-header [HeaderTitle]="HeaderTitle"></tr-header>
</ion-header>
<ion-content padding>
Page Content
</ion-content>
The problem is CSS looks weird like the button does not have proper color/height. All this happens if I declare a component in componentmodule.ts and use the componentmodule file in my page module.
If I declare the component in my page module only it works great. But I need my custom component to be used in all the pages. What am I doing wrong?

Navigated automatically to wrong page after clicking in a button

I am newbie in ionic2, I have made a list of events with sliding Edit and Delete buttons. I have wanted to view the event details page by tapping on the row and it works fine. But if I tap on the edit button, the edit page appears and immediately replaced by event detail page. My code is following:
<ion-list>
<ion-item-sliding *ngFor="let event of eventList" (click)='goToEventDetail(event.id)'>
<ion-item><p><strong>{{event?.eventName}}</strong><p>
<p>Place: <strong>{{event?.place}}</strong></p>
<p>Date: <strong >{{event?.date}}</strong></p>
</ion-item>
<ion-item-options>
<button ion-button color="primary" (click)="goToEditEventDetail(event.id)"><ion-icon name='clipboard'></ion-icon> Edit</button>
<button ion-button color="danger" (click)="removeEvent(event.id)"><ion-icon name='trash'></ion-icon> Delete</button>
</ion-item-options>
</ion-item-sliding >
I have tried by removing "(click)='goToEventDetail(event.id)" event from "ion-item-sliding", in that case I have got expected result. My finding is, after clicking to edit button it fires "goToEditEventDetail" event and after that it also fires "goToEventDetail". I need to stop firing the second event, is there any solution? Thanks in advance.

How to programmatically hide header and tabs in landscape mode in Ionic 3?

I have one view in portrait mode and another in landscape mode where I want to show chart and I hide tabs and header (fullscreen mode, no scrolling). My view in landscape mode would look something like this:
<div showWhen="landscape" class="chart-settings split-container">
<ion-toolbar showWhen="landscape">
<ion-grid>
<ion-row>
<ion-col col-6>
<ion-item>
<ion-label>Period</ion-label>
<ion-select [(ngModel)]="period">
//options
</ion-select>
</ion-item>
</ion-col>
<ion-col col-6>
<ion-item>
<ion-label>Won/Lost</ion-label>
<ion-select [(ngModel)]="gender">
//options
</ion-select>
</ion-item>
</ion-col>
</ion-row>
</ion-grid>
</ion-toolbar>
<div class="flexChart">
<div id="chartdiv" [style.width.%]="100" [style.height.%]="100"></div>
</div>
I use flex to fill out the page and create "fullscreen effect with no scrolling".
Thanks
Well it seems there is this:
http://ionicframework.com/docs/api/platform/Platform/
It has:
isPortrait()
isLandscape()
so you can do:
platform.isPortrait() or platform.isLandscape()
if you inject platform into constructor.
Combine this with *NgIf:
https://angular.io/guide/template-syntax#ngif
CSS overflow, overflow-x, overflow-y is what you'd look to for prevent scrolling provided it's a block level container:
https://developer.mozilla.org/en/docs/Web/CSS/overflow
UPDATE
Based on this comment:
That was my initial thought. The problem with this is that it leaves
padding on top. I solved it by configuring styles, but it seemed
pretty dirty solution to me
You can fix that padding issue by getting the instance of the Content and call the resize() method like this:
import { Component, ViewChild } from '#angular/core';
import { Content } from 'ionic-angular';
#Component({...})
export class MyPage{
#ViewChild(Content) content: Content;
public yourMethod(): void {
this.content.resize();
}
}
https://ionicframework.com/docs/api/components/content/Content/#resize
Tell the content to recalculate its dimensions. This should be called
after dynamically adding/removing headers, footers, or tabs.
You can check landscape or portrait with platform, then you can get the ref of nav from template:
<ion-header>
<ion-navbar #navBar>
...
</ion-navbar>
</ion-header>
and call setHidden(true) in component with its ref:
#ViewChild('navBar') navBar: Navbar
// call in proper place
this.navBar.setHidden(true)
for tabs, I think you can do in the same way

hideBackButton attribute hides the menuToggle button too

The Problem
I push the Root Page to Page2 that supports a side menu, the issue is that when it opens Page2 it shows the back button and hides the menu button for that I've tried to add hideBackButton to Page2 in order to see the menu button but I both the back button and menu button disappeared!
Here is my current code:
<ion-navbar hideBackButton>
<button menuToggle start>
<ion-icon name="menu"></ion-icon>
</button>
</ion-navbar>
The expected behavior should be:
Should hide the back button, and show the menu button.
Ionic Version:
Ionic2
You can't do that following that way; however what you can do is to do a setRoot instead of pushing from the root to Page2
You can use following instead of your code:
<ion-toolbar hideBackButton>
<button menuToggle start>
<ion-icon name="menu"></ion-icon>
</button>
</ion-toolbar>
If you don't want to allow the "back" action on your Page2, and since you face a problem hiding the button, why not removing your root page from the history stack before accessing your Page2?
In such a case, the "back" action not gonna be allowed and the "back" button not gonna be displayed too.
About how to remove a page from the history stack before pushing another page, you could have a look at:
Remove a view from the back history - Ionic2