Skip to content

Commit

Permalink
Merge pull request #21 from corinna000/master
Browse files Browse the repository at this point in the history
Addresses issue #19
  • Loading branch information
Mark Lagendijk committed Mar 30, 2015
2 parents e564b05 + a0b90ee commit 86be6e4
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 11 deletions.
43 changes: 41 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,13 @@ angular.module('myApp', [ 'ui.router', 'ui.router.stateHelper' ])
```

## Options

* keepOriginalNames (default _false_)
* siblingTraversal (default _false_)

### Dot notation name conversion
By default, all state names are converted to use ui-router's dot notation (e.g. `parentStateName.childStateName`).
This can be disabled by calling `.state()` with an optional second parameter of `true`.
This can be disabled by calling `.state()` with options `options.keepOriginalNames = true`.
For example:

``` javascript
Expand All @@ -63,9 +67,44 @@ angular.module('myApp', ['ui.router', 'ui.router.stateHelper'])
templateUrl: 'contacts.html'
}
]
}, true);
}, { keepOriginalNames: true });
});
```

### Sibling Traversal
Child states may optionally receive a reference to the name of the previous state (if available) and the next state (if available) in order to facilitate sequential state traversal as in the case of building wizards or multi-part forms. Enable this by setting `options.siblingTraversal = true`.

Example:
``` javascript

angular.module('myApp', ['ui.router', 'ui.router.stateHelper'])
.config(function(stateHelperProvider){
stateHelperProvider.state({
name: 'resume',
children: [
{
name: 'contactInfo',
},
{
name: 'experience',
},
{
name: 'education',
}
]
}, { siblingTraversal: true });
});

console.log($state.get('resume.contactInfo').previousSibling) // undefined
console.log($state.get('resume.contactInfo').nextSibling) // 'resume.experience'

console.log($state.get('resume.experience').previousSibling) // 'resume.contactInfo'
console.log($state.get('resume.experience').nextSibling) // 'resume.education'

console.log($state.get('resume.education').previousSibling) // 'resume.experience'
console.log($state.get('resume.education').nextSibling) // undefined
```


## Name change
Before 1.2.0 `.setNestedState` was used instead of `.state`. In 1.2.0 `setNestedState` was deprecated in favour of `.state`, and chaining was added. This makes it easier to switch between `$stateProvider` and `stateHelperProvider`.
45 changes: 40 additions & 5 deletions statehelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,43 @@ angular.module('ui.router.stateHelper', [ 'ui.router' ])
*
* @param {Object} state - A regular ui.router state object.
* @param {Array} [state.children] - An optional array of child states.
* @param {Boolean} keepOriginalNames - An optional flag that prevents conversion of names to dot notation if true.
* @deprecated {Boolean} keepOriginalNames - An optional flag that prevents conversion
* of names to dot notation if true. (use options.keepOriginalNames instead)
* @param {Object} [options] - An optional options object.
* @param {Boolean} [options.keepOriginalNames=false] An optional flag that
* prevents conversion of names to dot notation if true.
* @param {Boolean} [options.siblingTraversal=false] An optional flag that
* adds `nextSibling` and `previousSibling` properties when enabled
*/
this.state = function(state, keepOriginalNames){
if(!keepOriginalNames){
this.state = function(state){
var args = Array.prototype.slice.apply(arguments);
var options = {
keepOriginalNames: false,
siblingTraversal: false
};

if (typeof args[1] === 'boolean') {
options.keepOriginalNames = args[1];
}
else if (typeof args[1] === 'object') {
angular.extend(options, args[1]);
}

if (!options.keepOriginalNames) {
fixStateName(state);
}

$stateProvider.state(state);

if(state.children && state.children.length){
state.children.forEach(function(childState){
childState.parent = state;
self.state(childState, keepOriginalNames);
self.state(childState, options);
});

if (options.siblingTraversal) {
addSiblings(state);
}
}

return self;
Expand All @@ -48,4 +72,15 @@ angular.module('ui.router.stateHelper', [ 'ui.router' ])
state.name = (angular.isObject(state.parent) ? state.parent.name : state.parent) + '.' + state.name;
}
}
});

function addSiblings(state) {
state.children.forEach(function (childState, idx, array) {
if (array[idx + 1]) {
childState.nextSibling = array[idx + 1].name;
}
if (array[idx - 1]) {
childState.previousSibling = array[idx - 1].name;
}
});
}
});
2 changes: 1 addition & 1 deletion statehelper.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 29 additions & 3 deletions test/statehelperSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
describe('ui-router.stateHelper', function(){
var stateHelperProvider, $stateProvider, rootState, expectedState;

var $injector;

var stateHelperProviderState;

beforeEach(module('ui.router.stateHelper', function(_stateHelperProvider_, _$stateProvider_){
stateHelperProvider = _stateHelperProvider_;
$stateProvider = _$stateProvider_;
}));

beforeEach(inject(function(){
beforeEach(inject(function(_$injector_){
$injector = _$injector_;

rootState = {
name: 'root',
children: [
Expand Down Expand Up @@ -38,10 +42,12 @@ describe('ui-router.stateHelper', function(){
children: [
{
name: 'root.login',
// nextSibling: 'root.backup',
templateUrl: '/partials/views/#.html'
},
{
name: 'root.backup',
// previousSibling: 'root.login',
children: [
{
name: 'root.backup.dashboard'
Expand All @@ -51,7 +57,7 @@ describe('ui-router.stateHelper', function(){
]
};

stateHelperProviderState = stateHelperProvider.state(rootState);
stateHelperProviderState = stateHelperProvider.state(rootState, { siblingTraversal: false});
}));

it('should set each state', function(){
Expand Down Expand Up @@ -83,10 +89,12 @@ describe('ui-router.stateHelper', function(){
children: [
{
name: 'login',
// nextSibling: 'backup',
templateUrl: '/partials/views/#.html'
},
{
name: 'backup',
// previousSibling: 'login',
children: [
{
name: 'dashboard'
Expand All @@ -96,7 +104,7 @@ describe('ui-router.stateHelper', function(){
]
};

stateHelperProvider.state(rootState, true);
stateHelperProvider.state(rootState, { keepOriginalNames: true });
}));

it('should not convert names to dot notation, set parent references', function(){
Expand All @@ -118,6 +126,24 @@ describe('ui-router.stateHelper', function(){
expect($stateProvider.state.calls.count()).toBe(4);
});
});

describe('children have references to siblings', function (){
beforeEach(function () {
stateHelperProvider.state(rootState, { siblingTraversal: true });
});

it('should see the next sibling', function (){
var $state = $injector.get('$state');
expect($state.get('root.login').nextSibling).toBeDefined();
expect($state.get('root.login').nextSibling).toBe('root.backup');
});

it('should see the previous sibling', function (){
var $state = $injector.get('$state');
expect($state.get('root.backup').previousSibling).toBeDefined();
expect($state.get('root.backup').previousSibling).toBe('root.login');
});
});
});


Expand Down

0 comments on commit 86be6e4

Please # to comment.