Disable the side menu's swipe to open gesture for Login page (or any page) in Ionic 2 - menu

I'm new to Ionic 2 & Angular2 and I have downloaded a new Ionic template with the following command
Ionic start appname sidemenu --v2 --ts
For this particular solution I have added a login page to validate a user. Once the validation succeeds the user will be navigated to the menu page which uses the side menu.
As the solution is based on the sidemenu template, the side menu is showing on the login page whenever the user swipes left.
So can somebody please guide me to rectify this mistake and stop the side menu from showing when the view is swiped.
My code
App.ts file
import {App, IonicApp, Platform,MenuController} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
import {HelloIonicPage} from './pages/hello-ionic/hello-ionic';
import {ListPage} from './pages/list/list';
import {HomePage} from './pages/home/home';
#App({
templateUrl: 'build/app.html',
config: {} // http://ionicframework.com/docs/v2/api/config/Config/
})
class MyApp {
// make HelloIonicPage the root (or first) page
rootPage: any = HomePage;
pages: Array<{title: string, component: any}>;
constructor(
private app: IonicApp,
private platform: Platform,
private menu: MenuController
) {
this.initializeApp();
// set our app's pages
this.pages = [
{ title: 'Hello Ionic', component: HelloIonicPage },
{ title: 'My First List', component: ListPage }
];
}
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();
});
}
openPage(page) {
// close the menu when clicking a link from the menu
this.menu.close();
// navigate to the new page if it is not the current page
let nav = this.app.getComponent('nav');
nav.setRoot(page.component);
}
}
app.html file
<ion-menu side-menu-content drag-content="false" [content]="content">
<ion-toolbar>
<ion-title>Pages</ion-title>
</ion-toolbar>
<ion-content>
<ion-list>
<button ion-item *ngFor="#p of pages" (click)="openPage(p)">
{{p.title}}
</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav id="nav" [root]="rootPage" #content swipe-back-enabled="false"></ion-nav>
Homepage.ts file (login page in this case).
import {Page, Events,Alert,NavController,Loading,Toast,Storage,LocalStorage,SqlStorage} from 'ionic-angular';
import { FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl } from 'angular2/common';
import {HelloIonicPage} from '../hello-ionic/hello-ionic';
import {NgZone} from 'angular2/core';
#Page({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
public Uname :string;
public usrvalid:boolean;
public usrpwd :boolean;
public usrpwdlength:boolean;
public usrvalidlength:boolean;
public isUnchanged:boolean;
public usrpwdzero:boolean;
public usrvaliddigits:boolean;
rootpage:any;
public Upwd:string;
constructor(public nav:NavController) {
this.nav=nav;
this.isUnchanged=true;
var mediumRegex = new RegExp("^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})");
// rootPage: any = HomePage;
}
}

I think the drag-content directive is used in ionic 1, for Ionic 2 what you can do is disable it from within your page class file.
You can do this by importing the MenuController provider from ionic-angular and then call the .swipeEnable(shouldEnableBoolean, menuId) method to disable the swipe gesture within your page's class (this is also documented here).
Your login controller should be something like this...
import {Page, MenuController} from 'ionic-angular';
#Page({
templateUrl: 'build/pages/home/home.html'
})
export class HomePage {
constructor(public menu: MenuController) {
this.menu.swipeEnable(false);
}
}
If you have multiple menus and each one has an id then you can target a specific menu like this...
this.menu.swipeEnable(false, `menuId`);

You can disable/enable sidemenu at any time at any page by calling
$ionicSideMenuDelegate.canDragContent(false)
e.g:
angular.module('ABC').controller('xyzCtrl', function($scope, $ionicSideMenuDelegate) {
$ionicSideMenuDelegate.canDragContent(false)
});

Related

How to add a Modal popup to lit element Project

I am developing a project using lit. Already developed two web components using lit.
I need to add image gallery, carousal, and also modal popup to open when click on a button inside those components.
And I saw that https://opensource.adobe.com/spectrum-web-components/components/card/ has already developed those components using lit. I installed one of those component to my lit project. But styles are no showing.
The question is, can I use those spectrum web components to lit project and why is styling now working.
Here is my component code with spectrum button,
import { LitElement, html, css} from 'lit';
import '#spectrum-web-components/button/sp-button.js';
import '#spectrum-web-components/button/sp-clear-button.js';
import { Button, ClearButton } from '#spectrum-web-components/button';
class plans_component extends LitElement {
static properties = {
...
}
static styles = [
...
]
constructor() {
super();
...
}
render() {
return html `
<sp-button size="xl">Extra Large</sp-button>
`
}
}
customElements.define('plans-component', plans_component);
Thanks in advance.

ionViewWillEnter doesn't work on entering the page

As the title suggests, my function doesn't trigger once I access the page itself. I have a button that is supposed to redirect me to another page, yet the page itself doesn't load nor the function. The code at the moment looks like this:
import {Component} from "#angular/core";
import {NavController, AlertController} from "ionic-angular";
#Component({
selector: 'page-patch-notes',
templateUrl: 'patch-notes.html'
})
export class PatchNotes {
constructor(private nav: NavController, private alertCtrl: AlertController) {
}
ionViewWillEnter() {
let alert = this.alertCtrl.create({
title: 'Patch Notes',
message: "Introduceti adresa de email pentru a va trimite un link de resetare parola.",
buttons: [
{
text: 'Anulati',
handler: data => {
console.log('Cancel clicked');
}
},
{
text: 'Ok',
handler: data => {
console.log('Ok clicked');
}
},
]
});
alert.present();
}
}
It's likely that the alert controller is created and displayed before the page is even loaded. Ionic lifecycles states that his hook fires
between the "Begin Page Transition" and "Page Fully Transitioned" stages.
I have had a lot of success tying this kind of logic to ngOnInit. You will need to update your class def to export class PatchNotes implements OnInit. The fact that this wasn't done suggests that fransicso neto's suggestion may be accurate as well. If you aren't already, it's always a good idea to generate pages using the Ionic CLI.

Get link of an image in react-photo-gallery?

I'm still a beginner in reactJS (using nodeJS backend) and I have to create a website to manage my collections. I don't know if what I'm going to ask you is feasible, but it probably is.
So I'm using a react component, react-photo-gallery. It's a component where you can use url links and it mixes them together to create a beautiful gallery.
https://github.com/neptunian/react-photo-gallery
I'm using nodeJS to get the information from the database, where I get the urls of all the pictures. For example I have a collection of cards, and an url of the image which represents the collection. What I want to do is get the link of the picture that I'm clicking on so I can use it in another component.
import React from 'react';
import { render } from 'react-dom';
import Gallery from 'react-photo-gallery';
import Photo from './Photo';
class PhotoGallery extends React.Component {
constructor(props){
super(props);
this.onClick = this.onClick.bind(this);
this.state = {
urlImages: []
};
}
async componentDidMount() {
var getUrlImages = 'http://localhost:3004';
const response = await fetch(getUrlImages+"/getUrlImages");
const newList = await response.json();
this.setState(previousState => ({
...previousState,
urlImages: newList,
}));
}
galleryPhotos() {
if(this.state.urlImages) {
return this.state.urlImages.map(function(urlimage) {
return { src: urlimage.urlimage, width: 2, height: 2 }
})
}
}
onClick() {
alert(this.galleryPhotos().value);
}
render() {
return (
<Gallery axis={"xy"} photos={this.galleryPhotos()} onClick={this.onClick}/>
)
}
}
const photos = [];
export default PhotoGallery;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Basically what I want to do is get the source link of the picture in the onClick function. Is that possible?
Thanks in advance!
Check the onClick event.
onClick(event) {
alert(event.target.src)
}
The DEMO
The onClick event of the Gallery component has a number of arguments:
the event
an object containing the selected index and the original photo object
You can use this in your onClick handler:
onClick(e, obj) {
const src = obj.photo.src
// do whatever you need with the src (setState, etc)
}

center paper-dialog upon opening

I'm trying to create a simple login window using Angular 2 and Polymer 1.0.2.
It's basically a paper-dialog (login window) with content. The dialog however is not positioned in the center of the screen, see this bugreport Dialog not centered until window resize #36:
The issue suggests calling the notifyResize() method on the paper-dialog. But I've no clue as how to refer to the paper-dialog instance in my angular 2/polymer class.
Somehow the import {PaperDialog} is not resolved, but looking in the paper-dialog.html makes me wondering if such an import is possible at all.
import {Component, View} from 'angular2/angular2';
import {PaperDialog} from 'bower_components/paper-dialog/paper-dialog';
#Component({
template: `
<paper-dialog open>
...
</paper-dialog>
`,
selector: 'login-window',
directives : [PaperDialog]
})
export class LoginWindow {
email: string;
password: string;
constructor(){
this.email = '';
this.password = '';
// Where and how to call the PaperDialog child's notifyResize() method
}
}
Note that I'm not opening the dialog programmatically (fix described here).
This solution uses the /deep/ selector that is deprecated.
And it shouldn't be fixed by applying some css, should it?
Instead of having my code fix the paper-dialog behaviour's code, it's way better to fix the problem itself.
Add the call this.notifyResize(); to the _onIronOverlayOpened method in the paper-dialog-behavior.html source.
...
_onIronOverlayOpened: function() {
if (this.modal) {
document.body.addEventListener('focus', this._boundOnFocus, true);
this.backdropElement.addEventListener('click', this._boundOnBackdropClick);
}
this.notifyResize(); // Added this line
},
...
Although this resolves my simple paper-dialog center problem, I can not oversee consequences for other elements and code yet.
You could also fix it in the following manner:
Within an angular2 Component (that wraps the paper-dialog element) you could so something like this (Typescript example):
interface PaperDialog extends HTMLElement {
notifyResize(): void;
}
#Component({
selector: 'login'
})
#View({
templateUrl: 'app/components/ts-login-window/ts-login-window.html'
})
export class LoginWindow {
email: string;
password: string;
dialogWindow: PaperDialog;
private bindIronOverlayOpened: EventListenerObject;
constructor(elementRef: ElementRef){
this.dialogWindow = elementRef.nativeElement.children[0];
this.bindIronOverlayOpened = this.ironOverlayOpened.bind(this);
this.dialogWindow.addEventListener('iron-overlay-opened', this.bindIronOverlayOpened);
}
ironOverlayOpened(event: Event) {
this.dialogWindow.notifyResize();
}
onDestroy() {
this.dialogWindow.removeEventListener('iron-overlay-opened', this.bindIronOverlayOpened);
}
}
Once the paper-dialog has been opened (by the event iron-overlay-opened) you could trigger the notifyResize() event on the dialog box. This in turn fixes the alignment problem.

Integrating WinJS and Angular2

I'm trying to wrap a WinJS rating control in an Angular2 component. When I debug, I can see that WinJS.UI.processAll(); is being called and executed. But I don't see the rating control.
How can I make it work?
Dashboard.cshtml:
#{
ViewBag.Title = "Dashboard";
}
<my-app></my-app>
<script src="/jspm_packages/system.js"></script>
<script src="/config.js"></script>
<script>
System.import('reflect-metadata')
.then(function () {
System.import('angular2')
.then(function () {
System.import("/js/app");
});
});
</script>
app.js:
import { Component, View, bootstrap } from 'angular2';
import 'reflect-metadata';
import 'winjs';
#Component({
selector: 'my-app'
})
#View({
template: '<div data-win-control=\'WinJS.UI.Rating\' data-win-options=\'{averageRating: 3.4}\'></div>'
})
class MyAppComponent {
constructor() {
}
onInit() {
WinJS.UI.processAll();
}
}
bootstrap(MyAppComponent);
As requested by #wonderfulworld
First of all, according to Adding the Windows Library for JavaScript to your page you must add the css file to your html.
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/winjs/4.3.0/css/ui-light.min.css">
Second thing, from alpha37+ you must import and implement the lifecycle hook you're using, onInit in this case (see remove LifecycleEvent).
import { Component, View, bootstrap, OnInit} from 'angular2/angular2';
import 'reflect-metadata';
import 'winjs';
#Component({
selector: 'my-app'
})
#View({
template: '<div data-win-control=\'WinJS.UI.Rating\' data-win-options=\'{averageRating: 3.4}\'></div>'
})
class MyAppComponent implements OnInit {
onInit() {
WinJS.UI.processAll();
}
}
And that would be all. Here's the plnkr.
Glad it helped ;)

Resources