I am using Ionic 1.3, and I have built a side menu app.
In on of my page, I want to have Tabs to display 3 different pages.
Here is my code (app.js) :
//MAIN
.state('app', {
url: "/app",
abstract: true,
templateUrl: "views/app/side-menu.html",
controller: 'AppCtrl'
})
//PROFIL
.state('app.profil', {
url: "/profil",
abstract: true,
views: {
'menuContent': {
templateUrl: "views/app/profil/tabs.html",
}
}
})
//PROFIL TAB 1
.state('app.profil.tab1', {
url: "/tab1",
views: {
'tabProfilContent': {
templateUrl: "views/app/profil/tab1.html",
controller: 'ProfilCtrl'
}
}
})
And here's my tabs.html view :
<ion-view class="profile-view">
<ion-nav-title>
<span>Votre profil</span>
</ion-nav-title>
<ion-header>
<div class="tabs-striped tabs-top tabs-background-positive tabs-color-light">
<div class="tabs">
<a class="tab-item" ui-sref="app.profil.tab1">
Tab 1
</a>
<a class="tab-item" ui-sref="app.profil.tab2">
Tab 2
</a>
<a class="tab-item" ui-sref="app.profil.tab3">
Tab 3
</a>
</div>
</div>
</ion-header>
<ion-nav-view name="tabProfilContent"></ion-nav-view>
</ion-view>
It works, but, is there a way to set the status of tab ? The tabs are not active while I change Tab. Is this the correct way to achieve it ?
Related
The short story:
When I open up the index page using gulp watch, I see nothing.
I get the error:
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.12/$injector/modulerr?p0=confusionApp&p1=Er…0(http%3A%2F%2Flocalhost%3A3000%2Fscripts%2Fmain-94e7868a45.js%3A1%3A18165)
When I hit the link to see what the error is, it says that:
Failed to instantiate module {0} due to:
{1}
It then goes into ngRoute issues which I'm not using at this point, as I am using angular-ui-router.
I can't go any further without solving this problem so I'm throwing it up to you guys.
The code is below, but bear in mind,I am only including the areas I have changed in the assignment as it would be too long for this post. So if there's any other code you'd like to see, please put them into the contents.
Thanks.
header.html
...
<ul class="nav navbar-nav">
<li class="active">
<a ui-sref="app">
<span class="glyphicon glyphicon-home"
aria-hidden="true"></span> Home</a></li>
<li><a ui-sref="app.aboutus">
<span class="glyphicon glyphicon-info-sign"
aria-hidden="true"></span> About</a></li>
<li><a ui-sref="app.menu">
<span class="glyphicon glyphicon-list-alt"
aria-hidden="true"></span>
Menu</a></li>
<li><a ui-sref="app.contactus">
<i class="fa fa-envelope-o"></i> Contact</a></li>
</ul>
...
footer.html
...
<ul class="list-unstyled">
<li><a ui-sref="app">Home</a></li>
<li><a ui-sref="app.aboutus">About</a></li>
<li><a ui-sref="app.menu">Menu</a></li>
<li><a ui-sref="app.contactus">Contact</a></li>
</ul>
...
app.js
'use strict';
angular.module('confusionApp',['ui.router'])
.config(function($stateProvider, $urlRouteProvider){
$stateProvider
//route for the home page
.state('app', {
url:'/',
views: {
'header': {
templateUrl: 'views/header.html',
},
'content': {
template: '<h1>To be completed</h1>',
controller: 'IndexController'
},
'footer': {
templateUrl: 'views/footer.html',
}
}
})
//route to aboutus page
.state('app.aboutus', {
url:'aboutus',
views: {
'content#': {
template: '<h1>To be completed</h1>',
controller: 'AboutController'
}
}
})
//route to contactus page
.state('app.contactus', {
url:'contactus',
views: {
'content#': {
templateUrl: 'views/contactus.html',
controller: 'ContactController'
}
}
})
//route to menu page
.state('app.menu', {
url:'menu',
views: {
'content#': {
templateUrl: 'views/menu.html',
controller: 'MenuController'
}
}
})
//route to dishdetail page
.state('app.dishdetail', {
url:'menu/:id',
views: {
'content#': {
templateUrl: 'views/dishdetail.html',
controller: 'DishDetailController'
}
}
});
$urlRouteProvider.otherwise('/');
})
;
menu.html
...
<div class="media-left media-middle">
<a ui-sref="app.dishdetail({id: dish._id})">
<img class="media-object img-thumbnail" ng-src={{dish.image}} alt={{dish.name}} />
</a>
</div>
...
index.html
<body>
<div ui-view="header"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>
<!-- build:js scripts/main.js -->
<script src="../bower_components/angular/angular.min.js"></script>
<!-- <script src="../bower_components/angular-route/angular-route.min.js"></script> -->
<script src="../bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers.js"></script>
<script src="scripts/services.js"></script>
<!-- endbuild -->
</body>
When I downloaded the new app.js file, it fixed everything, but there wasn't that much different between the two files. (Much frustration.)
The templates were replaced with templateUrls which I had actually done and everything was the same, but when I just copied and pasted the code over my code, it worked.
Here is the new working code:
'use strict';
angular.module('confusionApp', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// route for the home page
.state('app', {
url:'/',
views: {
'header': {
templateUrl : 'views/header.html',
},
'content': {
templateUrl : 'views/home.html',
controller : 'IndexController'
},
'footer': {
templateUrl : 'views/footer.html',
}
}
})
// route for the aboutus page
.state('app.aboutus', {
url:'aboutus',
views: {
'content#': {
templateUrl : 'views/aboutus.html',
controller : 'AboutController'
}
}
})
// route for the contactus page
.state('app.contactus', {
url:'contactus',
views: {
'content#': {
templateUrl : 'views/contactus.html',
controller : 'ContactController'
}
}
})
// route for the menu page
.state('app.menu', {
url: 'menu',
views: {
'content#': {
templateUrl : 'views/menu.html',
controller : 'MenuController'
}
}
})
// route for the dishdetail page
.state('app.dishdetails', {
url: 'menu/:id',
views: {
'content#': {
templateUrl : 'views/dishdetail.html',
controller : 'DishDetailController'
}
}
});
$urlRouterProvider.otherwise('/');
})
;
And if you are facing the same issue with the same course, then please copy and paste the app.js code even if you've filled everything in correctly.
I want to build an app that uses both tab interface and side menu for going to states.
Now what I want is that side menu linked views also have original tabs under their selected tabs, once on those new views.
router.js
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "js/base/menu.html"
})
.state('app.tabs', {
url: '/tabs',
views: {
'menuContent': {
templateUrl: 'js/base/tabs.html',
controller: 'TabsController as tabsController'
}
}
})
.state('app.tabs.old', {
url: '/old',
views: {
'old': {
templateUrl: 'js/old/old.html',
}
}
})
.state('app.tabs.new', {
url: '/new',
views: {
'new': {
templateUrl: 'js/new/new.html',
}
}
})
.state('app.tabs.profile', {
url: '/profile',
views: {
'profile': {
templateUrl: 'js/profile/profile.html'
}
}
});
$urlRouterProvider.otherwise('/app/tabs');}
Here old and new are in tabs, while profile should be accessed from side menu, and also have old and new tabs on bottom on its view.
menu.html
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="header-style">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view name="menuContent"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="right">
<ion-content>
<ion-list>
<!--THE MOST IMPORTANT PART-->
<ion-item nav-clear class="item item-avatar" href="#/profile">
<img src="../images/img/avatar/header-avatar-2.png">
<h2 class="item-text-center">{{user}}'s Profile</h2>
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
Now the most important is in ion-item, I tried everything, from
href
onclick
ng-click to go to state
ui-sref
and obviously did not do it right.
Any suggestions how to connect the profile view to the app?
My project has the file home, page1, page2.
My home page has a different header layout than the rest of my pages. So, it is a separate html file. page1 and page 2 is using ui routing to load in the content of the page, but the header and footer are the same.
My Question is: if I am on the home page and click btn 1. how do I get it to load in the content of page1? (It will load index.html, but no content of btn1.)
I'm not sure if passing an id to the index.js is a solution and I'm not sure how to even do that. Would it make more sense to just make the entire thing a SPA?
My home.html with the buttons:
<a type="text/html" href="home.html" class="button home_btn">Home</a>
<a type="text/html" href="index.html" class="button my_btn1">Page1</a>
<a type="text/html" href="index.html" class="button my_btn2">Page2</a>
My idex.html:
<body>
<div class="container" ng-app="app">
<header ng-include="'html/header.html'"></header>
<div ui-view></div>
<footer ng-include="'html/footer.html'"></footer>
</div>
</body>
<script src="vendors/angular/angular.js"></script>
<script src="vendors/angular-ui-router/release/angular-ui-router.js </script>
<script src="scripts/index.js"></script>
my header.html:
<div id="headerLinks">
<a type="text/html" href="home.html" class="button home_btn">Home</a>
<a type="text/html" ui-sref="page1" class="button my_btn1">Page1</a>
<a type="text/html" ui-sref="page2" class="button my_btn2">Page2</a>
</div>
</div>
my index.js:
var app = angular.module('app', ['ui.router']);
app.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('Page1', {
url: 'Page1',
templateUrl: 'Page1.html',
controller: 'Page1Ctrl'
})
.state('Page2', {
url: 'Page2',
templateUrl: 'Page2.html',
controller: 'Page2Ctrl'
})
}])
I"m kinda confused by what I was asking now that I look at it. I believe I was asking how to build a router with multiple pages. I got that to work. if this doesn't help, I'll see if I can find a resource or explain it better.
import angular-ui-router.
<script src="vendors/angular-ui-router/release/angular-ui-router.js" type="text/javascript"></script>
This is what my index.js file now looks like. it has multiply views which allow for different header or content or footer or whatever.
var app = angular.module('app', [
'ui.router',
'ctrls'
]);
app.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider, $state) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home',{
url: '/home',
views: {
'header': {
templateUrl: 'html/headerHome.html',
controller: 'headCtrl'
},
'content': {
templateUrl: 'home.html',
//controller: 'ContentController'
}
}
})
.state('page1', {
url: '/page1',
views: {
'header': {
templateUrl: 'html/header.html',
controller: 'headCtrl'
},
'content': {
templateUrl: 'page1.html',
controller: 'page1Ctrl'
}
}
})
.state('page2', {
url: '/page1',
views:{
'header':{
templateUrl: 'html/header.html',
controller: 'headCtrl'
},
'content':{
templateUrl: 'page2.html',
controller: 'page2Ctrl'
}
}
})
Within the Ionic Framework, you can setup tabs. The pages within the tabs can easily transition using a slide-left-right or some other type of transition. This makes the application feel smooth and thought-out.
The issue that I have is that the pages associated with each tab, once clicked from the tab menu, do not transition at all, there is just boom: a page.
I found a pen on codepen (link to codepen demo) that can replicate this effect as I want it (to some degree), but I cannot replicate it in any scenario, much less the Ionic rc0 (1.0) version.
The codepen code uses an animation that seems to not work elsewhere:
<ion-nav-view animation="slide-left-right"></ion-nav-view>
Please assist.
I haven't tried to get that exact example working, but I achieved a similar effect in one of my apps by giving all the tabs the same view name:
app.js
$stateProvider
.state('signin', {
url: "/sign-in",
templateUrl: "sign-in.html",
controller: 'SignInCtrl'
})
.state('forgotpassword', {
url: "/forgot-password",
templateUrl: "forgot-password.html"
})
.state('tabs', {
url: "/tab",
abstract: true,
templateUrl: "tabs.html"
})
.state('tabs.home', {
url: "/home",
views: {
'tab-view': {
templateUrl: "home.html",
controller: 'HomeTabCtrl'
}
}
})
.state('tabs.facts', {
url: "/facts",
views: {
'tab-view': {
templateUrl: "facts.html"
}
}
})
.state('tabs.facts2', {
url: "/facts2",
views: {
'tab-view': {
templateUrl: "facts2.html"
}
}
})
.state('tabs.about', {
url: "/about",
views: {
'tab-view': {
templateUrl: "about.html"
}
}
})
tabs.html
<ion-tabs tabs-style="tabs-icon-top" tabs-type="tabs-positive" animation="slide-left-right">
<ion-tab title="Home" icon="ion-home" href="#/tab/home">
<ion-nav-view name="tab-view"></ion-nav-view>
</ion-tab>
<ion-tab title="About" icon="ion-ios7-information" href="#/tab/about">
<ion-nav-view name="tab-view"></ion-nav-view>
</ion-tab>
</ion-tabs>
Notice the name "tab-view" for each state and again as the name attribute on the ion-nav-view in each tab.
This helped me to find a solution https://github.com/driftyco/ionic/issues/2997 . The trick is to load all tabs in single view. You can't use ion-tabs directive to achieve that, you you will have to create your tab container using regular html:
<ion-view title="Tabs Controller">
<!-- All tabs are going to load here -->
<ion-nav-view name="menuContent"></ion-nav-view>
<!-- TABS -->
<div class="tabs-stable tabs-icon-top tabs-bottom tabs-standard">
<div class="tab-nav tabs">
<a class="tab-item" ng-click="goTabForums()" ng-class="{ active : settings.isTab1}">
<i class="icon bb-ios-forums"></i>
<span translate="TABS.FORUMS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabGroups()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-forums"></i>
<span translate="TABS.GROUPS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabTopics()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-topics"></i>
<span translate="TABS.TOPICS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabNotifications()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-notifications"></i>
<span translate="TABS.NOTIFICATIONS_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabProfile()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-my-profile"></i>
<span translate="TABS.MY_PROFILE_TAB"></span>
</a>
<a class="tab-item" ng-click="goTabMore()" ng-class="{ active : settings.isTab2 }">
<i class="icon bb-ios-more"></i>
<span translate="TABS.MORE_TAB"></span>
</a>
</div>
</div>
your tabs controller should look like this:
.controller('tabsCtrl', function($scope, $ionicConfig, $state) {
$scope.goTabForums = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.forums');
}
$scope.goTabGroups = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.groups');
}
$scope.goTabTopics = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.topics');
}
$scope.goTabNotifications = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.notifications');
}
$scope.goTabProfile = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.profile');
}
$scope.goTabMore = function(){
$ionicConfig.views.transition('platform');
$state.go('tabsController.more');
}})
And finally routs:
$stateProvider
.state('tabsController.forums', {
url: '/forums',
views: {
'menuContent': {
templateUrl: 'templates/forums.html',
controller: 'forumsCtrl'
}
}})
.state('tabsController.topics', {
url: '/topics',
views: {
'menuContent': {
templateUrl: 'templates/topics.html',
controller: 'topicsCtrl'
}
}})
I wrote an app with angular.js and trying to load different subviews based on the page they land on. Specifically, when the user is landing on the english version a partial view is loaded and when they land on the french version a different one is loaded. But whatever I'm not seeing in my code makes the subview always land on the ELSE (or '/') route. This is the current code in my appRoutes.js file...
angular.module('appRoutes', []).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
var homeLang = document.documentElement.getAttribute('lang');
var english = 'en';
var homeView = function (homeLang) {
if (homeLang === english) {
homeView = '/';
return homeView;
} else {
homeView = '/accueil';
return homeView;
}
};
$routeProvider
// client routes
.when('/', {
templateUrl: 'views/home.html',
controller: 'MainController'
})
.when('/web', {
templateUrl: 'views/web.html',
controller: 'MainController'
})
.when('/design', {
templateUrl: 'views/design.html',
controller: 'MainController'
})
.when('/hosting', {
templateUrl: 'views/hosting.html',
controller: 'MainController'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'MainController'
})
.when('/accueil', {
templateUrl: 'views/accueil.html',
controller: 'MainController'
})
.when('/sites', {
templateUrl: 'views/sites.html',
controller: 'MainController'
})
.when('/services', {
templateUrl: 'views/services.html',
controller: 'MainController'
})
.when('/hebergement', {
templateUrl: 'views/hebergement.html',
controller: 'MainController'
})
.when('/contactez', {
templateUrl: 'views/contactez.html',
controller: 'MainController'
})
.otherwise({ redirectTo: homeView });
$locationProvider.html5Mode(true);
}]);
Here is the HTML that loads the different views.
<body ng-app="myApp">
<div class="navbar-wrapper">
<div class="container">
<div role="navigation" class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target=".navbar-collapse" class="navbar-toggle collapsed"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div class="navbar-collapse collapse">
<div class="nav navbar-nav">
<li>Accueil</li>
<li>Sites & Apps</li>
<li>Design</li>
<li>Hébergement</li>
<li>Contact</li>
</div>
</div></div></div></div></div>
<section class="content">
<div ng-view></div></section></body>
in your view, you can load a different template based on language without changing routing.
for example have in the routed view something like
than you can also add a ng-if before each span to check the language value.
I actually went back to the code and used ui-router instead and created states with building blocks (several views) and it solved all my issues!! :)