diff --git a/src/tabs/docs/readme.md b/src/tabs/docs/readme.md
index 0bdbfeb9ed..d7681a95be 100644
--- a/src/tabs/docs/readme.md
+++ b/src/tabs/docs/readme.md
@@ -33,7 +33,7 @@ AngularJS version of the tabs directive.
* `deselect()`
$ -
- 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`
$
diff --git a/src/tabs/tabs.js b/src/tabs/tabs.js
index adf3c5c7a6..06cc9b6e43 100644
--- a/src/tabs/tabs.js
+++ b/src/tabs/tabs.js
@@ -13,6 +13,9 @@ angular.module('ui.bootstrap.tabs', [])
previousSelected.tab.onDeselect({
$event: evt
});
+ if (evt && evt.defaultPrevented) {
+ return;
+ }
previousSelected.tab.active = false;
}
diff --git a/src/tabs/test/tabs.spec.js b/src/tabs/test/tabs.spec.js
index f2e7642e11..9e89846bd6 100644
--- a/src/tabs/test/tabs.spec.js
+++ b/src/tabs/test/tabs.spec.js
@@ -33,6 +33,7 @@ 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';
@@ -40,6 +41,9 @@ describe('tabs', function() {
scope.selectSecond = jasmine.createSpy();
scope.deselectFirst = jasmine.createSpy();
scope.deselectSecond = jasmine.createSpy();
+ scope.deselectThird = function($event) {
+ $event.preventDefault();
+ };
elm = $compile([
'',
' ',
@@ -49,6 +53,10 @@ describe('tabs', function() {
' Second Tab {{second}}',
' second content is {{second}}',
' ',
+ ' ',
+ ' Second Tab {{third}}',
+ ' third content is {{third}}',
+ ' ',
''
].join('\n'))(scope);
scope.$apply();
@@ -65,7 +73,7 @@ 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);
@@ -73,7 +81,7 @@ describe('tabs', function() {
});
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);
@@ -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() {