i'm new in ionic ( just a little less in angularjs ) .
i'm trying to do a simple switch between two views:
HTML
<body ng-app="starter" animation="slide-left-right-ios7">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar class="bar-stable nav-title-slide-ios7">
<ion-nav-back-button class="button-icon icon ion-ios7-arrow-back">
Back
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view name="intro"></ion-nav-view>
<ion-nav-view name="login"></ion-nav-view>
<ion-nav-view name="home"></ion-nav-view>
<ion-nav-view name="pizze"></ion-nav-view>
<ion-nav-view name="sponsor"></ion-nav-view>
<ion-nav-view name="scontrino"></ion-nav-view>
</body>
APP.js
.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
.state('intro', {
url: '/intro',
views: {
'intro': {
templateUrl: 'templates/intro.html',
controller: 'IntroCtrl'
}
}
})
.state('login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
}
}
})
$urlRouterProvider.otherwise('/intro');
});
Controllers.js
angular.module('starter.controllers', [])
.controller('IntroCtrl', function($scope,$location) {
$location.url("/login");
})
.controller('LoginCtrl', function($scope,$location) {
})
Intro is shown correctly but when it tries to change location to "login.html" it says:
TypeError: Cannot read property 'querySelectorAll' of undefined
at cancelChildAnimations (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:30611:21)
at Object.leave (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:30176:11)
at Object.leave (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:38411:24)
at updateView (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:41540:31)
at eventHook (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:41501:17)
at Scope.$broadcast (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:21190:28)
at $state.transition.resolved.then.$state.transition (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:33975:22)
at wrappedCallback (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:19894:81)
at http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:19980:26
at Scope.$eval (http://localhost:8000/www/lib/ionic/js/ionic.bundle.js:20906:28)
What could be the problem???
Thanks!
Try this
angular.module('starter.controllers', [])
.controller('IntroCtrl', function($scope,$state) {
$state.transitionTo("login");
})
.controller('LoginCtrl', function($scope,$location) {
})
You are using the view names wrong.
In a state, the view's name
views: {
'_name_': {
}
is used for different navigation histories for different views.
Say you have two tabs, home and pizza, and you want both to have several pages, then the view name comes in handy.
For your example it is important to know, how you want the views to be used.
I set up an example for you, making the views accessible in tabs.
See here for that example: http://plnkr.co/edit/Yd5ehQd0wnwlPzP0KYnp?p=preview
Related
I have a problem regarding tabs in ionic. I'm creating a basic hotel app in Ionic v1 as a school project but I can't get my tabs or controller to work. The states aren't found, it immediately directs me to the link provided in $urlRouterProvider.otherwise. I've followed my teachers tabs example closely and the example found when starting a new tabs project in Ionic. I did get it to work briefly about two days ago but when I returned to the project today it was just blank (besides what i type in the index file nav-view).
This is my app.js file
angular.module('sthlmBB', ['ionic', 'sthlmBB.controllers'])
.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: "HotelCtrl"
}
}
})
.state("tabs.bookings", {
url: "/bookings",
views: {
"bookings-tab": {
templateUrl: "templates/bookings.html",
controller: "BookingsCtrl"
}
}
})
.state("tabs.events", {
url: "/events",
views: {
"events-tab": {
templateUrl: "templates/events.html",
controller: "EventsCtrl"
}
}
});
$urlRouterProvider.otherwise("/tabs/home");
})
controllers.js
angular.module('sthlmBB.controllers', [])
.controller('HotelCtrl', function($scope, $http, $state){
var url = 'link to php file';
$http.get(url).success(function(response){
$scope.rooms = response.data;
console.log('HotelCtrl Test')
console.log($state);
})
$scope.data = { };
$scope.submit = function(){
var url = 'link to another php file';
$http.post(url, $scope.data)
.then(function(response){
$scope.response = response;
console.log($scope.response);
});
}
})
In the index.html file I have link to both app.js and controllers.js in the head an ion-nav-view in the body.
tabs.html
<ion-tabs class="tabs-icon-top tabs-color-active-positive">
<ion-tab title="Home" icon="ion-home" href="#/tab/home">
<ion-nav-view name="home-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="My Bookings" icon="ion-home"
href="#/tab/bookings">
<ion-nav-view name="bookings-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="Events" icon="ion-home"
href="#/tab/events">
<ion-nav-view name="events-tab"></ion-nav-view>
</ion-tab>
</ion-tabs>
I'm fairly new to this so chances are there's just a rookie mistake in there somewhere. I would really appreciate any help I can get!
It was a typo in app.js under the first state where the url was '/tab' when it should be '/tabs'. facepalm
I have an icon in the nav bar should display or not according to position true / false toggle . Testing in view works perfectly but the result does not work in the nav bar . Both pages use the same controller . Translator English
index.html - nav-bar
<ion-nav-bar class="bar-stable" ng-controller="DashCtrl">
<ion-nav-buttons side="right">
<i class="icon ion-eye ng-show="vaovivo.valor"></i>
</ion-nav-buttons>
<ion-nav-bar
Account.html - toggle
<ion-toggle ng-model="vaovivo.valor" ng-checked="vaovivo.valor">
Modo ao Vivo
</ion-toggle>
Controllers.js
angular.module('starter.controllers', [])
.controller('DashCtrl', function($scope,$rootScope) {
$scope.vaovivo = {'valor':false}
})
app.js
.config(function($stateProvider, $urlRouterProvider) {
$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.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'DashCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/dash');
});
UPDATE:
index.html - nav-bar
<ion-nav-bar class="bar-stable" ng-controller="DashCtrl">
<ion-nav-buttons side="right">
<i class="icon ion-eye" ng-show="vaovivo.valor"></i>
</ion-nav-buttons>
<ion-nav-bar>
The logic looks sound but there is one thing that might prevent the ng-show to work in the nav-bar. You are not closing the ion-nav-bar properly and might be the issue.
Firstly, close of the ng-class properly like by adding a closing quote
<i class="icon ion-eye" ng-show="vaovivo.valor"></i>
Secondly close the ion-nav-bar properly.
</ion-nav-bar>
I have a Ionic app based on the tabs template. The general navigation structure of my app is:
-- users (/users)
-- user (/users/[id])
-- todos (/todos)
-- todo (/users/[id])
-- settings (/settings)
There are some nested views there (user and todo). They appear in the same nav view, like so:
<ion-tabs class="tabs-icon-only tabs-color-assertive">
<ion-tab icon="ion-ios-pulse-strong" href="#/tab/users">
<ion-nav-view name="users-tab"></ion-nav-view>
</ion-tab>
<ion-tab icon="ion-ios-pulse-strong" href="#/tab/todos">
<ion-nav-view name="todos-tab"></ion-nav-view>
</ion-tab>
<ion-tab icon="ion-ios-pulse-strong" href="#/tab/settings">
<ion-nav-view name="settings-tab"></ion-nav-view>
</ion-tab>
</ion-tabs>
With states being defined thusly:
.state('tabs', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('users', {
url: '/users',
views: {
'users-tab': {
templateUrl: 'templates/tab-users.html',
controller: 'UsersCtrl'
}
}
})
.state('tabs.user', {
url: '/users/:userId',
views: {
'users-tab': {
templateUrl: 'templates/user-detail.html',
controller: 'UserCtrl'
}
}
})
.state('todos', {
url: '/todos',
views: {
'todos-tab': {
templateUrl: 'templates/tab-todos.html',
controller: 'TodosCtrl'
}
}
})
.state('tabs.todo', {
url: '/todos/:todoId',
views: {
'todos-tab': {
templateUrl: 'templates/todo-detail.html',
controller: 'TodoCtrl'
}
}
})
.state('tab.settings', {
url: '/settings',
views: {
'settings-tab': {
templateUrl: 'templates/tab-settings.html',
controller: 'SettingsCtrl'
}
}
})
In my index.html file, I have the following:
<ion-nav-bar class="bar-light">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
I make use of the ion-nav-back-button to handle de master-detail views users and todos. This works completely automatically and Ionic handles this very well. Except for one case. When I refer to a detail view of a todo (e.g. /todos/3) from within another view (e.g. users/1), the back button does not appear, and there is no way to go back to the todos overview (/todos). A click on the tab button has no effect but going to /todos/3).
I guess this is expected behavior, but is there any way to show the back button anyway, or to make the tab button go to the todos view (/todos) at all times?
I found a solution. It's not ideal, but it works.
Instead of going directly to the detail state:
$state.go('tabs.todos', {
id: 1
});
I first go to the master state, and in the promise I go to the detail state:
$state.go('tabs.todos').then(function() {
setTimeout(function() {
$state.go('tabs.todos', {
id: 1
});
}, 100);
});
The timeout is not strictly necessary, but I've found that sometimes it fails without it.
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');
});