Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

fix(tab): add support for tab deselect prevention #5723

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/tabs/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ AngularJS version of the tabs directive.

* `deselect()`
<small class="badge">$</small> -
An optional expression called when tab is deactivated. Supports $event in template for expression.
An optional expression called when tab is deactivated. Supports $event in template for expression. You may call `$event.preventDefault()` in this event handler to prevent a tab change from occurring.

* `disable`
<small class="badge">$</small>
Expand Down
3 changes: 3 additions & 0 deletions src/tabs/tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ angular.module('ui.bootstrap.tabs', [])
previousSelected.tab.onDeselect({
$event: evt
});
if (evt && evt.defaultPrevented) {
return;
}
previousSelected.tab.active = false;
}

Expand Down
22 changes: 20 additions & 2 deletions src/tabs/test/tabs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ describe('tabs', function() {
scope = $rootScope.$new();
scope.first = '1';
scope.second = '2';
scope.third = '3';
scope.active = 1;
scope.firstClass = 'first-class';
scope.secondClass = 'second-class-1 second-class-2';
scope.selectFirst = jasmine.createSpy();
scope.selectSecond = jasmine.createSpy();
scope.deselectFirst = jasmine.createSpy();
scope.deselectSecond = jasmine.createSpy();
scope.deselectThird = function($event) {
$event.preventDefault();
};
elm = $compile([
'<uib-tabset class="hello" data-pizza="pepperoni" active="active">',
' <uib-tab index="1" heading="First Tab {{first}}" classes="{{firstClass}}" select="selectFirst($event)" deselect="deselectFirst($event)">',
Expand All @@ -49,6 +53,10 @@ describe('tabs', function() {
' <uib-tab-heading><b>Second</b> Tab {{second}}</uib-tab-heading>',
' second content is {{second}}',
' </uib-tab>',
' <uib-tab index="3" classes="{{thirdClass}}" deselect="deselectThird($event)">',
' <uib-tab-heading><b>Second</b> Tab {{third}}</uib-tab-heading>',
' third content is {{third}}',
' </uib-tab>',
'</uib-tabset>'
].join('\n'))(scope);
scope.$apply();
Expand All @@ -65,15 +73,15 @@ describe('tabs', function() {

it('should create clickable titles', function() {
var t = titles();
expect(t.length).toBe(2);
expect(t.length).toBe(3);
expect(t.find('> a').eq(0).text()).toBe('First Tab 1');
//It should put the uib-tab-heading element into the 'a' title
expect(t.find('> a').eq(1).children().is('uib-tab-heading')).toBe(true);
expect(t.find('> a').eq(1).children().html()).toBe('<b>Second</b> Tab 2');
});

it('should bind tabs content and set first tab active', function() {
expectContents(['first content is 1', 'second content is 2']);
expectContents(['first content is 1', 'second content is 2', 'third content is 3']);
expect(titles().eq(0)).toHaveClass('active');
expect(titles().eq(1)).not.toHaveClass('active');
expect(scope.active).toBe(1);
Expand Down Expand Up @@ -117,6 +125,16 @@ describe('tabs', function() {
expect(scope.deselectFirst.calls.count()).toBe(2);
expect(scope.deselectFirst.calls.argsFor(1)[0].target).toBe(titles().eq(1).find('> a')[0]);
});

it('should prevent tab deselection when $event.preventDefault() is called', function() {
spyOn(scope, 'deselectThird');
titles().eq(2).find('> a').click();
expect(scope.active).toBe(3);
titles().eq(1).find('> a').click();
expect(scope.deselectThird).toHaveBeenCalled();
expect(scope.active).not.toBe(1);
expect(scope.active).toBe(2);
});
});

describe('basics with initial active tab', function() {
Expand Down