I'm created one side menu project. It has 3 HTML files: firstPage.html contains button NEXT (go to secondPage.html). Same as secondPage.html that contains button NEXT (go to thirdPage.html) and for thirdPage.html NEXT button (go to firstPage.html). Every html has their own controller.
I followed this link in handling my back button action for Android device. It worked but for already registered back button didn't destroy after I changed my state.
Based on my codes below, the result was when I clicked android back button at firstPage.html, its prompt the alert. Then I clicked NEXT button in firstPage.html then directly go to secondPage.html. When I clicked android back button in that page, its also prompt me the alert. Eventhough the 'TheSecondController' didn't have '$ionicPlatform.registerBackButtonAction'. Same with thirdPage.html.
Here is my code:
Javascript: app.js
.state('app.firstPage', {
url: '/firstPage',
views: {
'menuContent': {
templateUrl: 'templates/firstPage.html',
controller: 'TheFirstController'
}
}
})
.state('app.secondPage', {
url: '/secondPage',
views: {
'menuContent': {
templateUrl: 'templates/secondPage.html',
controller: 'TheSecondController'
}
}
})
.state('app.thirdPage', {
url: '/thirdPage',
views: {
'menuContent': {
templateUrl: 'templates/thirdPage.html',
controller: 'TheThirdController'
}
}
})
HTML: firstPage.html
<ion-view view-title="First">
<ion-content>
<h1>First</h1>
<button class="button button-block button-positive" ui-sref="app.secondPage">Next</button>
</ion-content>
</ion-view>
HTML: secondPage.html
<ion-view view-title="Second">
<ion-content>
<h1>Second</h1>
<button class="button button-block button-positive" ui-sref="app.thirdPage">Next</button>
</ion-content>
</ion-view>
HTML: thirdPage.html
<ion-view view-title="Third">
<ion-content>
<h1>Third</h1>
<button class="button button-block button-positive" ui-sref="app.firstPage">Next</button>
</ion-content>
</ion-view>
Javascript: TheFirstController.js
.controller('TheFirstController', function($scope, $ionicPlatform, $ionicPopup) {
var deregisterFirst = $ionicPlatform.registerBackButtonAction(
function() {
if (true) { // your check here
$ionicPopup.confirm({
title: 'System warning',
template: 'Are you sure you want to exit?'
}).then(function(res) {
if (res) {
ionic.Platform.exitApp();
}
})
}
}, 100
);
$scope.$on('$destroy', deregisterFirst);
})
Javascript: TheSecondController.js
.controller('TheSecondController', function() {
//Allow user to go to previous page
})
Javascript: TheThirdController.js
.controller('TheThirdController', function() {
//Allow user to go to previous page
});
Please anyone help me. Thank you.
The $ionicPlatform.registerBackButtonAction() function registers the action for the whole Application, not specific to a page. $ionicPlatform is a service created by Ionic so it is a singleton (as all angular services are) therefore there is only one instance of it in the app.
So when you set the registerBackButtonAction in one controller it sets it for the whole app.
If you want it to exit only if you're on the first app, you have to add an if() on the state name.
Something like
if($state.current.name === 'app.firstPage'){
//your code here
}
The same way the guide you followed did it.
Related
I'm getting a peculiar problem. I have a nested accordion and I need a button like Edit on every accordion. When the button is clicked, I need to call a different function. What I'm doing is on click of the edit button I'm trying to use $event.stopPropagation() which will stop accordion functionality. But this isn't happening when I pass $event.stopPropagation(). It is redirecting to some other URL.
I'm posting some of my huge code. If any further info is required please comment.
HTML
<accordion-heading>
{{course.className}}
<button type="button"
ng-show="course.classId!=$scope.null"
class="pull-right btn btn-default btn-sm"
ng-click="editCourse(course,$event)">
Edit Course
</button>
</accordion-heading>
JS
$scope.editCourse = function(course, ev) {
ev.stopPropagation();
course.courseEditPermission = true;
}
app.js
.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {
$httpProvider.defaults.headers.common['Access-Control-Allow-Headers'] = '*';
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$routeProvider
.when('/login', {
controller: 'LoginController',
templateUrl: 'modules/authentication/views/login.html',
hideMenus: true
})
.when('/home', {
controller: 'HomeController',
templateUrl: 'modules/home/views/home.html'
})
.otherwise({
redirectTo: '/xyz'
});
}])
I don't know why it is redirecting but in my JS I provided routes, so I think event.stopPropagation is getting some anonymous URL, so it is redirecting to "/xyz" as I have mentioned.
You need to add event.preventDefault() handler like this:
$scope.editCourse = function(course, ev) {
ev.preventDefault();
ev.stopPropagation();
course.courseEditPermission = true;
}
I have a app that im writing. The first page is a list of books, when you click on a book it takes you to the chapter selection of that book, which works. However i have an issue when i try to select a chapter and go to it. From what i can tell it looks like my route is not valid according to the .state() function.
In my chapter selection template i have the following
<ion-view view-title="{{textbook.title}}">
<ion-content>
<ion-list>
<ion-item ng-repeat="chapter in textbook.chapters">
<a ng-href="#/app/textbooks/{{textbook.id}}/ch/{{chapter.id}}">{{chapter.title}}</a>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
In my app.js i have the following routes.
This is the chapter select
.state('app.chapters', {
url: "/textbooks/:textbookId",
views: {
'menuContent': {
templateUrl: "templates/textbook-chapters.html",
controller: 'TextbookSectionCtrl'
}
}
})
This should be the individual chapter
.state('app.chapter', {
url: "/textbooks/:textbookId/ch/:chapterId",
views: {
'menuContent': {
templateUrl: "templates/textbook-chapter.html",
controller: 'TextbookChapterCtrl'
}
}
});
You can download the directory zip here
https://www.sendspace.com/file/4iiuy2
I am developing and app in Ionic and I need that after you click in button it takes you to another template. This template is called area.html and is not in the sidemenu, I added as a state of it in app.js . Here you have some code:
app.js
.state('app.area', {
url: "/area",
views: {
'menuContent': {
templateUrl: "templates/area.html",
controller: 'AreaCtrl'
}
}
});
firsttemplate.html
<ion-view view-title="First Template">
<ion-content class="background">
<button class="button button-positive"
ng-click="changeToArea()">Current Position</button>
</ion-content>
</ion-view>
controller.js
.controller('FirstTempCtrl', function ($scope){
$scope.changeToArea = function() {
console.log("Area Func");
window.location = "#/app/area.html";
})
The thing is that when you click in the button it take you to another template, to the :
$urlRouterProvider.otherwise('/app/log');
in the app.js and what I want to load is area.html
window.location = "#/app/area.html";
will reload your app and therefore all controllers
you need to use ui-router with for exemple : $state.go('app.area');
I have an app with a tabbed interface, which consists of three tabs. When the user takes certain actions on tab1, it dynamically creates elements that should appear on the second tab. The problem is when I try to dynamically create that content within my javascript, I'm getting cannot set attribute of "null", which I'm assuming is because the second tab isn't loaded into the dom yet. If I first navigate to the second tab, then back to the first tab, it works fine. I'm not really using angular the way it's normally probably used. Everything is done in javascript. I just have a barebones app.js for the underlying UI.
Essentially, I just want to have all three tabs loaded into the DOM on app startup so I can dynamically modify the contents of any tab from any other tab. Not sure how to do this. Here's what my app.js looks like:
var myApp = angular.module('starter', ['ionic','ngCordova'])
myApp.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.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
$cordovaStatusbar.overlaysWebView(true)
$cordovaStatusbar.styleHex('#4a87ee')
$ionicConfigProvider.views.forwardCache(true);
});
});
myApp.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"
}
}
})
.state('tabs.favorites', {
url: "/favorites",
views: {
'favorites-tab': {
template: "templates/favorites.html",
controller: 'AppCtrl'
}
}
})
.state('tabs.settings', {
url: "/settings",
views: {
'settings-tab': {
templateUrl: "templates/settings.html"
}
}
});
$urlRouterProvider.otherwise("/tab/home");
})
myApp.controller('AppCtrl', function($scope) {
})
And my basic app structure/html looks like this:
<ion-nav-bar class="bar-positive"></ion-nav-bar>
<ion-nav-view></ion-nav-view>
<script id="templates/tabs.html" type="text/ng-template">
<ion-tabs class="tabs-positive tabs-icon-only">
<ion-tab title="Videos" icon-on="ion-ios-home" icon-off="ion-ios-home-outline" href="#/tab/home">
<ion-nav-view name="home-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="Favorites" icon-on="ion-ios-star" icon-off="ion-ios-star-outline" href="#/tab/favorites">
<ion-nav-view name="favorites-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="Settings" icon-on="ion-ios-gear" icon-off="ion-ios-gear-outline" href="#/tab/settings">
<ion-nav-view name="settings-tab"></ion-nav-view>
</ion-tab>
</ion-tabs>
</script>
<!-- **************************** HOME TAB **************************** -->
<script id="templates/home.html" type="text/ng-template">
<ion-view view-title="Lmao!Tube">
<ion-content has-bouncing="true" overflow-scroll="true" class="iframe-wrapper">
<div id="videoList"> </div>
</ion-content>
</ion-view>
</script>
<!-- **************************** FAVORITES TAB **************************** -->
<script id="templates/favorites.html" type="text/ng-template">
<ion-view view-title="Favorites" >
<ion-content has-bouncing="true" overflow-scroll="true" class="iframe-wrapper">
<div id="favoriteList"></div>
</ion-content>
</ion-view>
</script>
<!-- **************************** SETTINGS TAB **************************** -->
<script id="templates/settings.html" type="text/ng-template">
<ion-view view-title="Settings">
<ion-content>
</ion-content>
</ion-view>
</script>
Actually after rereading your question, you want to do it a different way. Once you click on the tab, it is placed on the stack and the content is rendered, that's why it only works when you push back and forward. What would be a better way is utilizing AngularJS and the application framework by saving changes like boolean values in a Service. A service is an object instantiated only once to hold information and pass it around from controller to controller. You can use the service to hold values that the controller dynamically creates content from, and in your templates you can use AngularJS's directives like ng-show and ng-if etc...
For instance in services.js you could have:
angular.module('starter.services', [])
.service('MyService', function() {
var Stuff = {};
this.set = function(key, value) {
Stuff[key] = value;
};
this.get = function(key) {
return Stuff[key];
}
});
And in your home controller
.controller('HomeCtrl', function(MyService, $scope) {
MyService.set('home', true);
})
And in your favorites controller
.controller('FavCtrl', function(MyService, $scope) {
if (MyService.get('home') === true) {
// set a variable or return list or query or whatever you want
// lets say it's an array
$scope.list = [1,2,3];
} else {
$scope.list = [4,5,6];
}
})
And in your template you could do something like:
<div ng-repeat="i in list">
{{i}}
</div>
And that should print out 1 2 3 if they clicked home tab, and 4 5 6 if not.
If you're new to angular go here: http://campus.codeschool.com/courses/shaping-up-with-angular-js/intro?utm_source=google&utm_medium=cpc&utm_campaign=course&gclid=CjwKEAjw9bKpBRD-geiF8OHz4EcSJACO4O7TsJ3Mx9m9DOH47-6rmFshzUkkkHzJFhJcNiPl1it9JRoCN_fw_wcB
Pretty nifty course that gets you knowing some things about AngularJS pretty fast to work with Ionic. Ionic is a great framework.
Ideally, all 3 methods ought to work.
This codepen below shows all 3 methods well.
Correct and working CodePen Demo app
Currently, neither of the 3 methods work; the navbar just dissappears upon clicking the button (shows empty nav bar) while the core page remains the same main page.
Im not sure if its an code problem, ionic issue or just simply I should not transit to a new page from a navbar. The last one is too illogical to accept though.
Would any kind souls know where the issue lie and help me please?
My core content code in index.html
<body animation="slide-left-right-ios7">
<ion-nav-bar class="bar-light nav-title-slide-ios7"></ion-nav-bar>
<ion-nav-view></ion-nav-view>
The button html I have (Note all 3 versions were tested seperately)
<ion-view ng-controller="NavCtrl">
<ion-nav-buttons side="left">
<button class="button button-icon ion-compose" ng-click="create('tab.newpost')"></button>
<button class="button button-icon ion-compose" ui-sref="tab.newpost"></button>
<button class="button button-icon ion-compose" href="/tab/newpost"></button>
</ion-nav-buttons>
<ion-content class>
<!-- Rest of the content body here -->
</ion-content>
</ion-view>
Code in nav.js mainly for the state.create method
app.controller('NavCtrl', function ($scope, $location, $state, Post, Auth) {
$scope.post = {url: 'http://', title: ''};
$scope.create = function(stateName) {
/* $location.path('/tab/newpost'); */
$state.go(stateName); /* tried swapping stateName with 'tab.newpost' and func() */
};
});
Code for app.js (Route file)
var app = angular.module('MyApp', ['ionic','firebase']);
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.posts', {
url: '/posts',
views: {
'tab-posts': {
templateUrl: 'templates/tab-posts.html',
controller: 'PostsCtrl'
}
}
})
.state('tab.newpost', {
url: '/newpost',
views: {
'tab-newpost':{
templateUrl: 'templates/tab-newpost.html',
controller: 'NewCtrl'
}
}
});
/* + other states .... */
$urlRouterProvider.otherwise('/auth/login');
});
First method you used according to the your code look like this
ng-click="create('tab/newpost')"
It should be
ng-click="create('tab.newpost')"
i think you need to modify states name so you can navigate between them
var app = angular.module('MyApp', ['ionic','firebase']);
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.posts', {
url: '/posts',
views: {
'tab-posts': {
templateUrl: 'templates/tab-posts.html',
controller: 'PostsCtrl'
}
}
})
.state('tab.newpost', {
url: '/newpost',
views: {
'tab-posts':{ /* the same name of the above state */
templateUrl: 'templates/tab-newpost.html',
controller: 'NewCtrl'
}
}
});
/* + other states .... */
$urlRouterProvider.otherwise('/auth/login');
});