Using Ionic tabs on a side menu page - angularjs

I am new to the ionic framework and was trying to achieve using the tabs component on a side menu page which works fine but the navigation animations from page to page with the slide-left-right animation declaration don't work.
for e.g.
there is a base state (app) which holds the side menu code
.state('app', {
url: '/app',
abstract: true,
templateUrl: "templates/menu.html",
controller: "appController"
})
and its loaded into
<body>
<ion-nav-view animation="slide-left-right"></ion-nav-view>
...
side menu pages are loaded with the parent (app.pageOne, app.pageTwo etc)
Login and register pages are loaded at the root so is no need to include a side menu (login, register etc)
I created a tabs template to use on a side menu page with another base state for the tabs
.state('app.tabs', {
url: '/tab',
abstract: true,
views: {
'menuContent' :{
templateUrl: "templates/tabs.html"
}
}
})
and is loaded in the side menu view
<ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view>
Now if I have a page 'app.pageOne' and navigate to 'app.pageTwo' the slide animations works as expected.
But if I'm on a tab page 'app.tabs.home' and click a link to go to 'app.pageTwo' the nav-bar don't update nor is there any animation transition.
I'm aware it looks like a parent child issue but I just can't solve it, any ideas?
state are as follows eg
login
register
app ____page1
|____page2
|____Tabs
|____Home
|____Contact etc
page1 animation to page2 works fine
Home to page2 doesn't animate (It just loads straight away)
Hope that makes more sense.

check this url http://codepen.io/calendee/pen/JdtuG?editors=101
it works for me :)
html
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic Template</title>
<link href="http://code.ionicframework.com/0.9.27/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/0.9.27/js/ionic.bundle.min.js"></script>
</head>
<body>
<!-- ALL VIEW STATES LOADED IN HERE -->
<ion-nav-view></ion-nav-view>
<script id="entry.html" type="text/ng-template">
<ion-nav-bar animation="nav-title-slide-ios7"
type="bar-positive"
back-button-type="button-icon"
back-button-icon="ion-ios7-arrow-back">
</ion-nav-bar>
<ion-view title="{{navTitle}}" class="bubble-background">
<ion-content has-header="true" padding="true">
<h1>Entry Page!</h1>
<a class="button button-positive" ng-click="signIn()" ui-sref="main.home">Sign In</a>
</ion-content>
</ion-view>
</script>
<script id="tabs.html" type="text/ng-template">
<ion-view title="{{navTitle}}" left-buttons="leftButtons">
<ion-tabs tabs-type="tabs-icon-only">
<ion-tab title="Tab 1" icon-on="ion-ios7-filing" icon-off="ion-ios7-filing-outline">
<ion-content has-header="true" padding="true">
<h2>Tab 1 Content</h2>
</ion-content>
</ion-tab>
<ion-tab title="Tab 2" icon-on="ion-ios7-filing" icon-off="ion-ios7-filing-outline">
<ion-content has-header="true" padding="true">
<h2>Tab 2 Content</h2>
</ion-content>
</ion-tab>
<ion-tab title="Tab 3" icon-on="ion-ios7-filing" icon-off="ion-ios7-filing-outline">
<ion-content has-header="true" padding="true">
<h2>Tab 3 Content</h2>
</ion-content>
</ion-tab>
</ion-tabs>
</ion-view>
</script>
<script id="mainContainer.html" type="text/ng-template">
<ion-side-menus>
<ion-pane ion-side-menu-content>
<ion-nav-bar type="bar-positive"
back-button-type="button-icon"
back-button-icon="ion-ios7-arrow-back"
animation="nav-title-slide-ios7"
>
</ion-nav-bar>
<ion-nav-view name="main"></ion-nav-view>
</ion-pane>
<ion-side-menu side="left">
<header class="bar bar-header bar-assertive">
<div class="title">Side Menu</div>
</header>
<ion-content has-header="true">
<ul class="list">
<a ui-sref="entry" class="item">Back To Entry Page</a>
<a ui-sref="main.home" class="item" ng-click="toggleMenu()">Home</a>
<a ui-sref="main.tabs" class="item" ng-click="toggleMenu()">Tabs</a>
</ul>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</script>
<script id="home.html" type="text/ng-template">
<ion-view title="{{navTitle}}" left-buttons="leftButtons">
<ion-content has-header="true" padding="true">
<h1>Home Page!</h1>
<a ui-sref="main.info" class="button button-positive">Info</a>
</ion-content>
</ion-view>
</script>
<script id="info.html" type="text/ng-template">
<ion-view title="{{navTitle}}" left-buttons="leftButtons">
<ion-content has-header="true" padding="true">
<h1>Info Page!</h1>
</ion-content>
</ion-view>
</script>
</body>
</html>
javascript
angular.module('ionicApp', ['ionic'])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('entry', {
url : '/entry',
templateUrl : 'entry.html',
controller : 'EntryPageController'
})
.state('main', {
url : '/main',
templateUrl : 'mainContainer.html',
abstract : true,
controller : 'MainController'
})
.state('main.home', {
url: '/home',
views: {
'main': {
templateUrl: 'home.html',
controller : 'HomePageController'
}
}
})
.state('main.info', {
url: '/info',
views: {
'main': {
templateUrl: 'info.html',
controller : 'InfoPageController'
}
}
})
.state('main.tabs', {
url: '/tabs',
views: {
'main': {
templateUrl: 'tabs.html',
controller : 'TabsPageController'
}
}
})
$urlRouterProvider.otherwise('/entry');
}])
.controller('MainController', [ '$scope', function($scope) {
$scope.toggleMenu = function() {
$scope.sideMenuController.toggleLeft();
}
}])
.controller('EntryPageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Entry Page';
$scope.signIn = function() {
$state.go('main.home');
}
}])
.controller('HomePageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Home Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function(e) {
$scope.toggleMenu();
}
}];
}])
.controller('InfoPageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Info Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function(e) {
$scope.toggleMenu();
}
}];
}])
.controller('TabsPageController', [ '$scope', '$state', function($scope, $state) {
$scope.navTitle = 'Tab Page';
$scope.leftButtons = [{
type: 'button-icon icon ion-navicon',
tap: function(e) {
$scope.toggleMenu();
}
}];
}])
it took some tweaks but finally worked on my scenario

Related

Unable to get routing work in Ionic app

I am unable to get routing to work for the Ionic app.
When I click on a link ('Scientific Facts') in home.html, it doesn't navigate to facts.html
I've gone through all the relevant documentation and other similar answers on stack overflow but none of them helped.
Below are my files index.html, app.js, states.js files. Could someone please suggest where I could be going wrong ?
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link rel="manifest" href="manifest.json">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<link href="css/ionicons.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="js/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/states.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="curie">
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Home">
<ion-content class="padding">
<p>
<a class="button icon icon-right ion-chevron-right" href="#/tab/facts">Scientific Facts</a>
</p>
</ion-content>
</ion-view>
</script>
<script id="templates/facts.html" type="text/ng-template">
<ion-view view-title="Facts">
<ion-content class="padding">
<p>Banging your head against a wall uses 150 calories an hour.</p>
</p>
</ion-content>
</ion-view>
</script>
</body>
</html>
states.js
angular.module('curie')
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.home', {
url: '/home',
views: {
'home': {
templateUrl: 'templates/home.html',
controller: 'HomeTabCtrl'
}
}
})
.state('tab.facts', {
url: '/facts',
views: {
'facts': {
templateUrl: 'templates/facts.html'
}
}
})
$urlRouterProvider.otherwise('/tab/home');
})
.controller('HomeTabCtrl', function($scope, $location) {
console.log('HomeTabCtrl');
$scope.goToUrl = function(path) {
$location.path('#/tab/overviewPhoto');
};
});
app.js
angular.module('curie', [
'ionic',
'ngCordova',
'ui.router',
])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
From further research, I've come to know that, the view name the page is being navigated to, shall be same as the view name from which it was navigated from.
Below is incorrectly defined view name.
.state('tab.facts', {
url: '/facts',
views: {
'facts': {
templateUrl: 'templates/facts.html'
}
}
})
Below is correctly defined view name i.e same as the view name it is being navigated from.
.state('tab.facts', {
url: '/facts',
views: {
'home': {
templateUrl: 'templates/facts.html'
}
}
})
since, you are using $stateProvider, why don't you use $state.go('urPage').
In your view:
<a class="button icon icon-right ion-chevron-right" ng-click="goFacts()">Scientific Facts</a>
In your controller:
.controller('HomeTabCtrl', function($scope, $location,$state) {
console.log('HomeTabCtrl');
$scope.goToUrl = function(path) {
$location.path('#/tab/overviewPhoto');
};//u don't have this function in the view.
$scope.goFacts = function(){
$state.go('tab.facts');
}
});
As Crhistian Ramirez said try to use ui-sref instead of href.
Old solution:
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Home">
<ion-content class="padding">
<p>
<a class="button icon icon-right ion-chevron-right" href="#/tab/facts">Scientific Facts</a>
</p>
</ion-content>
</ion-view>
</script>
New solution:
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Home">
<ion-content class="padding">
<p>
<a class="button icon icon-right ion-chevron-right" ui-sref="tab.facts">Scientific Facts</a>
</p>
</ion-content>
</ion-view>
</script>

Angular - Add compiled html snippet, dynamicly to a directive, before the directive gets compiled

I'm trying to add a directive into another directive dynamically in Ionic for Example:
<ion-nav-buttons side="right">
// If the page has my-directive, add here a my-button to control it
</ion-nav-buttons>
I'm trying to do this from another directive, which is more deeper.
my try on codepen.
Background:
I want, that if I use my-directive somewhere deeper, that my-directive adds dynamically a button to the navbar, which can control the my-directive.
Edit: I tried it again codepen 2, but there are still some issues:
When going to a page where the directive isn't present, the button should also be removed.
The button only appears, when you directly start on the page where the directive is. If you start somewhere else and navigate to it, it doesn't work.
Somewhere I have a $timeout wich waits 0 milliseconds, doesn't work without, but why should this be necessary.
You could create a directive for your navbar and pass the markup to the directive's isoltated scope.
Passing can be done with $rootScope or with a factory. I would prefer a factory but in the demo I've used the rootScope for passing.
I also don't like the scope passing in the demo. It's working but I think it would be better to store the handler in a factory too. The factory can then manage the creation of the icon in navbar and the event handler for the action you need for the button.
Please have a look at the following demo or in this codepen.
angular.module('ionicApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$ionicConfigProvider.views.swipeBackEnabled(false);
$ionicConfigProvider.views.maxCache(0);
$stateProvider
.state('eventmenu', {
url: "/event",
abstract: true,
templateUrl: "templates/event-menu.html"
})
.state('eventmenu.home', {
url: "/home",
views: {
'menuContent' :{
templateUrl: "templates/home.html"
}
}
})
.state('eventmenu.checkin', {
url: "/check-in",
views: {
'menuContent' :{
templateUrl: "templates/check-in.html",
controller: "CheckinCtrl"
}
}
})
.state('eventmenu.attendees', {
url: "/attendees",
views: {
'menuContent' :{
templateUrl: "templates/attendees.html",
controller: "AttendeesCtrl"
}
}
})
$urlRouterProvider.otherwise("/event/home");
})
.controller('MainCtrl', function($scope, $ionicSideMenuDelegate) {
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.toggleLeft();
};
})
.controller('CheckinCtrl', function($scope) {
$scope.$on('$ionicView.afterEnter', function() {
console.log('entered');
});
})
.controller('AttendeesCtrl', function($scope) {
})
.directive( 'dynNavbar', function($compile) {
return {
scope: {
optional: '='
},
template: '<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button><div class="dynButton"/>',
link: function(scope, element) {
scope.$watch('optional', function(){
var dynButton = scope.optional;
console.log(scope.optional, element, element[0].querySelector('.dynButton'), $compile(dynButton.html)(scope));
angular.element(element[0].querySelector('.dynButton')).replaceWith($compile(dynButton.html)(dynButton.scope));
});
}
}
})
.directive('test', function($compile) {
return {
restrict: 'E',
replace: true,
template: '<p ng-style="{color: styleFlag}">use this directive, with the button in the navbar</p>',
controller: function($scope, $rootScope) {
$rootScope.injectedButton = {html: '<a class="button button-icon icon ion-eye" ng-click="cry()"></a>',
scope: $scope
};
var styleFlag = false;
$scope.cry = function () {
console.log('buhuhuhu');
styleFlag = !styleFlag; // change style just as example
$scope.styleFlag = styleFlag ? 'red': 'black';
//console.log(styleFlag, $scope.styleFlag);
};
},
link: function(scope, el, attrs){
// -----------------------------------
// ADD BUTTON IN NAVBAR
// -----------------------------------
//scope.$on('$ionicView.afterEnter', function(){
/* var nav = document.getElementsByClassName('nav-bar-block');
if (nav[0].getAttribute('nav-bar') == 'active' || nav[0].getAttribute('nav-bar') == 'entering') {
nav = angular.element(nav[0].getElementsByClassName('right-buttons')[0]);
}
if (nav[1] && nav[1].getAttribute('nav-bar') == 'active' || nav[1] && nav[1].getAttribute('nav-bar') == 'entering') {
nav = angular.element(nav[1].getElementsByClassName('right-buttons')[0]);
}
console.log(nav);
nav.append($compile('<a class="button button-icon icon ion-eye" ng-click="cry()"></a>')(scope));
// });
*/
// -----------------------------------
// FUNCTION FOR THE BUTTON
// -----------------------------------
/*scope.cry = function () {
console.log('buhuhuhu');
};*/
}
}
});
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Side Menus</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="MainCtrl">
<ion-nav-view></ion-nav-view>
<script id="templates/event-menu.html" type="text/ng-template">
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>
</ion-nav-buttons>
<ion-nav-buttons side="right">
<!--<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>-->
<dyn-navbar optional="injectedButton"/>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left">
<ion-header-bar class="bar-assertive">
<h1 class="title">Left Menu</h1>
</ion-header-bar>
<ion-content>
<ul class="list">
<a href="#/event/check-in" class="item" menu-close>Check-in</a>
<a href="#/event/attendees" class="item" menu-close>Attendees</a>
</ul>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</script>
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Welcome">
<ion-content class="padding">
home: <test></test>
</ion-content>
</ion-view>
</script>
<script id="templates/check-in.html" type="text/ng-template">
<ion-view view-title="Event Check-in">
<ion-content>
checkin: <test></test>
</ion-content>
</ion-view>
</script>
<script id="templates/attendees.html" type="text/ng-template">
<ion-view view-title="Event Attendees">
<ion-content>
attendees: <test></test>
</ion-content>
</ion-view>
</script>
</body>
</html>

UI-Router Multiple Views Single Controller not work

I would like to use one controller defined in views, but the $scope does not define anything. Is there a way to do this? Please share a simple example in order to understand.
I have this index.html
<body ng-app="ehc">
<h1>{{home}}+{{a}}+{{b}}</h1>
<ion-side-menus enable-menu-with-back-views="false" delegate-handle="left">
<!-- Left menu -->
<ion-side-menu side="left" is-enabled="true">
<ion-header-bar class="bar-stable">AAA</ion-header-bar>
<ion-content>
<div class="list">
<div class="item item-divider">
Candy Bars
</div>
</div>
</ion-content>
</ion-side-menu>
<ion-side-menu-content edge-drag-threshold="true" drag-content="true">
<!-- Main content, usually <ion-nav-view> -->
<ion-nav-bar class="bar-positive" >
<ion-nav-title>
<h2>hello world title *{{home}}*</h2>
</ion-nav-title>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-view>
<ion-content class="has-header">
<div class="row">
<div class="col-50">
<div ui-view="a"></div>
</div>
<div class="col-50">
<div ui-view="b"></div>
</div>
</div>
</ion-content>
</ion-view>
</ion-side-menu-content>
<script type="text/ng-template" id="templates/a.html">
<ion-view>
<ion-content class="has-header">
**{{a}}**
</ion-content>
</ion-view>
</script>
<script type="text/ng-template" id="templates/b.html">
<ion-view>
<ion-content class="has-header">
**{{b}}**
</ion-content>
</ion-view>
</script>
</body>
<script src="js/app.js"></script>
And this is my model definition app.js
var app = angular.module("ehc", ["ionic"])
.config(function ($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('Home', {
url: '/',
controller: "HomeCtrl",
//template:"<ion-header-bar></ion-header-bar><ion-content><h1>hello dal AngularJs</h1></ion-content>",
views: {
"a": {
templateUrl: 'templates/a.html'
},
"b": {
templateUrl: 'templates/b.html'
}
}
});
}).controller("HomeCtrl", ["$scope", "$ionicSideMenuDelegate",
"$routeParams", "config", "$q", "$http"], function ($scope, $ionicSideMenuDelegate, $routeParams, config, $q, $http) {
$scope.toggleLeft = function () {
$ionicSideMenuDelegate.toggleLeft();
};
//carico le lingue e il menu
console.log("AAAAAAAAAAAA");
$scope.home = "Pippo";
$scope.a="XAX";
$scope.b="XBX";
})
console is empty and also the scope in html template. Please if you have the solution, use very simple example.
I've read here and I thought it worked Rakrap Jaknap answered on 2015-04-17 08:01
Very similar issue: Why controller does not work in UI-router of angularjs?
The point here is:
Controller always belongs to View, never to state.
Other words, to use same type of controller (but two instances for each view), we have to do that kind of declaration:
$stateProvider.state('Home', {
url: '/',
// instead of this
//controller: "HomeCtrl",
views: {
"a": {
templateUrl: 'templates/a.html',
controller: "HomeCtrl", // we need this
},
"b": {
templateUrl: 'templates/b.html',
controller: "HomeCtrl", // and also this
}
}
});
In case, we want to share some stuff among many views, we need different technique than "same controller". See:
How do I share $scope data between states in angularjs ui-router?
Another insight, could be covered here:
scope and controller instantiation with ui router
And including typescript, there is a detailed description and example how all views/states could target some common RootModel
Angular Digest cycle being ran but ng-bind value not updating

Popup and ion-nav-view don't work togehter

I have newbie question.
I need some really basic AngularJS in my app. I made my popup work and then added ion-nav-view. Both elements works, but not simultaneously. Now ion-nav-view works perfect, but when i change
body ng-app="starter"
to
body ng-app="starter" ng-controller="PopupCtrl"
app turns into blank site.
It must be some small mistake but i can't find, where it is. Can anyone help me? My app.js:
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
})
angular.module('starter', ['ionic'])
.controller('PopupCtrl', function($scope, $ionicPopup, $timeout) {
$scope.showAlert = function() {
var alertPopup = $ionicPopup.alert({
title: 'Alert',
template: 'Alert text'
});
};
});
angular.module('starter', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('list', {
url: '/1',
templateUrl: 'list.html'
})
.state('info', {
url: '/2',
templateUrl: 'info.html'
})
$urlRouterProvider.otherwise("/1");
})
EDIT:
Body section of index.html:
<body ng-app="starter" ng-controller="PopupCtrl">
<ion-nav-bar class="bar-positive" align-title="center">
</ion-nav-bar>
<ion-nav-view class="slide-left-right"></ion-nav-view>
<script id="list.html" type="text/ng-template">
<ion-view title="title">
<ion-nav-buttons side="right">
<button class="button button-icon icon ion-android-locate" ng-click="showAlert()"></button>
</ion-nav-buttons>
<ion-content>
<div class="list">
<a class="item item-thumbnail-left" href="#">
<img src="cover.jpg">
<h2>Pretty Hate Machine</h2>
<p>Nine Inch Nails</p>
</a>
<a class="item" ui-sref="info">
<p>Żeby uzyskać pomoc, dotknij to pole.</p>
</a>
</div>
</ion-content>
</ion-view>
</script>
<script id="info.html" type="text/ng-template">
<ion-view title="Informacje">
<ion-content class="padding">
<div class="card">
<div class="item item-text-wrap">
<img src="img/logo.png" style="width: 100%">
</div>
</div>
</ion-content>
</ion-view>
</script>
</body>
Module should be get injected with dependency while you are creating it like here you did angular.module('starter', ['ionic']) but while consuming it you need to use angular.module('starter'), As module is already created. If you do the same thing again then previously registered component of that module will get flushed.
Like in your code you need to use angular.module('starter') while defining controller & config
Code
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
//code here
})
angular.module('starter')//<-- change here
.controller('PopupCtrl', function($scope, $ionicPopup, $timeout) {
//code here
});
angular.module('starter') //<-- change here
.config(function($stateProvider, $urlRouterProvider) {
//code here
})

Ionic tabs and side menu navigation issue

I learn and try to create an ionic app with tabs combining the side menu.
Here is what it looks like (Codepen):
The side-menu part is okay. There is an additional link on my home page. Here is my problem: After clicking the link, I can go back to the previous page only through the back button. And my home tab doesn't work. I try to add another link to my about page, and either back button or home tab could go back to the previous page, which is the home page.
Here is my .js file:
angular.module('demo', ['ionic'])
.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/')
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html'
})
.state('about', {
url: '/about',
templateUrl: 'about.html'
})
.state('contact', {
url: '/contact',
templateUrl: 'contact.html'
})
})
.controller('MyCtrl', function ($scope, $ionicSideMenuDelegate) {
$scope.showRightMenu = function () {
$ionicSideMenuDelegate.toggleRight();
};
});
I looked for other similar issues and tried to switch the href to ui-sref. The home tab still doesn't work. Did I miss something?
And here is my .html:
<body ng-app="demo" ng-controller="MyCtrl">
<ion-side-menus>
<ion-side-menu-content>
<ion-nav-bar class="bar-positive nav-title-slide-ios7">
<ion-nav-back-button class="button-clear">
<i class="ion-arrow-left-c"></i> Back </ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
<ion-tabs class="tabs-icon-top tabs-positive">
<ion-tab title="Home" icon="ion-home" ui-sref="home">
<ion-nav-view name="home"></ion-nav-view>
</ion-tab>
<ion-tab title="About" icon="ion-ios-information" ui-sref="about">
<ion-nav-view name="about"></ion-nav-view>
</ion-tab>
<ion-tab title="Setting" icon="ion-navicon" ng-click="showRightMenu()">
</ion-tab>
</ion-tabs>
</ion-side-menu-content>
<ion-side-menu side="right">
<ion-header-bar class="bar-dark">
<h1 class="title">Setting</h1>
</ion-header-bar>
<ion-content has-header="true">
<ion-list>
<ion-item>Setting</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
<script id="home.html" type="text/ng-template">
<ion-view view-title="Home">
<ion-content class="padding">
<a class="button button-stable button-block" ui-sref="contact">Contact</a>
<a class="button button-stable button-block" ui-sref="about">About</a>
</ion-content>
</ion-view>
</script>
<script id="about.html" type="text/ng-template">
<ion-view view-title="About">
<ion-content class="padding">
</ion-content>
</ion-view>
</script>
<script id="contact.html" type="text/ng-template">
<ion-view view-title="Contact">
<ion-content class="contactBg" scroll="false">
</ion-content>
</ion-view>
</script>
Tabs have history only when you navigate to a sub item; a child element in the tab. That's the only situation when you should have a back button inside a tab.
First thing I've noticed, you're referencing an old version of the framework:
<link href="http://code.ionicframework.com/1.0.0-beta.14/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.0.0-beta.14/js/ionic.bundle.min.js"></script>
I would suggest to use the latest, stable:
<link href="http://code.ionicframework.com/1.1.0/css/ionic.min.css" rel="stylesheet">
<script src="http://code.ionicframework.com/1.1.0/js/ionic.bundle.min.js"></script>
Then you're trying to wrap everything inside a big container.
Normally what you would do is create a menu (menu.html):
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="bar-positive nav-title-slide-ios7">
<ion-nav-back-button>
</ion-nav-back-button>
<!--
<ion-nav-buttons side="right">
<button class="button button-icon button-clear ion-navicon" menu-toggle="right">
</button>
</ion-nav-buttons>
-->
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="right">
<ion-header-bar class="bar-dark">
<h1 class="title">Settings</h1>
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item nav-clear href="#">
Settings
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
Where you have a <ion-nav-view name="menuContent"></ion-nav-view>.
That's the place where all the views will be loaded.
I've hidden the navigation button for the menu so you won't see it:
<!--
<ion-nav-buttons side="right">
<button class="button button-icon button-clear ion-navicon" menu-toggle="right"></button>
</ion-nav-buttons>
-->
Then you would have your tabs container (tabs.html):
<ion-view view-title="Tabs">
<ion-tabs class="tabs-icon-top tabs-positive">
<ion-tab title="Home" icon-on="ion-ios-home" icon-off="ion-ios-home-outline" ui-sref="app.tabs.home">
<ion-nav-view name="home"></ion-nav-view>
</ion-tab>
<ion-tab title="About" icon-on="ion-ios-information" icon-off="ion-ios-information-outline" ui-sref="app.tabs.about">
<ion-nav-view name="about"></ion-nav-view>
</ion-tab>
<ion-tab title="Contact" ui-sref="app.tabs.contact" class="ng-hide">
<ion-nav-view name="contact"></ion-nav-view>
</ion-tab>
<ion-tab title="Setting" icon-on="ion-navicon" icon-off="ion-navicon" ng-click="showRightMenu()"></ion-tab>
</ion-tabs>
</ion-view>
I've hidden the tab contacts class="ng-hide" cause I don't really understand what you're trying to do there (it will be loaded when you click the button in the home page):
<ion-tab title="Contact" ui-sref="app.tabs.contact" class="ng-hide">
<ion-nav-view name="contact"></ion-nav-view>
</ion-tab>
Each tab has got its ion-nav-view container where the specific tabs will be loaded:
<ion-nav-view name="home"></ion-nav-view>
You should configure your states so that the menu is the main, abstract state:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "menu.html"
})
.state('app.tabs', {
url: "/tabs",
views: {
'menuContent': {
templateUrl: "tabs.html",
controller: 'tabsController'
}
}
})
.state('app.tabs.home', {
url: "/home",
views: {
'home': {
templateUrl: "home.html",
}
}
})
.state('app.tabs.about', {
url: "/about",
views: {
'about': {
templateUrl: "about.html",
}
}
})
.state('app.tabs.contact', {
url: "/contact",
views: {
'contact': {
templateUrl: "contact.html"
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/tabs');
});
The state for the tabs container (app.tabs) will be loaded in the menuContent
.state('app.tabs', {
url: "/tabs",
views: {
'menuContent': {
templateUrl: "tabs.html",
controller: 'tabsController'
}
}
})
while all the others (specific tab) will have their own view:
.state('app.tabs.home', {
url: "/home",
views: {
'home': {
templateUrl: "home.html",
}
}
})
I've also used a controller for the tabs container => tabsController:
.controller('tabsController', function($scope, $ionicSideMenuDelegate) {
$scope.showRightMenu = function() {
$ionicSideMenuDelegate.toggleRight();
};
});
so you can manage your side-menu.
Roughly your app should look like this.

Resources