I have a site built with “Drupal 8” and “Bootstrap 3”. I created in the header, a menu collapse on the left and a menu collapse on the right.
How to close the first menu collapse when the second is open ?
And vice versa ?
Here are the two menus :
JavaScript
x
3
1
id="navbar-collapse-first"
2
id="navbar-collapse-second"
3
What should I add to my JS file.
Here is the contents of the file collapse.js :
JavaScript
1
226
226
1
/* ========================================================================
2
* Bootstrap: collapse.js v3.3.7
3
* http://getbootstrap.com/javascript/#collapse
4
* ========================================================================
5
* Copyright 2011-2016 Twitter, Inc.
6
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7
* ======================================================================== */
8
9
/* jshint latedef: false */
10
11
+function ($) {
12
'use strict';
13
14
// COLLAPSE PUBLIC CLASS DEFINITION
15
// ================================
16
17
var Collapse = function (element, options) {
18
this.$element = $(element)
19
this.options = $.extend({}, Collapse.DEFAULTS, options)
20
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
21
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
22
this.transitioning = null
23
24
if (this.options.parent) {
25
this.$parent = this.getParent()
26
} else {
27
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
28
}
29
30
if (this.options.toggle) this.toggle()
31
}
32
33
Collapse.VERSION = '3.3.7'
34
35
Collapse.TRANSITION_DURATION = 350
36
37
Collapse.DEFAULTS = {
38
toggle: true
39
}
40
41
Collapse.prototype.dimension = function () {
42
var hasWidth = this.$element.hasClass('width')
43
return hasWidth ? 'width' : 'height'
44
}
45
46
Collapse.prototype.show = function () {
47
if (this.transitioning || this.$element.hasClass('in')) return
48
49
var activesData
50
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
51
52
if (actives && actives.length) {
53
activesData = actives.data('bs.collapse')
54
if (activesData && activesData.transitioning) return
55
}
56
57
var startEvent = $.Event('show.bs.collapse')
58
this.$element.trigger(startEvent)
59
if (startEvent.isDefaultPrevented()) return
60
61
if (actives && actives.length) {
62
Plugin.call(actives, 'hide')
63
activesData || actives.data('bs.collapse', null)
64
}
65
66
var dimension = this.dimension()
67
68
this.$element
69
.removeClass('collapse')
70
.addClass('collapsing')[dimension](0)
71
.attr('aria-expanded', true)
72
73
this.$trigger
74
.removeClass('collapsed')
75
.attr('aria-expanded', true)
76
77
this.transitioning = 1
78
79
var complete = function () {
80
this.$element
81
.removeClass('collapsing')
82
.addClass('collapse in')[dimension]('')
83
this.transitioning = 0
84
this.$element
85
.trigger('shown.bs.collapse')
86
}
87
88
if (!$.support.transition) return complete.call(this)
89
90
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
91
92
this.$element
93
.one('bsTransitionEnd', $.proxy(complete, this))
94
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
95
}
96
97
Collapse.prototype.hide = function () {
98
if (this.transitioning || !this.$element.hasClass('in')) return
99
100
var startEvent = $.Event('hide.bs.collapse')
101
this.$element.trigger(startEvent)
102
if (startEvent.isDefaultPrevented()) return
103
104
var dimension = this.dimension()
105
106
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
107
108
this.$element
109
.addClass('collapsing')
110
.removeClass('collapse in')
111
.attr('aria-expanded', false)
112
113
this.$trigger
114
.addClass('collapsed')
115
.attr('aria-expanded', false)
116
117
this.transitioning = 1
118
119
var complete = function () {
120
this.transitioning = 0
121
this.$element
122
.removeClass('collapsing')
123
.addClass('collapse')
124
.trigger('hidden.bs.collapse')
125
}
126
127
if (!$.support.transition) return complete.call(this)
128
129
this.$element
130
[dimension](0)
131
.one('bsTransitionEnd', $.proxy(complete, this))
132
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
133
}
134
135
Collapse.prototype.toggle = function () {
136
this[this.$element.hasClass('in') ? 'hide' : 'show']()
137
}
138
139
Collapse.prototype.getParent = function () {
140
return $(this.options.parent)
141
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
142
.each($.proxy(function (i, element) {
143
var $element = $(element)
144
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
145
}, this))
146
.end()
147
}
148
149
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
150
var isOpen = $element.hasClass('in')
151
152
$element.attr('aria-expanded', isOpen)
153
$trigger
154
.toggleClass('collapsed', !isOpen)
155
.attr('aria-expanded', isOpen)
156
}
157
158
function getTargetFromTrigger($trigger) {
159
var href
160
var target = $trigger.attr('data-target')
161
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^s]+$)/, '') // strip for ie7
162
163
return $(target)
164
}
165
166
167
// COLLAPSE PLUGIN DEFINITION
168
// ==========================
169
170
function Plugin(option) {
171
return this.each(function () {
172
var $this = $(this)
173
var data = $this.data('bs.collapse')
174
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
175
176
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
177
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
178
if (typeof option == 'string') data[option]()
179
})
180
}
181
182
var old = $.fn.collapse
183
184
$.fn.collapse = Plugin
185
$.fn.collapse.Constructor = Collapse
186
187
188
// COLLAPSE NO CONFLICT
189
// ====================
190
191
$.fn.collapse.noConflict = function () {
192
$.fn.collapse = old
193
return this
194
}
195
196
197
// COLLAPSE DATA-API
198
// =================
199
200
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
201
var $this = $(this)
202
203
if (!$this.attr('data-target')) e.preventDefault()
204
205
var $target = getTargetFromTrigger($this)
206
var data = $target.data('bs.collapse')
207
var option = data ? 'toggle' : $this.data()
208
209
Plugin.call($target, option)
210
})
211
212
$('#navbar-collapse-first').on('show.bs.collapse', function () {
213
$('body').addClass('overlay-is-navbar-collapse');
214
});
215
$('#navbar-collapse-first').on('hide.bs.collapse', function () {
216
$('body').removeClass('overlay-is-navbar-collapse');
217
});
218
$('#navbar-collapse-second').on('show.bs.collapse', function () {
219
$('body').addClass('overlay-is-navbar-collapse');
220
});
221
$('#navbar-collapse-second').on('hide.bs.collapse', function () {
222
$('body').removeClass('overlay-is-navbar-collapse');
223
});
224
225
}(jQuery);
226
Advertisement
Answer
Following the bootstrap doc, I think you could test something like this :
JavaScript
1
8
1
$('#navbar-collapse-first').on('show.bs.collapse', function () {
2
$('#navbar-collapse-second').collapse('hide');
3
})
4
5
$('#navbar-collapse-second').on('show.bs.collapse', function () {
6
$('#navbar-collapse-first').collapse('hide');
7
})
8