Navigation with tabs not working - angularjs

I am trying to do navigation to tab list after selecting some items from the list.
when I am trying to run my code I am getting Cannot GET /tab/1337
my selection from the list looks like:
<div class="list">
<a ng-repeat="item in items"
href="/tab/{{item.queId}}"
class="item item-thumbnail-left">
My app.js looks like
.state('tabs.details', {
url: "/details/:itemqueId",
views: {
'details-tab': {
templateUrl: "templates/details.html",
controller: 'FriendDetailCtrl'
}
}
})
.state('tabs', {
url: "/tab/:itemqueId",
abstract: true,
templateUrl: "templates/tabs.html"
});
my tabs.html looks like:
<ion-view>
<ion-tabs class="tabs-icon-top">
<!-- Pets Tab -->
<ion-tab title="Dashboard" icon="icon ion-home" href="#/tab/dash">
<ion-nav-view name="tab-dash"></ion-nav-view>
</ion-tab>
<!-- Adopt Tab -->
<ion-tab title="details" icon="icon ion-heart" href="#/tab/details">
<ion-nav-view name="tab-details"></ion-nav-view>
</ion-tab>
</ion-tabs>
</ion-view>
don't know what can be the issue, but hope you will help!
Thanks!

Remove the line saying abstract: true in the tabs state definition - abstract states can not get activated. See ui-router docs.
Update:
What do you actually expect to happen when hitting /tab/1337?
Available Tabs
First of all, taking a look at the current state config, you have only a single valid route, since the tab state is abstract:
/tab/:itemqueId/details/:itemqueId
See how tab.details it will append it's url the one of tab, since it's a nested state of tabs. Therefor /tab/1337 is not a valid route.
What you might be looking for is /tab/:itemqueId/details - therefor change your url for tab.details to url: "/details"
Linking
Instead of using the href attribute, you should always prefer using the ng-href directive when interpolating variables from the angular scope.
In this case I'd even suggest to use ui-sref directive from ui-router. This way you can create urls with state definition and also check if your definition is valid.
<a ui-sref="tab.details({ itemqueId: item.queId })">
In the tabs.html your links should look like this to point to an sibling state - given that tabs.dash is a valid state similar to tabs.details:
<!-- Pets Tab -->
<ion-tab title="Dashboard" icon="icon ion-home" ui-sref="^.dash">
<ion-nav-view name="tab-dash"></ion-nav-view>
</ion-tab>
<!-- Adopt Tab -->
<ion-tab title="details" icon="icon ion-heart" href="^.details">
<ion-nav-view name="tab-details"></ion-nav-view>
</ion-tab>

Related

How do I add a new state to ui-router with Ionic tab

I am building an app using the Ionic framework tabbed view. Ionic already gives me tabs at the bottom but I also want two buttons at the top that changes the view. I cannot seem to get this to work. Specifically the one at the top right (see screenshot). Right now, when you click on it; it does nothing.
This is the tab interface they give me:
<ion-view id="page1">
<ion-tabs class="tabs-stable tabs-icon-bottom" id="tabsController-tabs1">
<ion-tab icon="ion-ios-photos" href="#/page1/index" id="tabsController-tab1">
<ion-nav-view name="tab1"></ion-nav-view>
</ion-tab>
<ion-tab icon="ion-camera" ng-if="timer === '0m'" ng-click="indexController.camera()">
<ion-nav-view name="tab3"></ion-nav-view>
</ion-tab>
<ion-tab title="{{timer}}" ng-if="timer !== '0m'" disabled="true" ng-if="true" ng-click="indexController.camera()">
<ion-nav-view name="tab3"></ion-nav-view>
</ion-tab>
<ion-tab icon="ion-android-list" href="#/page1/bestMoments" id="tabsController-tab2">
<ion-nav-view name="tab2"></ion-nav-view>
</ion-tab>
</ion-tabs>
</ion-view>
In my routes.js I have this state for my new button:
.state('tabsController.myMoments', {
url: '/myMoments',
cache:false,
views: {
'tab4': {
templateUrl: 'myMoments/myMoments.html',
controller: 'MyMomentsController',
controllerAs: 'vm'
}
}
})
I have also, sort of 'hacked' the button. Its not actually a tabbed state, its just a button with a ng-click that sends you to the desired state. I put this code in my index.html:
<ion-nav-buttons side="right">
<div class="ion-person" ng-click="indexController.redirectMyMoments()"></div>
</ion-nav-buttons>
I don't understand where I am supposed to put 'tab4'. My assumption is that it goes with these rest of my tabs but no matter where I put it, it seems to mess up my other tabs and I don't want to make another ion-tab in there because I don't want it to be at the bottom.
I have also noticed that if I change the view name to 'tab3' it actually works so it is changing the state correctly, however, it highlights the third tab when you click on the top right view which is also bad.
Thanks for any help.
EDIT:
Plunker of my problem:
https://plnkr.co/edit/PTS9Jt?p=preview
Your last tab name is suppose to be tab4 instead of tab2 in your tab interface.
<ion-view id="page1">
<ion-tab icon="" href="#/page1/index" id="tabsController-tab2">
<ion-nav-view name="tab2"></ion-nav-view>
</ion-tab>
<ion-tab icon="ion-camera" ng-if="timer === '0m'" ng-click="indexController.camera()">
<ion-nav-view name="tab3"></ion-nav-view>
</ion-tab>
<ion-tab title="{{timer}}" ng-if="timer !== '0m'" disabled="true" ng-if="true" ng-click="indexController.camera()">
<ion-nav-view name="tab3"></ion-nav-view>
</ion-tab>
<ion-tab icon="ion-android-list" href="#/page1/bestMoments" id="tabsController-tab4">
<ion-nav-view name="tab4"></ion-nav-view>
</ion-tab>
Replace your code with this.
--------------------------UPDATE------------------------
Now, for Tab-3, You cannot have multiple tabs with same name. So what you can do in it is you can create a nested view in it. As in, you can have 2 views in it with different names.. one timer and one camera(OR ANYTHING ELSE YOU WANT). Here is the reference of multiple views in one tab. ionic multiple view states for one tab
Now each of your tab will have a unique name and a unique-associated id for them. So you can style it as you want it to look like.

Setting up different tab navigation depending on view Ionic

I have a tricky problem (or at least I think its tricky). I have set up tabs in ionic by having a menu view with an associated abstract route.
menu.html:
<ion-nav-bar class="bar-custom">
<!-- Add Back Button Directive -->
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view name="menuContent">
<ion-tabs class="tabs-stable tabs-icon-top">
<ion-tab title="Dashboard" icon="ion-home" ui-sref="app.headlines">
<ion-nav-view name="dashboard"></ion-nav-view>
</ion-tab>
<ion-tab title="Portfolio" icon="ion-arrow-graph-up-right" ui-sref="app.stocks">
<ion-nav-view name="portfolio"></ion-nav-view>
</ion-tab>
<ion-tab title="Alerts" icon="ion-ios-bolt" ui-sref="app.alerts">
<ion-nav-view name="alerts"></ion-nav-view>
</ion-tab>
<ion-tab title="Saved" icon="ion-bookmark" ui-sref="app.saved-posts">
<ion-nav-view name="saved"></ion-nav-view>
</ion-tab>
<ion-tab title="Accounts" icon="ion-gear-a" ui-sref="app.accounts">
<ion-nav-view name="accounts"></ion-nav-view>
</ion-tab>
</ion-tabs>
</ion-nav-view>
piece of routes.js:
angular.module('starter')
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'LoginController',
cache: false
})
The tabs work beautifully and just as I would expect. The next step is to change what those tab options are depending on what view I currently am on. So for example instead of Dashboard, Portfolio, Alerts, Saved, Accounts, that I have set as a default, I want options that will lead to foo, bar and foo2. What is the best approach to accomplish this? I have read a little on nested tabs but I don't think that is the way to go (seems to be for having tabs on top of tabs or something).

Concerns about ionic navigate out of tab but keep history, transition and back button

Navigate to Friends tab then click "G.I. Joe".
Back button, transition and history are working as expected.
this sample
But I want it to hide the tabs while entering the details page, so I made the view replace the main nav, like this:
.state('tab.friend-detail', {
url: '/friend/:friendId',
views: {
'#': {
templateUrl: 'friend-detail.html',
controller: 'FriendDetailCtrl'
}
}
})
But now Back button, transition and history stop working.
expected to work
Here is just what I want
Looking at your tabs.html:
<!--
Create tabs with an icon and label, using the tabs-positive style.
Each tab's child <ion-nav-view> directive will have its own
navigation history that also transitions its views in and out.
-->
<ion-tabs class="tabs-icon-top">
<!-- Pets Tab -->
<ion-tab title="Dashboard" icon="icon ion-home" href="#/tab/dash">
<ion-nav-view name="tab-dash"></ion-nav-view>
</ion-tab>
<!-- Adopt Tab -->
<ion-tab title="Friends" icon="icon ion-heart" href="#/tab/friends">
<ion-nav-view name="tab-friends"></ion-nav-view>
</ion-tab>
<!-- About Tab -->
<ion-tab title="Account" icon="icon ion-gear-b" href="#/tab/account">
<ion-nav-view name="tab-account"></ion-nav-view>
</ion-tab>
</ion-tabs>
it already states at the top that each ion-nav-view has its own navigation history.
So if you load the details html in another view you'll lose history information. Hence there's no backbutton.
However, look at this proposed solution witch uses a custom directive to achieve what you want.
Here is the expected to work.
How ?
I added the tabs-item-hide class for the <ion-tabs> tag with ng-class.
Then use $rootScope as a flag inside every controller to detect if current view wants to show or not the tabs.
Maybe my solution is not good enough, but I think it will help you.
Cons?
You have to put the $rootScope flag (in my example is : $rootScope.data.hideTabs) in every controller that you want the tabs to show or hide.
Everything inside <ion-content> won't be shown.
But you can modify it anytime for better usage, for example you can create a factory to manage it.
P/S: I have inspired from this post

Ionic: No back button when navigating away from tab view

I cannot figure out how to get the back button to show when navigating away from a tabbed view to a single page view. The single page view shouldn't have the tab bar. I can make the back button appear when I make the view I'm navigating to part of the tab hierarchy, but that's not what I want.
I've been looking around and can't seem to find a post on this issue. I just might not be searching for the right keywords.
My set up is this...
tabs: tab.feed, tab.friends, tab.account
other view: randompage
Here is my route set up...
.state('randompage', {
url:'/randompage',
templateUrl: 'templates/randompage.html',
controller: 'RandomPageCtrl'
})
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html',
controller: 'TabCtrl'
})
.state('tab.feed', {
url: '/feed',
views: {
'tab-feed': {
templateUrl: 'templates/tab-feed.html',
controller: 'FeedCtrl'
}
}
})
Here is the tabs.html
<ion-tabs class="tabs-icon-top tabs-top">
<!-- Feed Tab -->
<ion-tab title="Feed" icon="icon ion-ios7-paper" href="#/tab/feed">
<ion-nav-view name="tab-feed"></ion-nav-view>
</ion-tab>
<!-- The rest are just from the tab skeleton -->
<ion-tab title="Friends" icon="icon ion-heart" href="#/tab/friends">
<ion-nav-view name="tab-friends"></ion-nav-view>
</ion-tab>
<ion-tab title="Account" icon="icon ion-gear-b" href="#/tab/account">
<ion-nav-view name="tab-account"></ion-nav-view>
</ion-tab>
</ion-tabs>
Here is the tab-feed.html
<ion-view title="Feed">
<ion-nav-buttons side="right">
<a class="button button-icon ion-android-camera" href="#/randompage"></a>
</ion-nav-buttons>
<ion-content class="padding">
<h1>Feed</h1>
</ion-content>
</ion-view>
Here is the randompage.html
<ion-view title="Random Page">
<ion-content lass="padding">
</ion-content>
</ion-view>
Everything navigates and shows correctly except the back button is not showing.
Please let me know if you know of any alternate solution, possibly what I may be doing wrong, or need more information.
Thanks!
This has been a long time problem for me as well. While the history stack is broken in this use case, 'backView' in the history object is correct. The full history object can be seen with this log line:
console.log( JSON.stringify($ionicHistory.viewHistory(), null, 4) );
My solution is to manually add in a Back button on global pages.
Global page html:
<ion-view view-title="Help">
<ion-nav-buttons side="left">
<button class="button button-clear" ng-click="goBack()"><i class="icon ion-arrow-left-c" ></i> Back</button>
</ion-nav-buttons>
Javascript:
$scope.goBack = function() {
$ionicHistory.goBack();
};
Another alternative is to modify the ionic source. Replace enabledBack() in ionic.bundle.js with this:
enabledBack: function(view) {
//original code
//var backView = getBackView(view);
//return !!(backView && backView.historyId === view.historyId);
//new code to show back
var backView = viewHistory.backView;
return backView != null;
},
I have the same issue. By check the source code, ionic sets up an default history stack named root history, views are pushed and popped from the stack as user navigate through the app. However, the tab view is taken out of this default history stack and a new stack will be setup for it.
splash view --> tab view --> random page (out of tab)
|
tab1 --> nested view (in tab)
|
tab2 --> nested view (in tab)
root history stack:
splash view ---> random page
tab history stack:
tab view ---> tab1 --> nested view
---> tab2 --> nested view
I couldn't find an easy way to change this behavior. But there's a workaround work for my case. I created a normal ionic view and composed the tab view by myself so no new history stack will be created.
<ion-view title="tabs">
<ion-content padding="false">
<ion-pane>
<ion-nav-view name="tab-content"></ion-nav-view>
</ion-pane>
<div class="tabs tabs-icon-top" style="position: absolute;bottom: 0;">
<a class="tab-item">
<i class="icon ion-home"></i>
Home
</a>
<a class="tab-item">
<i class="icon ion-star"></i>
Favorites
</a>
<a class="tab-item">
<i class="icon ion-gear-a"></i>
Settings
</a>
</div>
</ion-content>
</ion-view>
then you can set up your $stateProvider to load different tab view into tab-content to mimics the ion-tabs behavior. Of course you have to maintain the active states of tabs by yourself.
I am sorry I don't have enough reputation to add a comment.
Ryan's answer worked like a charm for me(not the modify ionic source part), I just want to add a point that if one uses
ng-click="$ionicGoBack()"
instead of
ng-click="goBack()"
the Javascript can be omitted.

Angularjs + Ionic Framework: How to create a new route that shows the ion-tabs navigation but without defining a tab for itself?

Long title but here is a better explanation.
I have a template html file called "Login". I define a route in app.js like so
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'createAccountCtrl'
})
By using ui-sref="login" I can link to this template from anywhere which is perfect for my needs.
However the main app uses an abstract route "tab" to load the tabs template which contains the main navigation.
.state('tab.about', {
url: '/about',
views: {
'about-tab': {
templateUrl: 'templates/about.html',
controller: 'aboutCtrl'
}
}
})
<ion-tabs tabs-style="tabs-icon-top" tabs-type="tabs-default">
<!-- Home Tab -->
<ion-tab title="Home" icon="icon ion-home" href="#/tab/home">
<ion-nav-view name="home-tab"></ion-nav-view>
</ion-tab>
<!-- Products Tab -->
<ion-tab title="Earn Points" icon="icon ion-ios7-plus-outline" href="#/tab/retail-store">
<ion-nav-view name="retail-store-tab"></ion-nav-view>
</ion-tab>
</ion-tabs>
My problem is this. I want the Login page to have the main app's navigation like every other page has. That way a user who makes it to the login page, if they don't to login can still navigate off to the home or about page. But, I do not want a navigation tab/icon of its own to show.
Is is possible to just add the tabs html directly to the login.html template file or possibly hide the login icon/tab. I am open to suggestions and help. Thank you!
The tabs are meant to have their own tab icon. So you can't put the login page inside the tabs abstract view without creating a tab icon for it.
Instead of putting the login page under the tab abstract view, you should just put a separate tabbed navigation for the login page.
Load the following view into your index page.
<ion-view title="'Login'">
<ion-content has-header="true" has-footer="true" padding="true">
Login page content goes here
</ion-content>
<div class="tabs tabs-icon-left">
<a class="tab-item" href="#/tab/home">
Home
</a>
<a class="tab-item" href="#/tab/about">
About
</a>
</div>
</ion-view>

Resources