<!DOCTYPE html>
<html ng-app="QaOmatic">
<head>
<title>AngularJS: ui-router & deep linking</title>
<link href="style.css" rel="stylesheet">
<link href="http://goo.gl/5fjaQ" rel="stylesheet"><!--Bootstrap-->
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#/">QA-o-matic</a>
<ul class="nav">
<li ng-class="{active:$state.includes('manage')}">
<a href="#/manage/store/1234/complaints">Manage</a></li>
<li ng-class="{active:$state.includes('assess')}">
<a href="#/assess">Assess</a></li>
<li ng-class="{active:$state.includes('analyze')}">
<a href="#/analyze">Analyze</a></li>
</ul>
</div>
</div>
<div ui-view>
<!-- First Level -->
</div>
</div>
<div class="container">
<pre>
$state = {{$state.current.name}}
$stateParams = {{$stateParams}}
</pre>
</div>
<script src="http://goo.gl/63o9b">/*Angular*/</script>
<script src="http://goo.gl/hhjaS">/*jQuery*/</script>
<script src="http://goo.gl/aixcg">/*Bootstrap*/</script>
<script src="ui_router.js"></script>
<script src="script.js"></script>
</body>
</html>
angular.module('QaOmatic',['ui.compat']).config(function($stateProvider,$routeProvider){
var home = {redirectTo:'/home'};
$routeProvider
.when('', home)
.when('/', home);
$stateProvider
/* Home */
.state('home', {
url:'/home',
templateUrl:'home.html'
})
/* Manage */
.state('manage', {
abstract:true,
templateUrl:'manage.html'
})
/* Manage > Store */
.state('manage.store', {
abstract:true,
templateUrl:'manage_store.html'
})
/* Manage > Edit Store */
.state('manage.editStore', {
url:'/manage/store/:id/edit',
templateUrl:'manage_editStore.html'
})
/* Manage > Store > Complaints */
.state('manage.store.complaints', {
url:'/manage/store/:id/complaints',
templateUrl:'manage_store_complaints.html'
})
/* Manage > Store > Add Complaints */
.state('manage.store.addComplaint', {
url:'/manage/store/:id/addcomplaint',
templateUrl:'manage_store_addComplaint.html'
})
/* Manage > Store > Accidents */
.state('manage.store.accidents', {
url:'/manage/store/:id/accidents',
templateUrl:'manage_store_accidents.html'
})
/* Manage > Employees */
.state('manage.employees', {
url:'/manage/employees',
templateUrl: 'manage_employees.html'
})
/* Manage > Groups */
.state('manage.groups', {
url:'/manage/groups',
templateUrl: 'manage_groups.html'
})
/* Assess */
.state('assess', {
url:'/assess',
templateUrl:'assess.html'
})
/* Analyze */
.state('analyze', {
url:'/analyze',
templateUrl:'analyze.html'
});
})
.run(function($rootScope,$state,$stateParams){
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
});
angular.module('QaOmatic').controller('ApplicationController',['$scope',function($scope){
// ?
}]);
/* ? * /
/**
* State-based routing for AngularJS
* @version v0.0.2-dev-2013-05-25
* @link http://angular-ui.github.com/
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
(function(t,r,e){"use strict";function n(t,r){return g(new(g(function(){},{prototype:t})),r)}function a(t){return d(arguments,function(r){r!==t&&d(r,function(r,e){t.hasOwnProperty(e)||(t[e]=r)})}),t}function i(t,r,e){this.fromConfig=function(t,r,e){return h(t.template)?this.fromString(t.template,r):h(t.templateUrl)?this.fromUrl(t.templateUrl,r):h(t.templateProvider)?this.fromProvider(t.templateProvider,r,e):null},this.fromString=function(t,r){return m(t)?t(r):t},this.fromUrl=function(e,n){return m(e)&&(e=e(n)),null==e?null:t.get(e,{cache:r}).then(function(t){return t.data})},this.fromProvider=function(t,r,n){return e.invoke(t,null,n||{params:r})}}function o(t){function r(r){if(!/^\w+$/.test(r))throw Error("Invalid parameter name '"+r+"' in pattern '"+t+"'");if(i[r])throw Error("Duplicate parameter name '"+r+"' in pattern '"+t+"'");i[r]=!0,l.push(r)}function e(t){return t.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&")}var n,a=/([:*])(\w+)|\{(\w+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,i={},o="^",s=0,u=this.segments=[],l=this.params=[];this.source=t;for(var c,f,h;(n=a.exec(t))&&(c=n[2]||n[3],f=n[4]||("*"==n[1]?".*":"[^/]*"),h=t.substring(s,n.index),!(h.indexOf("?")>=0));)o+=e(h)+"("+f+")",r(c),u.push(h),s=a.lastIndex;h=t.substring(s);var m=h.indexOf("?");if(m>=0){var p=this.sourceSearch=h.substring(m);h=h.substring(0,m),this.sourcePath=t.substring(0,s+m),d(p.substring(1).split(/[&?]/),r)}else this.sourcePath=t,this.sourceSearch="";o+=e(h)+"$",u.push(h),this.regexp=RegExp(o),this.prefix=u[0]}function s(){this.compile=function(t){return new o(t)},this.isMatcher=function(t){return t instanceof o},this.$get=function(){return this}}function u(t){function r(t){var r=/^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(t.source);return null!=r?r[1].replace(/\\(.)/g,"$1"):""}function e(t,r){return t.replace(/\$(\$|\d{1,2})/,function(t,e){return r["$"===e?0:Number(e)]})}function n(t,r,e){if(!e)return!1;var n=t.invoke(r,r,{$match:e});return h(n)?n:!0}var a=[],i=null;this.rule=function(t){if(!m(t))throw Error("'rule' must be a function");return a.push(t),this},this.otherwise=function(t){if(p(t)){var r=t;t=function(){return r}}else if(!m(t))throw Error("'rule' must be a function");return i=t,this},this.when=function(a,i){var o,s;if(p(a)&&(a=t.compile(a)),t.isMatcher(a)){if(p(i))s=t.compile(i),i=["$match",function(t){return s.format(t)}];else if(!m(i)&&!v(i))throw Error("invalid 'handler' in when()");o=function(t,r){return n(t,i,a.exec(r.path(),r.search()))},o.prefix=p(a.prefix)?a.prefix:""}else{if(!(a instanceof RegExp))throw Error("invalid 'what' in when()");if(p(i))s=i,i=["$match",function(t){return e(s,t)}];else if(!m(i)&&!v(i))throw Error("invalid 'handler' in when()");if(a.global||a.sticky)throw Error("when() RegExp must not be global or sticky");o=function(t,r){return n(t,i,a.exec(r.path()))},o.prefix=r(a)}return this.rule(o)},this.$get=["$location","$rootScope","$injector",function(t,r,e){function n(){var r,n,i=a.length;for(r=0;i>r;r++)if(n=a[r](e,t)){p(n)&&t.replace().url(n);break}}return i&&a.push(i),r.$on("$locationChangeSuccess",n),{}}]}function l(t,r){function e(t){var r;if(p(t)){if(r=c[t],!r)throw Error("No such state '"+t+"'")}else if(r=c[t.name],!r||r!==t&&r.self!==t)throw Error("Invalid or unregistered state");return r}function i(a){a=n(a,{self:a,toString:function(){return this.name}});var i=a.name;if(!p(i)||i.indexOf("@")>=0)throw Error("State must have a valid name");if(c[i])throw Error("State '"+i+"'' is already defined");var o=u;if(h(a.parent))null!=a.parent&&(o=e(a.parent));else{var s=/^(.+)\.[^.]+$/.exec(i);null!=s&&(o=e(s[1]))}a.parent=o;var f=a.url;if(p(f))f=a.url="^"==f.charAt(0)?r.compile(f.substring(1)):(o.navigable||u).url.concat(f);else if($(f)&&m(f.exec)&&m(f.format)&&m(f.concat));else if(null!=f)throw Error("Invalid url '"+f+"' in state '"+a+"'");a.navigable=f?a:o?o.navigable:null;var w=a.params;if(w){if(!v(w))throw Error("Invalid params in state '"+a+"'");if(f)throw Error("Both params and url specicified in state '"+a+"'")}else w=a.params=f?f.parameters():a.parent.params;var b={};if(d(w,function(t){b[t]=!0}),o){d(o.params,function(t){if(!b[t])throw Error("Missing required parameter '"+t+"' in state '"+i+"'");b[t]=!1});var E=a.ownParams=[];d(b,function(t,r){t&&E.push(r)})}else a.ownParams=w;var x={};d(h(a.views)?a.views:{"":a},function(t,r){0>r.indexOf("@")&&(r=r+"@"+a.parent.name),x[r]=t}),a.views=x,a.path=o?o.path.concat(a):[];var P=a.includes=o?g({},o.includes):{};return P[i]=!0,a.resolve||(a.resolve={}),!a["abstract"]&&f&&t.when(f,["$match",function(t){l.transitionTo(a,t,!1)}]),c[i]=a,a}function o(t,r){return $(t)?r=t:r.name=t,i(r),this}function s(t,r,i,o,s,c){function f(t,e,n,s,u){function l(e,n){d(e,function(e,a){f.push(r.when(p(e)?o.get(e):o.invoke(e,t.self,h)).then(function(t){n[a]=t}))})}var c,f=[s];n?c=e:(c={},d(t.params,function(t){c[t]=e[t]}));var h={$stateParams:c},m=u.globals={$stateParams:c};return l(t.resolve,m),m.$$state=t,d(t.views,function(e,n){var a=u[n]={$$controller:e.controller};f.push(r.when(i.fromConfig(e,c,h)||"").then(function(t){a.$template=t})),e.resolve!==t.resolve&&l(e.resolve,a)}),r.all(f).then(function(r){return a(u.globals,r[0].globals),d(t.views,function(t,r){a(u[r],u.globals)}),u})}function m(t,r){var e={};return d(t,function(t){var n=r[t];e[t]=null!=n?n+"":null}),e}function $(t,r,e){for(var n=0;e.length>n;n++){var a=e[n];if(t[a]!=r[a])return!1}return!0}var v=r.reject(Error("transition superseded")),g=r.reject(Error("transition prevented"));return l={params:{},current:u.self,$current:u,transition:null},l.transitionTo=function(a,i,p){if(h(p)||(p=!0),a=e(a),a["abstract"])throw Error("Cannot transition to abstract state '"+a+"'");var d,b,E=a.path,x=l.$current,P=l.params,S=x.path,C=u.locals,y=[];for(d=0,b=E[d];b&&b===S[d]&&$(i,P,b.ownParams);d++,b=E[d])C=y[d]=b.locals;if(a===x&&C===x.locals)return l.transition=null,r.when(l.current);if(i=m(a.params,i||{}),t.$broadcast("$stateChangeStart",a.self,i,x.self,P).defaultPrevented)return g;for(var j=r.when(C),R=d;E.length>R;R++,b=E[R])C=y[R]=n(C),j=f(b,i,b===a,j,C);var k=l.transition=j.then(function(){var r,e,n;if(l.transition!==k)return v;for(r=S.length-1;r>=d;r--)n=S[r],n.self.onExit&&o.invoke(n.self.onExit,n.self,n.locals.globals),n.locals=null;for(r=d;E.length>r;r++)e=E[r],e.locals=y[r],e.self.onEnter&&o.invoke(e.self.onEnter,e.self,e.locals.globals);l.$current=a,l.current=a.self,l.params=i,w(l.params,s),l.transition=null;var u=a.navigable;return p&&u&&c.url(u.url.format(u.locals.globals.$stateParams)),t.$broadcast("$stateChangeSuccess",a.self,i,x.self,P),l.current},function(e){return l.transition!==k?v:(l.transition=null,t.$broadcast("$stateChangeError",a.self,i,x.self,P,e),r.reject(e))});return k},l.is=function(t){return l.$current===e(t)},l.includes=function(t){return l.$current.includes[e(t).name]},l.href=function(t,r){var n=e(t),a=n.navigable;if(!a)throw Error("State '"+n+"' is not navigable");return a.url.format(m(n.params,r||{}))},l}var u,l,c={};u=i({name:"",url:"^",views:null,"abstract":!0}),u.locals={globals:{$stateParams:{}}},u.navigable=null,this.state=o,this.$get=s,s.$inject=["$rootScope","$q","$templateFactory","$injector","$stateParams","$location","$urlRouter"]}function c(t,e,n,a,i){var o;try{o=a.get("$animator")}catch(s){}var u={restrict:"ECA",terminal:!0,link:function(a,s,l){function c(o){var u=t.$current&&t.$current.locals[p];if(u!==m)if(f&&(v&&o?v.leave(s.contents(),s):s.html(""),f.$destroy(),f=null),u){m=u,g.state=u.$$state;var l;v&&o?(l=r.element("<div></div>").html(u.$template).contents(),v.enter(l,s)):(s.html(u.$template),l=s.contents());var c=e(l);if(f=a.$new(),u.$$controller){u.$scope=f;var h=n(u.$$controller,u);s.children().data("$ngControllerController",h)}c(f),f.$emit("$viewContentLoaded"),f.$eval($),i()}else m=null,g.state=null}var f,m,p=l[u.name]||l.name||"",$=l.onload||"",v=h(o)&&o(a,l),d=s.parent().inheritedData("$uiView");0>p.indexOf("@")&&(p=p+"@"+(d?d.state.name:""));var g={name:p,state:null};s.data("$uiView",g),a.$on("$stateChangeSuccess",function(){c(!0)}),c(!1)}};return u}function f(t,r){function a(t){this.locals=t.locals.globals,this.params=this.locals.$stateParams}function i(){this.locals=null,this.params=null}function o(e,o){if(null!=o.redirectTo){var s,l=o.redirectTo;if(p(l))s=l;else{if(!m(l))throw Error("Invalid 'redirectTo' in when()");s=function(t,r){return l(t,r.path(),r.search())}}r.when(e,s)}else t.state(n(o,{parent:null,name:"route:"+encodeURIComponent(e),url:e,onEnter:a,onExit:i}));return u.push(o),this}function s(t,r,n){function a(t){return""!==t.name?t:e}var i={routes:u,params:n,current:e};return r.$on("$stateChangeStart",function(t,e,n,i){r.$broadcast("$routeChangeStart",a(e),a(i))}),r.$on("$stateChangeSuccess",function(t,e,n,o){i.current=a(e),r.$broadcast("$routeChangeSuccess",a(e),a(o)),w(n,i.params)}),r.$on("$stateChangeError",function(t,e,n,i,o,s){r.$broadcast("$routeChangeError",a(e),a(i),s)}),i}var u=[];a.$inject=["$$state"],this.when=o,this.$get=s,s.$inject=["$state","$rootScope","$routeParams"]}var h=r.isDefined,m=r.isFunction,p=r.isString,$=r.isObject,v=r.isArray,d=r.forEach,g=r.extend,w=r.copy;r.module("ui.util",["ng"]),r.module("ui.router",["ui.util"]),r.module("ui.state",["ui.router","ui.util"]),r.module("ui.compat",["ui.state"]),i.$inject=["$http","$templateCache","$injector"],r.module("ui.util").service("$templateFactory",i),o.prototype.concat=function(t){return new o(this.sourcePath+t+this.sourceSearch)},o.prototype.toString=function(){return this.source},o.prototype.exec=function(t,r){var e=this.regexp.exec(t);if(!e)return null;var n,a=this.params,i=a.length,o=this.segments.length-1,s={};for(n=0;o>n;n++)s[a[n]]=decodeURIComponent(e[n+1]);for(;i>n;n++)s[a[n]]=r[a[n]];return s},o.prototype.parameters=function(){return this.params},o.prototype.format=function(t){var r=this.segments,e=this.params;if(!t)return r.join("");var n,a,i,o=r.length-1,s=e.length,u=r[0];for(n=0;o>n;n++)i=t[e[n]],null!=i&&(u+=i),u+=r[n+1];for(;s>n;n++)i=t[e[n]],null!=i&&(u+=(a?"&":"?")+e[n]+"="+encodeURIComponent(i),a=!0);return u},r.module("ui.util").provider("$urlMatcherFactory",s),u.$inject=["$urlMatcherFactoryProvider"],r.module("ui.router").provider("$urlRouter",u),l.$inject=["$urlRouterProvider","$urlMatcherFactoryProvider"],r.module("ui.state").value("$stateParams",{}).provider("$state",l),c.$inject=["$state","$compile","$controller","$injector","$anchorScroll"],r.module("ui.state").directive("uiView",c),f.$inject=["$stateProvider","$urlRouterProvider"],r.module("ui.compat").provider("$route",f).directive("ngView",c)})(window,window.angular);
<h1>Home!</h1>
<p>Welcome to QA-o-matic! Click <strong>Manage</strong> above...</p>
<div class="row">
<div class="span3">
<ul class="nav nav-tabs nav-stacked">
<li ng-class="{active:$state.includes('manage.store') || $state.includes('manage.editStore') }">
<a href="#/manage/store/1234/complaints">Store</a></li>
<li ng-class="{active:$state.includes('manage.employees')}">
<a href="#/manage/employees">Employees</a></li>
<li ng-class="{active:$state.includes('manage.groups')}">
<a href="#/manage/groups">Groups</a></li>
</ul>
</div>
<div class="span9" ui-view>
<!-- Second Level -->
</div>
</div>
<h1>Manage Store</h1>
<table class="table">
<thead>
<tr><th>Store</th><th>City</th><th>State</th><th>Zip</th></tr>
</thead>
<tbody>
<tr><td>#1234</td><td>Whatever</td><td>AK</td><td>54321</td></tr>
</tbody>
</table>
<a href="#/manage/store/1234/edit" class="btn">
<i class="icon-edit"></i> Edit Store</a>
<hr>
<ul class="nav nav-tabs">
<li class="active" ng-class="{active:$state.includes('manage.store.complaints') || $state.includes('manage.store.addComplaint')}">
<a href="#/manage/store/1234/complaints">Complaints</a></li>
<li ng-class="{active:$state.includes('manage.store.accidents')}">
<a href="#/manage/store/1234/accidents">Accidents</a></li>
</ul>
<div ui-view>
<!-- Third Level -->
</div>
<h1>Assess</h1>
<p>Placeholder...</p>
<h1>Analyze</h1>
<p>Placeholder...</p>
<h1>Manage Employees</h1>
<p>Placeholder...</p>
<h1>Manage Groups</h1>
<p>Placeholder...</p>
<a href="#/manage/store/1234/addcomplaint" class="btn">
<i class="icon-plus"></i> Add Complaint</a>
<table class="table table-bordered table-striped" style="margin-top:20px">
<thead>
<tr>
<th>Fe</th>
<th>Fi</th>
<th>Fo</th>
<th>Fum</th>
</tr>
</thead>
<tbody>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
<tr><td>A</td><td>Row</td><td>Of</td><td>Data</td></tr>
</tbody>
</table>
<p>Store accients placeholder</p>
<h1>Edit Store</h1>
<form>
<label>Store</label>
<input type="text" value="1234">
<label>City</label>
<input type="text" value="Whatever">
<label>State</label>
<input type="text" value="AK">
<label>Zip</label>
<input type="text" value="54321">
<hr>
<input type="submit" value="Save" class="btn btn-primary">
<a href="#/manage/store/1234/complaints" class="btn">Cancel</a>
</form>
<form class="well">
<h3>Add Complaint</h3>
<label>Fe</label>
<input type="text">
<label>Fi</label>
<input type="text">
<label>Fo</label>
<input type="text">
<label>Fum</label>
<input type="text">
<hr>
<input type="submit" value="Save" class="btn btn-primary">
<a href="#/manage/store/1234/complaints" class="btn">Cancel</a>
</form>