<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width" />
<title></title>
<link rel="stylesheet" href="http://code.ionicframework.com/1.3.0/css/ionic.css" />
<link rel="stylesheet" href="style.css" />
<script src="http://code.ionicframework.com/1.3.0/js/ionic.bundle.js"></script>
<script src="ion-wizard.js"></script>
<script src="app.js"></script>
<script src="controllers.js"></script>
</head>
<body ng-app="starter">
<ion-nav-bar class="bar-positive">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>
/* Styles go here */
// Ionic Starter App, v0.9.20
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers', 'ionic.wizard'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('wizard', {
url: '/wizard',
abstract: true,
template: '<ion-nav-view></ion-nav-view>'
})
.state('wizard.intro', {
url: '/intro',
templateUrl: 'intro.html',
controller: 'IntroCtrl'
})
.state('app', {
url: "/app",
abstract: true,
templateUrl: "menu.html",
controller: 'AppCtrl'
})
.state('app.search', {
url: "/search",
views: {
'menuContent' :{
templateUrl: "search.html"
}
}
})
.state('app.browse', {
url: "/browse",
views: {
'menuContent' :{
templateUrl: "browse.html"
}
}
})
.state('app.playlists', {
url: "/playlists",
views: {
'menuContent' :{
templateUrl: "playlists.html",
controller: 'PlaylistsCtrl'
}
}
})
.state('app.single', {
url: "/playlists/:playlistId",
views: {
'menuContent' :{
templateUrl: "playlist.html",
controller: 'PlaylistCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/wizard/intro');
});
This is a side menu ionic framework starter template.
https://github.com/driftyco/ionic-starter-sidemenu
<ion-view title="Browse">
<ion-nav-buttons side="left">
<button menu-toggle="left"class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-content class="has-header">
<h1>Browse</h1>
</ion-content>
</ion-view>
<ion-side-menus>
<ion-pane ion-side-menu-content>
<ion-nav-bar class="bar-stable">
<ion-nav-back-button class="button-clear"><i class="icon ion-chevron-left"></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-stable">
<h1 class="title">Left</h1>
</header>
<ion-content class="has-header">
<ion-list>
<ion-item nav-clear menu-close href="#/app/search">
Search
</ion-item>
<ion-item nav-clear menu-close href="#/app/browse">
Browse
</ion-item>
<ion-item nav-clear menu-close href="#/app/playlists">
Playlists
</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
<ion-view title="Playlist">
<ion-content class="has-header">
<h1>Playlist</h1>
</ion-content>
</ion-view>
<ion-view title="Playlists">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-content class="has-header">
<ion-list>
<ion-item ng-repeat="playlist in playlists" href="#/app/playlists/{{playlist.id}}">
{{playlist.title}}
</ion-item>
</ion-list>
</ion-content>
</ion-view>
<ion-view title="Search">
<ion-nav-buttons side="left">
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<ion-content class="has-header">
<h1>Search</h1>
</ion-content>
</ion-view>
angular.module('starter.controllers', [])
.controller('AppCtrl', function($scope) {
})
.controller('PlaylistsCtrl', function($scope) {
$scope.playlists = [
{ title: 'Reggae', id: 1 },
{ title: 'Chill', id: 2 },
{ title: 'Dubstep', id: 3 },
{ title: 'Indie', id: 4 },
{ title: 'Rap', id: 5 },
{ title: 'Cowbell', id: 6 }
];
})
.controller('PlaylistCtrl', function($scope, $stateParams) {
})
.controller('IntroCtrl', ['$scope', '$state', '$ionicPopup', function($scope, $state, $ionicPopup) {
$scope.step2 = {};
$scope.step3 = {};
$scope.start = function() {
$state.go('app.playlists');
};
$scope.startCondition = function() {
return angular.isDefined($scope.step3.something);
};
}]);
/*
Ionic Wizard v2.0
2016-02-07
Updated to work with Ionic 1.2
*/
angular.module('ionic.wizard', [])
.directive('ionWizard', ['$rootScope', '$timeout', function($rootScope, $timeout) {
return{
restrict: 'EA',
controller: [function() {
var conditions = [];
this.addCondition = function(condition) {
conditions.push(condition);
};
this.getCondition = function(index) {
return conditions[index];
};
this.checkNextCondition = function(index) {
return index > (conditions.length - 1)
? false
: conditions[index].next();
};
this.checkPreviousCondition = function(index) {
return index > (conditions.length - 1)
? false
: conditions[index].prev();
};
}],
link: function (scope, element, attrs, controller) {
var currentIndex = 0;
scope.swiperOptions = angular.extend(scope.swiperOptions || {}, {
initialSlide: 0,
autoHeight: true,
onInit: function(swiper){
scope.swiper = swiper;
}
});
scope.$on("wizard:Previous", function() {
scope.swiper.slidePrev(true);
});
scope.$on("wizard:Next", function() {
scope.swiper.slideNext(true);
});
scope.$watch('swiper', function(swiper) {
if (!swiper) return;
swiper.on('onTransitionStart', function(e){
$timeout(function() {
currentIndex = e.activeIndex;
});
$rootScope.$broadcast("wizard:IndexChanged", e.activeIndex, swiper.slides.length);
});
})
// watch the current index's condition for changes and broadcast the new condition state on change
scope.$watch(function() {
return controller.checkNextCondition(currentIndex) && controller.checkPreviousCondition(currentIndex);
}, function() {
if (!scope.swiper) return;
var allowNext = controller.checkNextCondition(currentIndex),
allowPrev = controller.checkPreviousCondition(currentIndex);
if (allowNext)
scope.swiper.unlockSwipeToNext()
else
scope.swiper.lockSwipeToNext();
if (allowPrev)
scope.swiper.unlockSwipeToPrev()
else
scope.swiper.lockSwipeToPrev();
$rootScope.$broadcast("wizard:NextCondition", allowNext);
$rootScope.$broadcast("wizard:PreviousCondition", allowPrev);
});
}
}
}])
.directive('ionWizardStep', ['$q', function($q) {
return {
restrict: 'EA',
scope: {
nextConditionFn: '&nextCondition',
prevConditionFn: "&prevCondition"
},
require: '^^ionWizard',
link: function(scope, element, attrs, controller) {
var nextFn = function() {
// if there's no condition, just set the condition to true, otherwise evaluate
return angular.isUndefined(attrs.nextCondition)
? true
: scope.nextConditionFn();
};
var prevFn = function() {
return angular.isUndefined(attrs.prevCondition)
? true
: scope.prevConditionFn();
};
var conditions = {
next: nextFn,
prev: prevFn
};
controller.addCondition(conditions);
}
}
}])
.directive('ionWizardPrevious', ['$rootScope', function($rootScope) {
return{
restrict: 'EA',
scope: {},
link: function(scope, element, attrs, controller) {
element.addClass('ng-hide');
element.on('click', function() {
$rootScope.$broadcast("wizard:Previous");
});
scope.$on("wizard:IndexChanged", function(e, index) {
element.toggleClass('ng-hide', index == 0);
});
scope.$on("wizard:PreviousCondition", function(e, condition) {
element.attr("disabled", !condition);
});
}
}
}])
.directive('ionWizardNext', ['$rootScope', function($rootScope) {
return{
restrict: 'EA',
scope: {},
link: function(scope, element, attrs, controller) {
element.on('click', function() {
$rootScope.$broadcast("wizard:Next");
});
scope.$on("wizard:IndexChanged", function(e, index, count) {
element.toggleClass('ng-hide', index == count - 1);
});
scope.$on("wizard:NextCondition", function(e, condition) {
element.attr("disabled", !condition);
});
}
}
}])
.directive('ionWizardStart', [function() {
return{
restrict: 'EA',
scope: {
startFn: '&ionWizardStart',
startCondition: '&condition'
},
link: function(scope, element, attrs) {
element.addClass('ng-hide');
function checkCondition() {
return (angular.isUndefined(attrs.condition)) ? true : scope.startCondition();
}
element.on('click', function() {
scope.startFn();
});
scope.$watch(function() {
return checkCondition()
}, function(result) {
element.attr('disabled', !result);
});
scope.$on("wizard:IndexChanged", function(e, index, count) {
element.toggleClass('ng-hide', index < count - 1);
});
}
}
}]);
<ion-view>
<ion-nav-buttons side="left">
<button class="button button-light"
ng-click="start()">
Skip wizard
</button>
<button class="button button-light" ion-wizard-previous>
Back
</button>
</ion-nav-buttons>
<ion-nav-buttons side="right">
<button class="button button-light" ion-wizard-next>
Next
</button>
<button class="button button-light" ion-wizard-start="start()" condition="startCondition()">
Start App
</button>
</ion-nav-buttons>
<ion-slides options="swiperOptions" slider="swiper" ion-wizard>
<ion-slide-page ion-wizard-step>
<ion-content class="has-header">
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">Thanks for trying out this wizard!</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
</ion-content>
</ion-slide-page>
<ion-slide-page ion-wizard-step next-condition="step2.name" prev-condition="!step2.name">
<ion-content class="has-header">
<div class="row">
<div class="col col-center">
<div class="item item-input-inset">
<label class="item item-input-wrapper">
<i class="icon ion-search placeholder-icon"></i>
<input type="text" placeholder="Type something" ng-model="step2.name" autocomplete="off">
</label>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded" ng-hide="step2.name">
<div class="item">
<h2 class="positive">The next button has been disabled until the input is filled</h2>
</div>
</div>
<div class="card rounded" ng-show="step2.name">
<div class="item">
<h2 class="positive">Now you can move on! Click on the next button. The previous button has now been disabled</h2>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col col-center">
<div class="card rounded">
<div class="item">
<h2 class="positive">This slide is scrollable</h2>
</div>
<div class="item item-text-wrap">
<p>
Click the buttons above
</p>
</div>
</div>
</div>
</div>
</ion-content>
</ion-slide-page>
<ion-slide-page ion-wizard-step class="has-header">
<div class="row">
<div class="col col-center">
<h3 class="positive">Thanks for running the wizard!</h3>
<p>As a last step please fill in the field below</p>
<div class="item item-input-inset">
<label class="item item-input-wrapper">
<i class="icon ion-search placeholder-icon"></i>
<input type="text" placeholder="Type something" ng-model="step3.something" autocomplete="off">
</label>
</div>
<h3 ng-show="step3.something">You can now launch the app using the button above!</h3>
</div>
</div>
</ion-slide-page>
</ion-slides>
</ion-view>