diff --git a/docs/_includes/js/tabs.html b/docs/_includes/js/tabs.html
index 39c244e8e4..570e21e201 100644
--- a/docs/_includes/js/tabs.html
+++ b/docs/_includes/js/tabs.html
@@ -132,6 +132,14 @@ $('#myTab li:eq(2) a').tab('show') // Select third tab (0-indexed)
shown.bs.tab |
This event fires on tab show after a tab has been shown. Use event.target and event.relatedTarget to target the active tab and the previous active tab (if available) respectively. |
+
+ hide.bs.tab |
+ This event fires immediately when a new tab is to be shown and before the show.bs.tab event. Use event.relatedTarget to target the new tab. |
+
+
+ hidden.bs.tab |
+ This event fires after a new tab is shown and before the shown.bs.tab event. Use event.relatedTarget to target the new tab. |
+
diff --git a/js/tab.js b/js/tab.js
index d7023c8170..c597d7ab6b 100644
--- a/js/tab.js
+++ b/js/tab.js
@@ -33,22 +33,30 @@
if ($this.parent('li').hasClass('active')) return
- var previous = $ul.find('.active:last a')[0]
- var e = $.Event('show.bs.tab', {
- relatedTarget: previous
+ var $previous = $ul.find('.active:last a')
+ var hideEvent = $.Event('hide.bs.tab', {
+ relatedTarget: $this[0]
+ })
+ var showEvent = $.Event('show.bs.tab', {
+ relatedTarget: $previous[0]
})
- $this.trigger(e)
+ $previous.trigger(hideEvent)
+ $this.trigger(showEvent)
- if (e.isDefaultPrevented()) return
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
var $target = $(selector)
this.activate($this.closest('li'), $ul)
this.activate($target, $target.parent(), function () {
+ $previous.trigger({
+ type: 'hidden.bs.tab',
+ relatedTarget: $this[0]
+ })
$this.trigger({
type: 'shown.bs.tab',
- relatedTarget: previous
+ relatedTarget: $previous[0]
})
})
}
diff --git a/js/tests/unit/tab.js b/js/tests/unit/tab.js
index 8e50614ecc..6fbf36c50b 100644
--- a/js/tests/unit/tab.js
+++ b/js/tests/unit/tab.js
@@ -101,4 +101,81 @@ $(function () {
.bootstrapTab('show')
})
+ test('should fire hide and hidden events', function () {
+ stop()
+
+ var tabsHTML = ''
+
+ $(tabsHTML)
+ .find('li:first a')
+ .on('hide.bs.tab', function () {
+ ok(true, 'hide event fired')
+ })
+ .bootstrapTab('show')
+ .end()
+ .find('li:last a')
+ .bootstrapTab('show')
+
+ $(tabsHTML)
+ .find('li:first a')
+ .on('hidden.bs.tab', function () {
+ ok(true, 'hidden event fired')
+ start()
+ })
+ .bootstrapTab('show')
+ .end()
+ .find('li:last a')
+ .bootstrapTab('show')
+ })
+
+ test('should not fire hidden when hide is prevented', function () {
+ stop()
+
+ var tabsHTML = ''
+
+ $(tabsHTML)
+ .find('li:first a')
+ .on('hide.bs.tab', function (e) {
+ e.preventDefault()
+ ok(true, 'hide event fired')
+ start()
+ })
+ .on('hidden.bs.tab', function () {
+ ok(false, 'hidden event fired')
+ })
+ .bootstrapTab('show')
+ .end()
+ .find('li:last a')
+ .bootstrapTab('show')
+ })
+
+ test('hide and hidden events contain correct relatedTarget', function () {
+ stop()
+
+ var tabsHTML = ''
+
+ $(tabsHTML)
+ .find('li:first a')
+ .on('hide.bs.tab', function (e) {
+ equal(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
+ })
+ .on('hidden.bs.tab', function (e) {
+ equal(e.relatedTarget.hash, '#profile', 'references correct element as relatedTarget')
+ start()
+ })
+ .bootstrapTab('show')
+ .end()
+ .find('li:last a')
+ .bootstrapTab('show')
+ })
+
})