I am kind of a noob in Ionic and I need help / guidelines to build something that sounds easy.
I want to have a single page composed of multiple content, the idea is to have multiple views in the same page each of them being linked to a specific controller.
Here is my code:
index.html content:
<ion-pane>
<ion-nav-view></ion-nav-view>
<ion-view ng-controller="FirstController">
<ion-content>
</ion-content>
</ion-view>
<ion-view ng-controller="ScdController">
<ion-content>
</ion-content>
</ion-view>
</ion-pane>
In my app.js:
angular.module('app', [])
.controller('FirstController', function($scope) {
})
.controller('ScdController', function($scope) {
});
In my config.routes.js:
angular.module('app')
.config(configure);
function configure($stateProvider){
$stateProvider
.state('first', {
url: '/',
templateUrl: 'templates/first.html',
controller: 'FirstController'
})
.state('second', {
url: '/',
templateUrl: 'templates/second.html',
controller: 'ScdController'
});
}
Templates are very simple:
first.html:
<div>first</div>
second.html:
<div>Second</div>
Right now nothing is displayed.
What do you guys think?
Thanks for your help!
Your requirement is multiple named views.
Following document is useful to implement multiple views in a single page
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
Example code:
HTML:
<ion-view title="">
<ion-content scroll="true">
<div ui-view="first"></div>
<div ui-view="second"></div>
</ion-content>
</ion-view>
JS:
angular.module('app')
.config(function($stateProvider) {
$stateProvider
.state({
name : 'multiple-views'
views: {
'first': {
url: '/',
templateUrl: 'templates/first.html',
controller: 'FirstController'
},
'second': {
url: '/',
templateUrl: 'templates/second.html',
controller: 'ScdController'
}
}
});
Working example link: http://plnkr.co/edit/kZZ4KikwLITOxR5IGltr?p=preview
Related
I am trying to put on my app 3 page content in one .html file but I cant figure it out to do that. My .html page code is here:
<script id="templates/topList.html" type="text/ng-template">
<ion-view>
<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/topList2.html" type="text/ng-template">
<ion-view>
<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>
And my app.js is this:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'templates/home.html'
})
.state('registration', {
url: '/registration',
templateUrl: 'templates/registration.html',
controller: 'RegistrationCtrl'
})
.state('code_entery_page', {
url: '/code_entery_page',
templateUrl: 'templates/code_entery_page.html',
controller: 'code_entery_pageCtrl'
})
.state('registration-create-profile', {
url: '/registration-create-profile',
templateUrl: 'templates/registration-create-profile.html',
controller: 'registration-create-profileCtrl'
})
.state('app.main-traveler-page', {
url: '/main-traveler-page',
templateUrl: 'templates/main-traveler-page.html',
controller: 'main-traveler-pageCtrl'
})
.state('pinko.main-pinko-page', {
url: '/main-pinko-page',
templateUrl: 'templates/main-pinko-page.html',
controller: 'main-pinko-pageCtrl'
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/directives/traveler-navigation.html',
controller: 'AppCtrl'
})
.state('pinko', {
url: '/pinko',
abstract: true,
templateUrl: 'templates/directives/pinko-navigation.html',
controller: 'AppCtrl'
})
$urlRouterProvider.otherwise('/');
});
but I dont know how to connect to toplist.html and toplist2.html in app.js to work when my page is open?
In app.js - .state('pinko.main-pinko-page') is the page where i want to show toplist.html and toplist2.html
Add your both template in single html file like common-template.html.
And include this common-template in main-pinko-page.html as you mentioned in your question that's needed in .state('pinko.main-pinko-page').
If this one required in only one place use above case otherwise include this common-template in your main html file from where all the navigation initiates.
I'm using angular UI Router in Ionic to build an application but my one page news.html is not loading the content.It shows the view-title but not the stuffs inside ion-content , the page is blank.
this code is inside of a template news.html
<ion-view view-title="news">
<ion-content>
<div class="list card" ng-repeat="item in articles">
<div class="item item-thumbnail-left item-text-wrap">
<h2 class="post-title">{{item.name}}</h2>
<p class="post-author">{{item.description}}</p>
</div>
</div>
</ion-content>
</ion-view>
in app.js i have added the following ui route code
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('index', {
url: '/',
templateUrl: 'templates/home.html',
controller: 'mainCtrl'
})
.state('news', {
url: '/news',
templateUrl: 'templates/news.html',
controller: 'newsCtrl'
});
$urlRouterProvider.otherwise('/');
})
and my newsCtrl is
.controller('newsCtrl',function($scope, $http){
$http.get('https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey=4ff16a30e00640cab0a2a9731ccc9510').success(function(data){
$scope.articles = data.sources;
console.log('news control');
});
Same code works
carService.controller('newsCtrl', ['$scope', '$http', function($scope, $http) {
$http.get('https://newsapi.org/v1/sources?language=en').success(function(data) {
$scope.articles = data.sources;
console.log(data);
console.log('news control');
});
}]);
DEMO
I'm using the Ionic Framework to create a mobile app, but I'm having a difficult time with the UI Router. I've gotten a few screens working properly, but I can't seem to get nested views working on a state with parameters. I'd like a URL that looks like /legislator/1/profile. It would have a header with the name of legislator #1 and tabs below. The profile tab would be automatically visible and clicking on other tabs (e.g. /legislator/1/votes) would change the content, but not the header
I wound up abandoning the tabs & sidemenu starter projects to customize my nested views. Here's what I have in app.js. The home and people.* states work correctly, but I can't seem to load the legislator screen with the profile view in place. I've tried changing the abstract & controller attributes, but no luck yet.
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/home.html",
controller: "homeController"
})
.state('people', {
url: "/people",
abstract: true,
templateUrl: "templates/people.html"
})
.state('people.legislators', {
url: "/legislators",
templateUrl: "templates/legislators.html",
controller: "legislatorController"
})
.state('people.following', {
url: "/following",
templateUrl: "templates/following.html",
controller: "followingController"
})
.state('legislator', {
url: "/legislator/{legislatorId:int}",
templateUrl: "templates/legislator.html",
abstract: true
})
.state('legislator.profile', {
url: "/legislator/{legislatorId:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
.state('legislator.votes', {
url: "/legislator/{legislatorId:int}/votes",
templateUrl: "templates/legislator.votes.html",
controller: "votelistController"
})
$urlRouterProvider.otherwise('/home');
// if none of the above states are matched, use this as the fall-back
})
How is this scenario supposed to work in the UI Router? Once I have $stateProvider configured, how should the tabs link to the nested states?
Thanks for any help you can give me.
Maybe your solution is as simple as replacing the classic href by Ui Router's ui-sref:
replace
<ion-tab ... href="#/legislator/{ scopeLegislatorId }/profile">...</ion-tab>
by
<ion-tab ... ui-sref="legislator.profile({ legislatorId: scopeLegislatorId })">...</ion-tab>
Where scopeLegislatorId is the legislatorId, available from your scope.
If that doesn't help, please provide us with your html files (e.g. legislator.html and legislator.profile.html).
You can use following method to create separate views.
state('people.following',{
data:{
anyVar: {
label: 'cp',
text : 'anyText'
}
},
views: {
'content#people': angularAMD.route({
template: infoView,
controller: 'custInfoCtrl',
controllerUrl: 'modules/custCtrl'
}),
'mobileView#people': angularAMD.route({
template: mobileView,
controller: 'mobileCtrl',
controllerUrl: 'modules/mobileBottomViewCtrl'
})
}
})
<pre>
<div ui-view='contentArea'> </div>
<div ui-view='mobileView'> </div>
</pre>
RobYed pointed me in the right direction to figure out the right way to define my states. Here's the bones of what I wound up with.
app.js:
.state('legislator', {
url: "/legislator",
templateUrl: "templates/legislator.header.html",
abstract: true,
})
.state('legislator.profile', {
url: "/{seq_no:int}/profile",
templateUrl: "templates/legislator.profile.html",
controller: "profileController"
})
templates/legislator.header.html:
<ion-nav-view animation="slide-left-right">
<div class="bar bar-header" ng-controller="profileController">
{{legislator.name}}
</div>
<div class="tabs tabs-striped tabs-top">
<a class="tab-item" ui-sref="legislator.profile" ng-class="{selected: is('legislator.profile')}">
{{'Profile' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.votes" ng-class="{selected: is('legislator.votes')}">
{{'Votes' | translate}}
</a>
<a class="tab-item" ui-sref="legislator.stats" ng-class="{selected: is('legislator.stats')}">
{{'Stats' | translate}}
</a>
</div>
<div ui-view></div>
</ion-nav-view>
templates/legislator.profile.html:
<ion-content>
<div class="bar bar-stable has-subheader" style="height:145px;">
{{legislator.whatever}}
Content Here
</div>
</ion-content>
profileController.js:
'use strict';
angular.module('myApp').controller('profileController', function($scope, $rootScope) {
$scope.legislator = $rootScope.legislators[$stateParams.seq_no-1];
});
Links from other states:
<a ui-sref="legislator.profile({seq_no:legislator.seq_num})"></a>
Sorry if this is a stupid question I am still fairly new to this. I have a basic understanding of how the navigation works with angular js but I cant figure out how to set a starting page. I want to set my login page as my start page the url shows that the login page is open ("http://localhost:8100/#/template/login") but it only displays a blank header which I suspect is from my index (ion-nav-bar).
thank you.
index.html
<body ng-app="starter">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<!--
The views will be rendered in the <ion-nav-view> directive below
Templates are in the /templates folder (but you could also
have templates inline in this html file if you'd like).
-->
<ion-nav-view class="slide-left-right"></ion-nav-view>
</body>
</html>
login.html
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<h1>lalalalala</h1>
<div class="list">
<label class="item item-input">
<span class="input-label">Username</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Password</span>
<input type="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
</ion-view>
app.js
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
.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 && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
});
})
.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
// 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.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
.state('tab.dash', {
url: '/dash',
views: {
'tab-dash': {
templateUrl: 'templates/tab-dash.html',
controller: 'DashCtrl'
}
}
})
.state('tab.projects', {
url: '/projects',
views: {
'tab-projects': {
templateUrl: 'templates/tab-projects.html',
controller: 'projectsCtrl'
}
}
})
.state('tab.projects-detail', {
url: '/projects/:projectsId',
views: {
'tab-projects': {
templateUrl: 'templates/projects-detail.html',
controller: 'projectsDetailCtrl'
}
}
})
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'AccountCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('login');
});
controllers.js
angular.module('starter.controllers', [])
.controller('loginCtrl', function($scope) {})
.controller('DashCtrl', function($scope) {})
.controller('projectsCtrl', function($scope, Chats) {
$scope.chats = Chats.all();
$scope.remove = function(chat) {
Chats.remove(chat);
}
})
.controller('ChatDetailCtrl', function($scope, $stateParams, Chats) {
$scope.chat = Chats.get($stateParams.chatId);
})
.controller('AccountCtrl', function($scope) {
$scope.settings = {
enableFriends: true
};
});
I guess the problems is in your default route:
$urlRouterProvider.otherwise('/tab/login');
You have defined it depending from the abastract tab:
$stateProvider
// setup an abstract state for the tabs directive
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
and this is your login:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
the state name is tab.login which means it inherits from tab.
so your root is /tab/login.
this should be your tabs.html:
<ion-tabs class="tabs-icon-top tabs-color-active-positive">
<ion-tab title="Login" icon-off="ion-ios-pulse" icon-on="ion-ios-pulse-strong" href="#/tab/login">
<ion-nav-view name="login"></ion-nav-view>
</ion-tab>
<ion-tab title="Status" icon-off="ion-ios-pulse" icon-on="ion-ios-pulse-strong" href="#/tab/dash">
<ion-nav-view name="tab-dash"></ion-nav-view>
</ion-tab>
</ion-tabs>
as you can see your ion-nav-view name:
<ion-nav-view name="login"></ion-nav-view>
must match the one defined in your state:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'login.html',
controller: 'loginCtrl'
}
}
})
You don't need to set the view's name here (login.html):
<ion-view view-title="Login" name="login-view">
Another thing I've noticed, you use the same name for two different views: tab-projects:
.state('tab.projects', {
url: '/projects',
views: {
'tab-projects': {
templateUrl: 'templates/tab-projects.html',
controller: 'projectsCtrl'
}
}
})
.state('tab.projects-detail', {
url: '/projects/:projectsId',
views: {
'tab-projects': {
templateUrl: 'templates/projects-detail.html',
controller: 'projectsDetailCtrl'
}
}
})
another thing has more to do with conventions. If you use for your views names starting with tab-, probably you should do the same for the login.
Here is a plunker with some of your code.
I've been putting comments regarding your code, so let me formulate an answer with some steps you would like to follow
1:
You have a mess once you declare your controllers, try to follow a guide like this, at least declare your controllers/services/directives and so on in the same way, LoginCtrl and not loginCtrl and the other stuff with no capital as a first letter. It is just an advise my friend.
2:
.state('tab.login', {
url: '/login',
views: {
'login': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
here something you need to check, the name of your view, you have login but
<ion-view view-title="Login" name="login-view">
...
</ion-view>
so change it to login only. And do the same in your abstract route.
like this
<ion-view view-title="Login" name="login">
And this so important
$urlRouterProvider.otherwise('/login');
which goes at the end of the $stateProvider. The otherwise method will always redirect to /login in case that any other route it's been matched
Change your app.js to
.state('login', {
url: '/login',
controller: 'LoginCtrl',
templateUrl: 'templates/login.html'
})
and $urlRouterProvider.otherwise('/login');
If you place your login.html in correct folder then there is not going to be any problem.
You should give a name to your <ion-nav-view> in your index.html template.
e.g. <ion-nav-view name="viewContent"></ion-nav-view>
Then, in your routes, you specify into which part of your app you want your template to be rendered, e.g.:
.state('login', {
url: '/login',
views: {
'viewContent': {
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
}
}
})
this will render templates/login.html into the viewContent area.
That's why UI-router is so flexible, because you can tell it exactly which parts should be replaced when routing.
If you don't need that flexibility, just write your routes without the views part and add controller and templateUrl directly to each state.
also your fallback probably should be $urlRouterProvider.otherwise('/login');
If you want to evaluate a success at login to show certain views should not be in the same state.
This should be true:
.state('login',{
url: "/login",
views : {
'menuContent' : {
templateUrl : "login.html",
controller : "LoginCtrl"
}
}
})
$urlRouterProvider.otherwise("/login");
Follow the order as advice or guide on how to write their app.js
<script id="login.html" type="text/ng-template">
<ion-view view-title="Login" name="login-view">
<ion-content class="padding">
<h1>lalalalala</h1>
<div class="list">
<label class="item item-input">
<span class="input-label">Username</span>
<input type="text">
</label>
<label class="item item-input">
<span class="input-label">Password</span>
<input type="password">
</label>
</div>
<button class="button button-block button-calm" ng-click="login()">Login</button>
</ion-content>
</ion-view>
</script>
I had a similar problem..simply open your app.js file..then right at the bottom you will find $urlRouterProvider.otherwise('/app/tabs'); so for instance if the page thats currently loading is "tabs"
simply change the value tabs to your prefered page name inorder for that page to load as the first default page.
There is config.xml file. Open it and and you will see 'Start Page' Option. Then enter any page you want to start.
I am using ionic framework's sidemenu project to build something on top of it.
I have created this plunker to demonstrate my problem.
In the plunker, on the join page, when you click home, it shows blank screen. I can see that the HTML elements of sidemenu are all there, however, it doesnt showup on screen.
If I change my sidemenu with tabs, it works fine.
Does anyone know whats going on?
My sidemenu template looks like this:
<ion-side-menus>
<ion-pane side-menu-content>
<ion-nav-bar class="bar-dark nav-title-slide-ios7">
<ion-nav-back-button class="button-clear"><i class="icon ion-ios7-arrow-back"></i> Back</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view name="menuContent" animation="slide-left-right"></ion-nav-view>
</ion-pane>
<ion-side-menu side="left">
<header class="bar bar-header bar-dark">
<h1 class="title">Menu</h1>
</header>
<ion-content class="has-header">
<ion-list>
<ion-item nav-clear menu-close ui-sref="home">
Search
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
My states looks like this:
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
//url: "/app",
abstract: true,
templateUrl: "tpl.tabs.html",
controller: 'AppCtrl'
})
.state('join', {
url: "/join",
views: {
'': {
templateUrl: "tpl.join.html",
controller: 'joinCtrl'
}
}
})
.state('home', {
parent: 'app',
url: "/app",
views: {
'home': {
templateUrl: "tpl.home.html",
controller:'homeCtrl'
}
}
})
.state('menu', {
parent: 'app',
url: "/menu",
views: {
'menuContent': {
templateUrl: "tpl.home.html",
}
}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/join');
})
You had several misconceptions in your code here is how it works properly.
First of all, I recommend you to use the newest version of Ionic.
Then make sure you use the
<ion-side-menu-content></ion-side-menu-content>
and the parent/child view function of the ui-router with dot notation, for example:
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "tpl.tabs.html",
controller: 'appCtrl'
})
.state('app.join', {
url: "/join",
views: {
'menuContent': {
templateUrl: "tpl.join.html",
controller: 'joinCtrl'
}
}
});
I solved it myself.
The problem was with the naming of views of the states, which should match with the
ion-nav-view name in the abstract template.
The updated solution is here