ionic app doesn't switch between pages - ionic-framework

I am only asking for someone to please look at my code and tell me why I can't go from login to sign up page after clicking a button.
my login page code is
<ion-view view-title="Login" >
<ion-content class="padding">
<label class="item item-input">
<input type="text" placeholder="email">
</label>
<label class="item item-input">
<input type="text" placeholder="Password">
</label>
<button class="button">login</button>
<a nav-transition="android" href="#/sign-up">
<button class="button">Sign up</button>
</a>
<button class="button">Forgot password</button>
</ion-content>
my sign up page looks like this
<ion-view view-title="Sign Up" >
<!-- content goes here -->
<ion-list>
<ion-item>
<h2>My Profile</h2>
<div class="list">
<label class="item item-input">
<span class="input-label">Age*</span>
<input type="range" name="volume" min="18" max="100" value="21">
</label>
<label class="item item-input">
<span class="input-label">Gender*</span>
<select>
<option>Male</option>
<option>Female</option>
</select>
</label>
</div>
</ion-item>
</ion-list>
</ion-content>
finally my app.js page looks like
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js
angular.module('social-arena', ['ionic', 'social-arena.controllers', 'social-arena.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
}
}
})
.state('signup', {
url: '/signup',
views: {
'signup': {
templateUrl: 'templates/sign-up.html',
controller: 'SignUpCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/login');
});

You can use ui-sref to go to a state:
<a nav-transition="android" ui-sref="signup">
Or href to go to a url:
<a nav-transition="android" href="#/signup">

You want your href to look like this:
<a nav-transition="android" href="#/signup">
the href should match the url you give in your state:
.state('signup', {
url: '/signup', // should match this
views: {
'signup': {
templateUrl: 'templates/sign-up.html', //not this
controller: 'SignUpCtrl'
}
}
});
not the template url.
edit
I see in the comments in your code that you are trying to use the tabs directive and I also noticed that you are missing an abstract state, Ionic's guide for setting up routing can help you through the steps.
From the example on Ionic Docs
$stateProvider.state('app.todos', {
abstract: true,
url: '/todos',
views: {
todos: {
template: '<ion-nav-view></ion-nav-view>'
}
}
})
As you can see, they set one view as and abstract
abstract:true,
and then have the rest of your views link to the abstract, again from the docs:
$stateProvider.state('app.todos.index', {
url: '',
templateUrl: 'todos.html',
controller: 'TodosCtrl'
})

Related

Child states not rendering with parent state in Ionic V-1

enter image description hereI'm new to Ionic v-1. I tried implementing navigation using parent-child relationship. The parent state is "tab" while the active child state is "home". When I load the app, the home state contents do not load.
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider,$urlRouterProvider){
$stateProvider
.state('tabs',{
url:"/tab",
abstract:true,
templateUrl:"templates/tabs.html"
})
.state('tabs.home', {
url: "/home",
views: {
'home-tab': {
templateUrl: "templates/home.html",
controller: 'HomeTabCtrl'
}
}
})
.state('tabs.addFriend',{
url:"/addFriend",
views:{
'addFriend-tab':{
templateUrl:"templates/addFriend.html",
controller:'addFriendTabController'
}
}
})
.state('tabs.message',{
url:"/message",
views:{
'message-tab':{
templateUrl:"templates/message.html",
controller:'messageTabController'
}
}
})
.state('tabs.notifications',{
url:"/notifications",
views:{
'notifications-tab':{
templateUrl:"templates/notifications.html",
controller:'notificationsTabController'
}
}
})
.state('tabs.profile',{
url:"/profile",
views:{
'profile-tab':{
templateUrl:"templates/profile.html",
controller:'profileTabController'
}
}
});
$urlRouterProvider.otherwise("/tab/home");
})
.controller('HomeTabCtrl',function($scope){
console.log("Home tab");
})
.controller('addFriendTabController',function($scope){
console.log("addFriend tab");
})
.controller('messageTabController',function($scope){
console.log("message tab");
})
.controller('notificationsTabController',function($scope){
console.log("notifications tab");
})
.controller('profileTabController',function($scope){
console.log("profile tab");
});
<body ng-app="starter">
<ion-pane>
<div class="bar bar-positive item-input-inset headerBorder">
<label class="item-input-wrapper positive-bg" id="headerSearch">
<i class="icon ion-ios-search placeholder-icon searchIcon"></i>
<input type="search" placeholder="People, jobs, posts and more...">
</label>
<i class="icon ion-grid placeholder-icon searchIcon"></i>
</div>
<ion-nav-view></ion-nav-view>
<script id="templates/tabs.html" type="text/ng-template">
<div class="tabs-stripped tabs-top tabs-background-positive tabs-color-light">
<div class="tabs tab-top">
<a href="#/tab/home" class="tab-item active">
<i class="icon ion-home"></i>
</a>
<a href="#/tab/addFriend" class="tab-item">
<i class="icon ion-person-stalker"></i>
</a>
<a href="#/tab/message" class="tab-item">
<i class="icon ion-chatboxes"></i>
</a>
<a href="#/tab/notifications" class="tab-item">
<i class="icon ion-android-notifications"></i>
</a>
<a href="#/tab/profile" class="tab-item">
<i class="icon ion-person"></i>
</a>
</div>
</div>
</script>
<script id="templates/home.html" type="text/ng-template">
<ion-content class="has-tabs-top">
<div class="list card">
<div class="item item-thumbnail-left">
<img src="img/ionic.png">
<h2 class="listCss">Name</h2>
<h3>Followers</h3>
<p>Time</p>
</div>
<div class="item item-image">
<img src="img/NIKHIL.jpg">
</div>
Click here...
</div>
</ion-content>
</script>
<script id="templates/addFriend.html" type="text/ng-template">
</script>
<script id="templates/message.html" type="text/ng-template">
</script>
<script id="templates/notifications.html" type="text/ng-template">
</script>
<script id="templates/profile.html" type="text/ng-template">
</script>
</ion-pane>
</body>
if you want to use multiple named views you've to do like so for exmaple:
IN you HTML:
<ion-tabs class="tabs-icon-bottom tabs-color-light tabs-background-brown">
<ion-tab title="LAST SCAN" icon-off="fwd-last-scan-off" icon-on="fwd-last-scan-on" ui-sref="tab.lastscan">
<ion-nav-view name="tab-left"></ion-nav-view>
</ion-tab>
<ion-tab title="SCAN" icon-off="fwd-total-scan-off" icon-on="fwd-total-scan-on" ui-sref="tab.scan">
<ion-nav-view name="tab-center"></ion-nav-view>
</ion-tab>
<ion-tab title="MENU" icon-off="fwd-menu-off" icon-on="fwd-menu-on" ui-sref="tab.menu">
<ion-nav-view name="tab-right"></ion-nav-view>
</ion-tab>
<ion-tab title="EXTRA" icon-off="fwd-extra-off" icon-on="fwd-extra-on">
<ion-nav-view name="tab-off"></ion-nav-view>
</ion-tab>
</ion-tabs>
In your JS:
"use strict";
angular.module("gestione")
.config(["$stateProvider", "$urlRouterProvider", "$ionicConfigProvider", "$httpProvider", "$ionicNativeTransitionsProvider",
function ($stateProvider, $urlRouterProvider, $ionicConfigProvider, $httpProvider, $ionicNativeTransitionsProvider) {
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise("/tab/login");
$stateProvider
// setup an abstract state for the tabs directive
.state("tab", {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
// Each tab has its own nav history stack:
.state("tab.lastscan", {
url: "/lastscan",
cache: false,
nativeTransitions: {
"type": "filp",
"direction": "up"
},
views: {
'tab-left': {
templateUrl: "templates/tab-lastscan.html",
controller: "LastScanCtrl",
controllerAs: "lastscan"
}
}
})
.state("tab.menu", {
url: "/menu",
views: {
'tab-right': {
templateUrl: "templates/tab-menu.html",
controller: "MenuCtrl"
}
}
})
.state("tab.settings", {
url: "/settings",
cache: false,
views: {
'tab-off': {
templateUrl: "templates/settings.html",
controller: "SettingCtrl",
controllerAs: "settingCtrl"
}
}
})
;
}]);

pull to refresh in ionic does not refresh my list

Using ionic pull to refresh function does not update my list. Function is called and in console data is retrieved from serve but does not refresh my list.
here is my view:
<ion-list>
<ion-item class="list card" ng-repeat="pickup in pickups">
<div class="item">
<h2>{{pickup.title}}</h2>
<p>Request Date : {{pickup.added_date}}</p>
<p>Status :
<span class="positive" ng-if="pickup.status==0">On Queue</span>
<span class="energized" ng-if="pickup.status==1">On Process</span>
<span class="balanced" ng-if="pickup.status==2">On Collected</span>
<span class="assertive" ng-if="pickup.status==2">Cancelled</span>
</p>
</div>
<div class="item item-body">
<p>Contact : {{pickup.b_contact}}</p>
<p>Location : {{pickup.b_location}}</p>
<p>
<a class="button circular-btn icon ion-android-done button-energized" href="#"
ng-click="statusData(pickup.pickupid,pickup.user_id,1)"
ng-if="pickup.status==0"></a>
<a class="button circular-btn ion-android-done-all button-balanced" href="#"
ng-click="statusData(pickup.pickupid,pickup.user_id,2)"
ng-if="pickup.status==0|| pickup.status==1"></a>
<a class="button circular-btn icon ion-close-circled button-assertive" href="#"
ng-click="statusData(pickup.pickupid,pickup.user_id,3)"
ng-if="pickup.status==0|| pickup.status==1|| pickup.status==2"></a>
</p>
</div>
</ion-item>
</ion-list>
</ion-content>
my controller code:
.controller('AppCtrl', function ($scope, Service, $ionicLoading, $ionicModal, $ionicPopup, $timeout, $state, $http, $stateParams) {
$scope.doRefresh = function () {
Service.getpickup($state, $http).success(function (data) {
$scope.pickups = data.pickup_request;
console.log(data.pickup_request);
})
.finally(function () {
$scope.$broadcast('scroll.refreshComplete');
});
}
});
Please guide me. Thanks in advance.
Have you used the ion-refresher tag in your html? I cant see it in your code. If not, use this
<ion-refresher pulling-text="Pull to refresh..." on-refresh="doRefresh()">
Also, try manually adding the items to your list like this and see if that works. (check that data.pickup_request is an array as well)
$scope.pickups.push.apply($scope.pickups, data.pickup_request);
I have found the issues. I have the view in pickupCtrl but i was calling the scope function in another control. Thank you every one for your guide.Thanks a lot.

Ionic Return value navigation on different view

I have a form view with an input text. When I click on this input, another view is opened.
In this view, there are an input search and a list. The list change when I change a text from the input search.
I want when I click one item of the list, this view gets closed and the input text change. But I don't know how I can do that.
Can you help me please?
the input text in my form view:
<div class="select-typeevent">
<ion-item nav-clear menu-close ui-sref="menu.setlocation">
<label class="padding">
Address:
</label>
</ion-item>
</div>
My searchview:
<ion-view view-title="Address" class="content">
<ion-content>
<h1>Address</h1>
<div class="bar bar-header item-input-inset">
<label class="item-input-wrapper">
<i class="icon ion-ios-search placeholder-icon"></i>
<input class="border-none" name="txtssearch" type="search" placeholder="Search" ng-model="addresssearch" ng-change="getGeocode(addresssearch)">
</label>
<button class="button button-clear" ng-click="addresssearch='';getGeocode(addresssearch)">
Annuler
</button>
</div>
<div class="list" >
<a ng-repeat="addr in addresslist" class="item" ng-click="setaddress(addr)">
{{addr.address}} {{addr.location}}
</a>
</div>
</ion-content>
</ion-view>
And the js:
'Use Strict';
angular.module('App').controller('setlocationController', function ($scope,$state, $cordovaOauth, $localStorage, $location, $http, $ionicPopup,$firebaseObject,$ionicHistory, Auth, FURL, Utils) {
$scope.getGeocode = function (addresssearch) {
$scope.geodata = {};
$scope.queryResults = {};
$scope.queryError = {};
$http.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + addresssearch)
.then(function (_results) {
$scope.addresslist = [];
$scope.queryResults = _results.data.results;
console.log($scope.queryResults);
$scope.queryResults.forEach(function(result) {
$scope.addresslist.push({ 'address': result.formatted_address, 'location': result.geometry.location });
});
},
function error(_error){
$scope.queryError = _error;
})
};
// Here I want when I click one item of the list, this view gets closed and the input text of formview change.
$scope.setaddress = function (addr) {
$scope.setaddress = addr;
$ionicHistory.backView();
}
Why not using an $ionicModal:
$scope.getGeocode = function (addresssearch) {
...
$scope.modal.show();
}
Previously set the modal:
$ionicModal.fromTemplateUrl('my-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
Where my-modal.html points to the template which shows geocode information.

Angular 2.0 and Modal Dialog

I am trying to find some examples on how to do a Confirmation modal dialog in Angular 2.0. I have been using Bootstrap dialog for Angular 1.0 and unable to find any examples in the web for Angular 2.0. I also checked angular 2.0 docs with no luck.
Is there a way to use the Bootstrap dialog with Angular 2.0?
Angular 2 and up
Bootstrap css (animation is preserved)
NO JQuery
NO bootstrap.js
Supports custom modal content (just like accepted answer)
Recently added support for multiple modals on top of each other.
`
#Component({
selector: 'app-component',
template: `
<button type="button" (click)="modal.show()">test</button>
<app-modal #modal>
<div class="app-modal-header">
header
</div>
<div class="app-modal-body">
Whatever content you like, form fields, anything
</div>
<div class="app-modal-footer">
<button type="button" class="btn btn-default" (click)="modal.hide()">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</app-modal>
`
})
export class AppComponent {
}
#Component({
selector: 'app-modal',
template: `
<div (click)="onContainerClicked($event)" class="modal fade" tabindex="-1" [ngClass]="{'in': visibleAnimate}"
[ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<ng-content select=".app-modal-header"></ng-content>
</div>
<div class="modal-body">
<ng-content select=".app-modal-body"></ng-content>
</div>
<div class="modal-footer">
<ng-content select=".app-modal-footer"></ng-content>
</div>
</div>
</div>
</div>
`
})
export class ModalComponent {
public visible = false;
public visibleAnimate = false;
public show(): void {
this.visible = true;
setTimeout(() => this.visibleAnimate = true, 100);
}
public hide(): void {
this.visibleAnimate = false;
setTimeout(() => this.visible = false, 300);
}
public onContainerClicked(event: MouseEvent): void {
if ((<HTMLElement>event.target).classList.contains('modal')) {
this.hide();
}
}
}
To show the backdrop, you'll need something like this CSS:
.modal {
background: rgba(0,0,0,0.6);
}
The example now allows for multiple modals at the same time. (see the onContainerClicked() method).
For Bootstrap 4 css users, you need to make 1 minor change (because a css class name was updated from Bootstrap 3). This line:
[ngClass]="{'in': visibleAnimate}" should be changed to:
[ngClass]="{'show': visibleAnimate}"
To demonstrate, here is a plunkr
Here's a pretty decent example of how you can use the Bootstrap modal within an Angular2 app on GitHub.
The gist of it is that you can wrap the bootstrap html and jquery initialization in a component. I've created a reusable modal component that allows you to trigger an open using a template variable.
<button type="button" class="btn btn-default" (click)="modal.open()">Open me!</button>
<modal #modal>
<modal-header [show-close]="true">
<h4 class="modal-title">I'm a modal!</h4>
</modal-header>
<modal-body>
Hello World!
</modal-body>
<modal-footer [show-default-buttons]="true"></modal-footer>
</modal>
You just need to install the npm package and register the modal module in your app module:
import { Ng2Bs3ModalModule } from 'ng2-bs3-modal/ng2-bs3-modal';
#NgModule({
imports: [Ng2Bs3ModalModule]
})
export class MyAppModule {}
This is a simple approach that does not depend on jquery or any other library except Angular 2.
The component below (errorMessage.ts) can be used as a child view of any other component. It is simply a bootstrap modal that is always open or shown. It's visibility is governed by the ngIf statement.
errorMessage.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-error-message',
templateUrl: './app/common/errorMessage.html',
})
export class ErrorMessage
{
private ErrorMsg: string;
public ErrorMessageIsVisible: boolean;
showErrorMessage(msg: string)
{
this.ErrorMsg = msg;
this.ErrorMessageIsVisible = true;
}
hideErrorMsg()
{
this.ErrorMessageIsVisible = false;
}
}
errorMessage.html
<div *ngIf="ErrorMessageIsVisible" class="modal fade show in danger" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Error</h4>
</div>
<div class="modal-body">
<p>{{ErrorMsg}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" (click)="hideErrorMsg()">Close</button>
</div>
</div>
</div>
</div>
This is an example parent control (some non-relevant code has been omitted for brevity):
parent.ts
import { Component, ViewChild } from '#angular/core';
import { NgForm } from '#angular/common';
import {Router, RouteSegment, OnActivate, ROUTER_DIRECTIVES } from '#angular/router';
import { OnInit } from '#angular/core';
import { Observable } from 'rxjs/Observable';
#Component({
selector: 'app-application-detail',
templateUrl: './app/permissions/applicationDetail.html',
directives: [ROUTER_DIRECTIVES, ErrorMessage] // Note ErrorMessage is a directive
})
export class ApplicationDetail implements OnActivate
{
#ViewChild(ErrorMessage) errorMsg: ErrorMessage; // ErrorMessage is a ViewChild
// yada yada
onSubmit()
{
let result = this.permissionsService.SaveApplication(this.Application).subscribe(x =>
{
x.Error = true;
x.Message = "This is a dummy error message";
if (x.Error) {
this.errorMsg.showErrorMessage(x.Message);
}
else {
this.router.navigate(['/applicationsIndex']);
}
});
}
}
parent.html
<app-error-message></app-error-message>
// your html...
Now available as a NPM package
angular-custom-modal
#Stephen Paul continuation...
Angular 2 and up Bootstrap css (animation is preserved)
NO JQuery
NO bootstrap.js
Supports custom modal content
Support for multiple modals on top of each
other.
Moduralized
Disable scroll when modal is open
Modal gets destroyed when navigating away.
Lazy content initialization, which gets ngOnDestroy(ed) when the modal is exited.
Parent scrolling disabled when modal is visible
Lazy content initialization
Why?
In some cases you might not want to modal to retain its status after having been closed, but rather restored to the initial state.
Original modal issue
Passing the content straightforward into the view actually generates initializes it even before the modal gets it. The modal doesn't have a way to kill such content even if using a *ngIf wrapper.
Solution
ng-template. ng-template doesn't render until ordered to do so.
my-component.module.ts
...
imports: [
...
ModalModule
]
my-component.ts
<button (click)="reuseModal.open()">Open</button>
<app-modal #reuseModal>
<ng-template #header></ng-template>
<ng-template #body>
<app-my-body-component>
<!-- This component will be created only when modal is visible and will be destroyed when it's not. -->
</app-my-body-content>
<ng-template #footer></ng-template>
</app-modal>
modal.component.ts
export class ModalComponent ... {
#ContentChild('header') header: TemplateRef<any>;
#ContentChild('body') body: TemplateRef<any>;
#ContentChild('footer') footer: TemplateRef<any>;
...
}
modal.component.html
<div ... *ngIf="visible">
...
<div class="modal-body">
ng-container *ngTemplateOutlet="body"></ng-container>
</div>
References
I have to say that it wouldn't have been possible without the excellent official and community documentation around the net. It might help some of you too to understand better how ng-template, *ngTemplateOutlet and #ContentChild work.
https://angular.io/api/common/NgTemplateOutlet
https://blog.angular-university.io/angular-ng-template-ng-container-ngtemplateoutlet/
https://medium.com/claritydesignsystem/ng-content-the-hidden-docs-96a29d70d11b
https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e
https://netbasal.com/understanding-viewchildren-contentchildren-and-querylist-in-angular-896b0c689f6e
Full copy-paste solution
modal.component.html
<div
(click)="onContainerClicked($event)"
class="modal fade"
tabindex="-1"
[ngClass]="{'in': visibleAnimate}"
[ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}"
*ngIf="visible">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<ng-container *ngTemplateOutlet="header"></ng-container>
<button class="close" data-dismiss="modal" type="button" aria-label="Close" (click)="close()">×</button>
</div>
<div class="modal-body">
<ng-container *ngTemplateOutlet="body"></ng-container>
</div>
<div class="modal-footer">
<ng-container *ngTemplateOutlet="footer"></ng-container>
</div>
</div>
</div>
</div>
modal.component.ts
/**
* #Stephen Paul https://stackoverflow.com/a/40144809/2013580
* #zurfyx https://stackoverflow.com/a/46949848/2013580
*/
import { Component, OnDestroy, ContentChild, TemplateRef } from '#angular/core';
#Component({
selector: 'app-modal',
templateUrl: 'modal.component.html',
styleUrls: ['modal.component.scss'],
})
export class ModalComponent implements OnDestroy {
#ContentChild('header') header: TemplateRef<any>;
#ContentChild('body') body: TemplateRef<any>;
#ContentChild('footer') footer: TemplateRef<any>;
public visible = false;
public visibleAnimate = false;
ngOnDestroy() {
// Prevent modal from not executing its closing actions if the user navigated away (for example,
// through a link).
this.close();
}
open(): void {
document.body.style.overflow = 'hidden';
this.visible = true;
setTimeout(() => this.visibleAnimate = true, 200);
}
close(): void {
document.body.style.overflow = 'auto';
this.visibleAnimate = false;
setTimeout(() => this.visible = false, 100);
}
onContainerClicked(event: MouseEvent): void {
if ((<HTMLElement>event.target).classList.contains('modal')) {
this.close();
}
}
}
modal.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { ModalComponent } from './modal.component';
#NgModule({
imports: [
CommonModule,
],
exports: [ModalComponent],
declarations: [ModalComponent],
providers: [],
})
export class ModalModule { }
I use ngx-bootstrap for my project.
You can find the demo here
The github is here
How to use:
Install ngx-bootstrap
Import to your module
// RECOMMENDED (doesn't work with system.js)
import { ModalModule } from 'ngx-bootstrap/modal';
// or
import { ModalModule } from 'ngx-bootstrap';
#NgModule({
imports: [ModalModule.forRoot(),...]
})
export class AppModule(){}
Simple static modal
<button type="button" class="btn btn-primary" (click)="staticModal.show()">Static modal</button>
<div class="modal fade" bsModal #staticModal="bs-modal" [config]="{backdrop: 'static'}"
tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title pull-left">Static modal</h4>
<button type="button" class="close pull-right" aria-label="Close" (click)="staticModal.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
This is static modal, backdrop click will not close it.
Click <b>×</b> to close modal.
</div>
</div>
</div>
</div>
Here is my full implementation of modal bootstrap angular2 component:
I assume that in your main index.html file (with <html> and <body> tags) at the bottom of <body> tag you have:
<script src="assets/js/jquery-2.1.1.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
modal.component.ts:
import { Component, Input, Output, ElementRef, EventEmitter, AfterViewInit } from '#angular/core';
declare var $: any;// this is very importnant (to work this line: this.modalEl.modal('show')) - don't do this (becouse this owerride jQuery which was changed by bootstrap, included in main html-body template): let $ = require('../../../../../node_modules/jquery/dist/jquery.min.js');
#Component({
selector: 'modal',
templateUrl: './modal.html',
})
export class Modal implements AfterViewInit {
#Input() title:string;
#Input() showClose:boolean = true;
#Output() onClose: EventEmitter<any> = new EventEmitter();
modalEl = null;
id: string = uniqueId('modal_');
constructor(private _rootNode: ElementRef) {}
open() {
this.modalEl.modal('show');
}
close() {
this.modalEl.modal('hide');
}
closeInternal() { // close modal when click on times button in up-right corner
this.onClose.next(null); // emit event
this.close();
}
ngAfterViewInit() {
this.modalEl = $(this._rootNode.nativeElement).find('div.modal');
}
has(selector) {
return $(this._rootNode.nativeElement).find(selector).length;
}
}
let modal_id: number = 0;
export function uniqueId(prefix: string): string {
return prefix + ++modal_id;
}
modal.html:
<div class="modal inmodal fade" id="{{modal_id}}" tabindex="-1" role="dialog" aria-hidden="true" #thisModal>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header" [ngClass]="{'hide': !(has('mhead') || title) }">
<button *ngIf="showClose" type="button" class="close" (click)="closeInternal()"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<ng-content select="mhead"></ng-content>
<h4 *ngIf='title' class="modal-title">{{ title }}</h4>
</div>
<div class="modal-body">
<ng-content></ng-content>
</div>
<div class="modal-footer" [ngClass]="{'hide': !has('mfoot') }" >
<ng-content select="mfoot"></ng-content>
</div>
</div>
</div>
</div>
And example of usage in client Editor component:
client-edit-component.ts:
import { Component } from '#angular/core';
import { ClientService } from './client.service';
import { Modal } from '../common';
#Component({
selector: 'client-edit',
directives: [ Modal ],
templateUrl: './client-edit.html',
providers: [ ClientService ]
})
export class ClientEdit {
_modal = null;
constructor(private _ClientService: ClientService) {}
bindModal(modal) {this._modal=modal;}
open(client) {
this._modal.open();
console.log({client});
}
close() {
this._modal.close();
}
}
client-edit.html:
<modal [title]='"Some standard title"' [showClose]='true' (onClose)="close()" #editModal>{{ bindModal(editModal) }}
<mhead>Som non-standart title</mhead>
Some contents
<mfoot><button calss='btn' (click)="close()">Close</button></mfoot>
</modal>
Ofcourse title, showClose, <mhead> and <mfoot> ar optional parameters/tags.
Check ASUI dialog which create at runtime. There is no need of hide and show logic. Simply service will create a component at runtime using AOT
ASUI NPM
try to use ng-window, it's allow developer to open and full control multiple windows in single page applications in simple way, No Jquery, No Bootstrap.
Avilable Configration
Maxmize window
Minimize window
Custom size,
Custom posation
the window is dragable
Block parent window or not
Center the window or not
Pass values to chield window
Pass values from chield window to parent window
Listening to closing chield window in parent window
Listen to resize event with your custom listener
Open with maximum size or not
Enable and disable window resizing
Enable and disable maximization
Enable and disable minimization
Angular 7 + NgBootstrap
A simple way of opening modal from main component and passing result back to it. is what I wanted. I created a step-by-step tutorial which includes creating a new project from scratch, installing ngbootstrap and creation of Modal. You can either clone it or follow the guide.
Hope this helps new to Angular.!
https://github.com/wkaczurba/modal-demo
Details:
modal-simple template (modal-simple.component.html):
<ng-template #content let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Are you sure?</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>You have not finished reading my code. Are you sure you want to close?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-dark" (click)="modal.close('yes')">Yes</button>
<button type="button" class="btn btn-outline-dark" (click)="modal.close('no')">No</button>
</div>
</ng-template>
The modal-simple.component.ts:
import { Component, OnInit, ViewChild, Output, EventEmitter } from '#angular/core';
import { NgbModal } from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'app-modal-simple',
templateUrl: './modal-simple.component.html',
styleUrls: ['./modal-simple.component.css']
})
export class ModalSimpleComponent implements OnInit {
#ViewChild('content') content;
#Output() result : EventEmitter<string> = new EventEmitter();
constructor(private modalService : NgbModal) { }
open() {
this.modalService.open(this.content, {ariaLabelledBy: 'modal-simple-title'})
.result.then((result) => { console.log(result as string); this.result.emit(result) },
(reason) => { console.log(reason as string); this.result.emit(reason) })
}
ngOnInit() {
}
}
Demo of it (app.component.html) - simple way of dealing with return event:
<app-modal-simple #mymodal (result)="onModalClose($event)"></app-modal-simple>
<button (click)="mymodal.open()">Open modal</button>
<p>
Result is {{ modalCloseResult }}
</p>
app.component.ts - onModalClosed is executed once modal is closed:
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
modalCloseResult : string;
title = 'modal-demo';
onModalClose(reason : string) {
this.modalCloseResult = reason;
}
}
Cheers

Ionic - Showing side-menu ONLY in concrete pages

I'm developing an App with Ionic Framework, and I only want to show a side-menu in some concrete views, but not in every view.
I' have my menu.html file:
<ion-side-menus>
<ion-pane ion-side-menu-content>
<ion-nav-bar class="bar-positive nav-title-slide-ios7">
</ion-nav-bar>
<ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view>
</ion-pane>
<ion-side-menu side="left">
<ion-content class="mymenu">
<div id="menu-list">
<ion-list class="list">
<ion-item item-type="item-icon-left" nav-clear menu-close href="#">
<i class="icon ion-home"></i><span>Menu Item</span>
</ion-item>
...
</ion-list>
</div>
</ion-content>
</ion-side-menu>
</ion-side-menus>
My index.html's body tag looks exactly like this:
<body ng-app="myApp">
<ion-nav-view></ion-nav-view>
</body>
And the JavaScript code where I set up my App states:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.page1', {
url: "/page1",
views: {
'menuContent' :{
templateUrl: "templates/page1.html"
}
}
})
.state('app.page2', {
url: "/page2",
views: {
'menuContent' :{
templateUrl: "templates/page2.html"
}
}
})
// etc...
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/page1');
});
page1.html and page2.html both contain the following structure:
<ion-view title="something">
<ion-content>
... // here comes the html content of the page
</ion-content>
</ion-view>
What can I actually do to only show my side-menu (menu.html) on page1.html and not on page2.html?? Is there anything I'm missing??
Is there a way of inserting the menu.html content only on those pages I want it to appear and forgetting about creating the state that uses it as templateUrl?
The reason why your all your pages have side menu is because you 'app' state as their parent state. When a state is activated, its templates are automatically inserted into the <ion-view> of its parent state's template. If it's a top-level state, because it has no parent state then its parent template is index.html. The app state has the side menu in it.
Your code should look like this:
config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
//this state has the 'app' state (which has the sidemenu) as its parent state
.state('app.page1', {
url: "/page1",
views: {
'menuContent' :{
templateUrl: "templates/page1.html"
}
}
})
//this state has no parent, so it uses 'index.html' as its template. The index page has no
//sidemenu in it
.state('page2', {
url: "/page2",
templateUrl: "templates/page2.html"
}
})
///more code here
});
Check out https://github.com/angular-ui/ui-router/wiki
if your problem is simple , use
onExit: function(){
angular.element(document.querySelector('#menuAPP')).removeClass('hidden');
}
into state
just add hide-nav-bar=" true " in ion-view
<ion-view title="Login" **hide-nav-bar="true"** id="page" class=" "> </ion-view>