mirror of
https://github.com/twbs/bootstrap.git
synced 2024-12-02 14:24:19 +01:00
Merge pull request #14686 from twbs/collapsed-class-manual-invocation
Handle `collapsed` class on triggers even when manually invoked
This commit is contained in:
commit
36e3d07c12
@ -16,9 +16,15 @@
|
|||||||
var Collapse = function (element, options) {
|
var Collapse = function (element, options) {
|
||||||
this.$element = $(element)
|
this.$element = $(element)
|
||||||
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
||||||
|
this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
|
||||||
this.transitioning = null
|
this.transitioning = null
|
||||||
|
|
||||||
if (this.options.parent) this.$parent = $(this.options.parent)
|
if (this.options.parent) {
|
||||||
|
this.$parent = this.getParent()
|
||||||
|
} else {
|
||||||
|
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
||||||
|
}
|
||||||
|
|
||||||
if (this.options.toggle) this.toggle()
|
if (this.options.toggle) this.toggle()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +33,8 @@
|
|||||||
Collapse.TRANSITION_DURATION = 350
|
Collapse.TRANSITION_DURATION = 350
|
||||||
|
|
||||||
Collapse.DEFAULTS = {
|
Collapse.DEFAULTS = {
|
||||||
toggle: true
|
toggle: true,
|
||||||
|
trigger: '[data-toggle="collapse"]'
|
||||||
}
|
}
|
||||||
|
|
||||||
Collapse.prototype.dimension = function () {
|
Collapse.prototype.dimension = function () {
|
||||||
@ -62,6 +69,10 @@
|
|||||||
.addClass('collapsing')[dimension](0)
|
.addClass('collapsing')[dimension](0)
|
||||||
.attr('aria-expanded', true)
|
.attr('aria-expanded', true)
|
||||||
|
|
||||||
|
this.$trigger
|
||||||
|
.removeClass('collapsed')
|
||||||
|
.attr('aria-expanded', true)
|
||||||
|
|
||||||
this.transitioning = 1
|
this.transitioning = 1
|
||||||
|
|
||||||
var complete = function () {
|
var complete = function () {
|
||||||
@ -98,6 +109,10 @@
|
|||||||
.removeClass('collapse in')
|
.removeClass('collapse in')
|
||||||
.attr('aria-expanded', false)
|
.attr('aria-expanded', false)
|
||||||
|
|
||||||
|
this.$trigger
|
||||||
|
.addClass('collapsed')
|
||||||
|
.attr('aria-expanded', false)
|
||||||
|
|
||||||
this.transitioning = 1
|
this.transitioning = 1
|
||||||
|
|
||||||
var complete = function () {
|
var complete = function () {
|
||||||
@ -120,6 +135,33 @@
|
|||||||
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.getParent = function () {
|
||||||
|
return $(this.options.parent)
|
||||||
|
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
|
||||||
|
.each($.proxy(function (i, element) {
|
||||||
|
var $element = $(element)
|
||||||
|
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
|
||||||
|
}, this))
|
||||||
|
.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
|
||||||
|
var isOpen = $element.hasClass('in')
|
||||||
|
|
||||||
|
$element.attr('aria-expanded', isOpen)
|
||||||
|
$trigger
|
||||||
|
.toggleClass('collapsed', !isOpen)
|
||||||
|
.attr('aria-expanded', isOpen)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTargetFromTrigger($trigger) {
|
||||||
|
var href
|
||||||
|
var target = $trigger.attr('data-target')
|
||||||
|
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
||||||
|
|
||||||
|
return $(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// COLLAPSE PLUGIN DEFINITION
|
// COLLAPSE PLUGIN DEFINITION
|
||||||
// ==========================
|
// ==========================
|
||||||
@ -155,22 +197,13 @@
|
|||||||
// =================
|
// =================
|
||||||
|
|
||||||
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
||||||
var href
|
|
||||||
var $this = $(this)
|
var $this = $(this)
|
||||||
var target = $this.attr('data-target')
|
|
||||||
|| e.preventDefault()
|
|
||||||
|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
|
||||||
var $target = $(target)
|
|
||||||
var data = $target.data('bs.collapse')
|
|
||||||
var option = data ? 'toggle' : $this.data()
|
|
||||||
var parent = $this.attr('data-parent')
|
|
||||||
var $parent = parent && $(parent)
|
|
||||||
|
|
||||||
if (!data || !data.transitioning) {
|
if (!$this.attr('data-target')) e.preventDefault()
|
||||||
if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed').attr('aria-expanded', false)
|
|
||||||
var isCollapsed = $target.hasClass('in')
|
var $target = getTargetFromTrigger($this)
|
||||||
$this.toggleClass('collapsed', isCollapsed).attr('aria-expanded', !isCollapsed)
|
var data = $target.data('bs.collapse')
|
||||||
}
|
var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
|
||||||
|
|
||||||
Plugin.call($target, option)
|
Plugin.call($target, option)
|
||||||
})
|
})
|
||||||
|
@ -79,7 +79,7 @@ $(function () {
|
|||||||
|
|
||||||
$('<div id="test1"/>')
|
$('<div id="test1"/>')
|
||||||
.appendTo('#qunit-fixture')
|
.appendTo('#qunit-fixture')
|
||||||
.on('show.bs.collapse', function () {
|
.on('shown.bs.collapse', function () {
|
||||||
ok(!$target.hasClass('collapsed'))
|
ok(!$target.hasClass('collapsed'))
|
||||||
start()
|
start()
|
||||||
})
|
})
|
||||||
@ -94,7 +94,7 @@ $(function () {
|
|||||||
|
|
||||||
$('<div id="test1" class="in"/>')
|
$('<div id="test1" class="in"/>')
|
||||||
.appendTo('#qunit-fixture')
|
.appendTo('#qunit-fixture')
|
||||||
.on('hide.bs.collapse', function () {
|
.on('hidden.bs.collapse', function () {
|
||||||
ok($target.hasClass('collapsed'))
|
ok($target.hasClass('collapsed'))
|
||||||
start()
|
start()
|
||||||
})
|
})
|
||||||
@ -137,12 +137,12 @@ $(function () {
|
|||||||
test('should remove "collapsed" class from active accordion target', function () {
|
test('should remove "collapsed" class from active accordion target', function () {
|
||||||
stop()
|
stop()
|
||||||
|
|
||||||
var accordionHTML = '<div id="accordion">'
|
var accordionHTML = '<div class="panel-group" id="accordion">'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.accordion-group')
|
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
|
||||||
|
|
||||||
var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
|
var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
|
||||||
|
|
||||||
@ -156,7 +156,7 @@ $(function () {
|
|||||||
|
|
||||||
$('<div id="body3"/>')
|
$('<div id="body3"/>')
|
||||||
.appendTo($groups.eq(2))
|
.appendTo($groups.eq(2))
|
||||||
.on('show.bs.collapse', function () {
|
.on('shown.bs.collapse', function () {
|
||||||
ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
|
ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
|
||||||
ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
|
ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
|
||||||
ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
|
ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
|
||||||
@ -170,12 +170,12 @@ $(function () {
|
|||||||
test('should allow dots in data-parent', function () {
|
test('should allow dots in data-parent', function () {
|
||||||
stop()
|
stop()
|
||||||
|
|
||||||
var accordionHTML = '<div class="accordion">'
|
var accordionHTML = '<div class="panel-group accordion">'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.accordion-group')
|
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
|
||||||
|
|
||||||
var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent=".accordion"/>').appendTo($groups.eq(0))
|
var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent=".accordion"/>').appendTo($groups.eq(0))
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ $(function () {
|
|||||||
|
|
||||||
$('<div id="body3"/>')
|
$('<div id="body3"/>')
|
||||||
.appendTo($groups.eq(2))
|
.appendTo($groups.eq(2))
|
||||||
.on('show.bs.collapse', function () {
|
.on('shown.bs.collapse', function () {
|
||||||
ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
|
ok($target1.hasClass('collapsed'), 'inactive target 1 does have class "collapsed"')
|
||||||
ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
|
ok($target2.hasClass('collapsed'), 'inactive target 2 does have class "collapsed"')
|
||||||
ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
|
ok(!$target3.hasClass('collapsed'), 'active target 3 does not have class "collapsed"')
|
||||||
@ -207,7 +207,7 @@ $(function () {
|
|||||||
|
|
||||||
$('<div id="test1"/>')
|
$('<div id="test1"/>')
|
||||||
.appendTo('#qunit-fixture')
|
.appendTo('#qunit-fixture')
|
||||||
.on('show.bs.collapse', function () {
|
.on('shown.bs.collapse', function () {
|
||||||
equal($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
|
equal($target.attr('aria-expanded'), 'true', 'aria-expanded on target is "true"')
|
||||||
start()
|
start()
|
||||||
})
|
})
|
||||||
@ -222,7 +222,7 @@ $(function () {
|
|||||||
|
|
||||||
$('<div id="test1" class="in"/>')
|
$('<div id="test1" class="in"/>')
|
||||||
.appendTo('#qunit-fixture')
|
.appendTo('#qunit-fixture')
|
||||||
.on('hide.bs.collapse', function () {
|
.on('hidden.bs.collapse', function () {
|
||||||
equal($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
|
equal($target.attr('aria-expanded'), 'false', 'aria-expanded on target is "false"')
|
||||||
start()
|
start()
|
||||||
})
|
})
|
||||||
@ -233,12 +233,12 @@ $(function () {
|
|||||||
test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function () {
|
test('should change aria-expanded from active accordion target to "false" and set the newly active one to "true"', function () {
|
||||||
stop()
|
stop()
|
||||||
|
|
||||||
var accordionHTML = '<div id="accordion">'
|
var accordionHTML = '<div class="panel-group" id="accordion">'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '<div class="accordion-group"/>'
|
+ '<div class="panel"/>'
|
||||||
+ '</div>'
|
+ '</div>'
|
||||||
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.accordion-group')
|
var $groups = $(accordionHTML).appendTo('#qunit-fixture').find('.panel')
|
||||||
|
|
||||||
var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
|
var $target1 = $('<a data-toggle="collapse" href="#body1" data-parent="#accordion"/>').appendTo($groups.eq(0))
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ $(function () {
|
|||||||
|
|
||||||
$('<div id="body3" aria-expanded="false"/>')
|
$('<div id="body3" aria-expanded="false"/>')
|
||||||
.appendTo($groups.eq(2))
|
.appendTo($groups.eq(2))
|
||||||
.on('show.bs.collapse', function () {
|
.on('shown.bs.collapse', function () {
|
||||||
equal($target1.attr('aria-expanded'), 'false', 'inactive target 1 has aria-expanded="false"')
|
equal($target1.attr('aria-expanded'), 'false', 'inactive target 1 has aria-expanded="false"')
|
||||||
equal($target2.attr('aria-expanded'), 'false', 'inactive target 2 has aria-expanded="false"')
|
equal($target2.attr('aria-expanded'), 'false', 'inactive target 2 has aria-expanded="false"')
|
||||||
equal($target3.attr('aria-expanded'), 'true', 'active target 3 has aria-expanded="false"')
|
equal($target3.attr('aria-expanded'), 'true', 'active target 3 has aria-expanded="false"')
|
||||||
@ -298,4 +298,32 @@ $(function () {
|
|||||||
}, 1)
|
}, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should add "collapsed" class to target when collapse is hidden via manual invocation', function () {
|
||||||
|
stop()
|
||||||
|
|
||||||
|
var $target = $('<a data-toggle="collapse" href="#test1"/>').appendTo('#qunit-fixture')
|
||||||
|
|
||||||
|
$('<div id="test1" class="in"/>')
|
||||||
|
.appendTo('#qunit-fixture')
|
||||||
|
.on('hidden.bs.collapse', function () {
|
||||||
|
ok($target.hasClass('collapsed'))
|
||||||
|
start()
|
||||||
|
})
|
||||||
|
.bootstrapCollapse('hide')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should remove "collapsed" class from target when collapse is shown via manual invocation', function () {
|
||||||
|
stop()
|
||||||
|
|
||||||
|
var $target = $('<a data-toggle="collapse" class="collapsed" href="#test1"/>').appendTo('#qunit-fixture')
|
||||||
|
|
||||||
|
$('<div id="test1"/>')
|
||||||
|
.appendTo('#qunit-fixture')
|
||||||
|
.on('shown.bs.collapse', function () {
|
||||||
|
ok(!$target.hasClass('collapsed'))
|
||||||
|
start()
|
||||||
|
})
|
||||||
|
.bootstrapCollapse('show')
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user