Modals
Modals are streamlined, but flexible dialog prompts powered by JavaScript and CSS. They support a
number of use cases from user notification to completely custom content and feature a handful of
helpful sub-components, sizes, variants, accessibility, and more.
<div>
<b-button v-b-modal.modal-1>Launch demo modal</b-button>
<b-modal id="modal-1" title="BootstrapVue">
<p class="my-4">Hello from modal!</p>
</b-modal>
</div>
Overview
<b-modal>
, by default, has an OK and Cancel buttons in the footer. These buttons can be
customized by setting various props on the component. You can customize the size of the buttons,
disable buttons, hide the Cancel button (i.e. OK Only), choose a variant (e.g. danger
for a
red OK button) using the ok-variant
and cancel-variant
props, and provide custom button content
using the ok-title
and cancel-title
props, or using the named slots modal-ok
and
modal-cancel
.
<b-modal>
supports close on ESC (enabled by default), close on backdrop click (enabled by
default), and the X
close button in the header (enabled by default). These features may be
disabled by setting the the props no-close-on-esc
, no-close-on-backdrop
, and hide-header-close
respectively.
You can override the modal title via the named slot modal-title
, override the header completely
via the modal-header
slot, and override the footer completely via the modal-footer
slot.
Note: when using the modal-footer
slot, the default OK and Cancel buttons will not be
present. Also, if you use the modal-header
slot, the default header X
close button will not be
present, nor can you use the modal-title
slot.
CHANGED in 2.0.0-rc.20 Modals will not render their
content in the document until they are shown (lazily rendered). Modals, when visible, are rendered
appended to the <body>
element. The placement of the <b-modal>
component will not affect
layout, as it always renders as a placeholder comment node (<!---->
). You can revert to the
behaviour of previous BootstrapVue versions via the use of the
static
prop.
Toggle modal visibility
There are several methods that you can employ to toggle the visibility of <b-modal>
.
Using v-b-modal
directive
Other elements can easily show modals using the v-b-modal
directive.
<div>
<b-button v-b-modal.my-modal>Show Modal</b-button>
<b-button v-b-modal="'my-modal'">Show Modal</b-button>
<b-modal id="my-modal">Hello From My Modal!</b-modal>
</div>
This approach will automatically return focus to the trigger element once the modal closes (similar
to default Bootstrap functionality). Other approaches for toggling modal visibility may require
additional code to implement this accessibility feature.
See the Accessibility section below for details.
Using this.$bvModal.show()
and this.$bvModal.hide()
instance methods
NEW in 2.0.0-rc.19
When BootstrapVue is installed as a plugin, or the ModalPlugin plugin is used,
BoostrapVue will inject a $bvModal
object on every Vue instance (components, apps).
this.$bvModal
exposes several methods, of which two are for showing and hiding modals:
Method |
Description |
this.$bvModal.show(id) |
Show the modal with the specified id |
this.$bvModal.hide(id) |
Hide the modal with the specified id |
Both methods return immediately after being called.
<div>
<b-button id="show-btn" @click="$bvModal.show('bv-modal-example')">Open Modal</b-button>
<b-modal id="bv-modal-example" hide-footer>
<template slot="modal-title">
Using <code>$bvModal</code> Methods
</template>
<div class="d-block text-center">
<h3>Hello From This Modal!</h3>
</div>
<b-button class="mt-3" block @click="$bvModal.hide('bv-modal-example')">Close Me</b-button>
</b-modal>
</div>
Using show()
, hide()
, and toggle()
component methods
You can access modal using ref
attribute and then call the show()
, hide()
or toggle()
methods.
<template>
<div>
<b-button id="show-btn" @click="showModal">Open Modal</b-button>
<b-button id="toggle-btn" @click="toggleModal">Toggle Modal</b-button>
<b-modal ref="my-modal" hide-footer title="Using Component Methods">
<div class="d-block text-center">
<h3>Hello From My Modal!</h3>
</div>
<b-button class="mt-3" variant="outline-danger" block @click="hideModal">Close Me</b-button>
<b-button class="mt-2" variant="outline-warning" block @click="toggleModal">Toggle Me</b-button>
</b-modal>
</div>
</template>
<script>
export default {
methods: {
showModal() {
this.$refs['my-modal'].show()
},
hideModal() {
this.$refs['my-modal'].hide()
},
toggleModal() {
this.$refs['my-modal'].toggle('#toggle-btn')
}
}
}
</script>
The hide()
method accepts an optional string trigger
argument for defining what triggered the
modal to close. See section Prevent Closing below for details.
Note: It is recommended to use the this.$bvModal.show()
and this.$bvModal.hide()
methods
(mentioned in the previous section) instead of using $ref
methods.
Using v-model
property
v-model
property is always automatically synced with <b-modal>
visible state and you can
show/hide using v-model
.
<template>
<div>
<b-button @click="modalShow = !modalShow">Open Modal</b-button>
<b-modal v-model="modalShow">Hello From Modal!</b-modal>
</div>
</template>
<script>
export default {
data() {
return {
modalShow: false
}
}
}
</script>
When using the v-model
prop, do not use the visible
prop at the same time.
Using scoped slot scope methods
Refer to the Custom rendering with slots section on using the
various methods passed to scoped slots for closing modals.
Emitting events on $root
You can emit bv::show::modal
, bv::hide::modal
, and bv::toggle::modal
events on $root
with
the first argument set to the modal's id. An optional second argument can specify the element to
return focus to once the modal is closed. The second argument can be a CSS selector, an element
reference, or a component reference (the root element of the component will be focused).
<div>
<b-button @click="showModal" ref="btnShow">Open Modal</b-button>
<b-button @click="toggleModal" ref="btnToggle">Toggle Modal</b-button>
<b-modal id="modal-1">
<div class="d-block">Hello From My Modal!</div>
<b-button @click="hideModal">Close Me</b-button>
<b-button @click="toggleModal">Toggle Me</b-button>
</b-modal>
</div>
export default {
methods: {
showModal() {
this.$root.$emit('bv::show::modal', 'modal-1', '#btnShow')
},
hideModal() {
this.$root.$emit('bv::hide::modal', 'modal-1', '#btnShow')
},
toggleModal() {
this.$root.$emit('bv::toggle::modal', 'modal-1', '#btnToggle')
}
}
}
Note: It is recommended to use the this.$bvModal.show()
and this.$bvModal.hide()
methods
(mentioned in a previous section) instead of emitting $root
events.
Prevent closing
To prevent <b-modal>
from closing (for example when validation fails). you can call the
.preventDefault()
method of the event object passed to your ok
(OK button), cancel
(Cancel button), close
(modal header close button) and hide
event handlers. Note that
.preventDefault()
, when used, must be called synchronously, as async is not supported.
<template>
<div>
<b-button v-b-modal.modal-prevent-closing>Open Modal</b-button>
<div class="mt-3">
Submitted Names:
<div v-if="submittedNames.length === 0">--</div>
<ul v-else class="mb-0 pl-3">
<li v-for="name in submittedNames">{{ name }}</li>
</ul>
</div>
<b-modal
id="modal-prevent-closing"
ref="modal"
title="Submit Your Name"
@show="resetModal"
@hidden="resetModal"
@ok="handleOk"
>
<form ref="form" @submit.stop.prevent="handleSubmit">
<b-form-group
:state="nameState"
label="Name"
label-for="name-input"
invalid-feedback="Name is required"
>
<b-form-input
id="name-input"
v-model="name"
:state="nameState"
required
></b-form-input>
</b-form-group>
</form>
</b-modal>
</div>
</template>
<script>
export default {
data() {
return {
name: '',
nameState: null,
submittedNames: []
}
},
methods: {
checkFormValidity() {
const valid = this.$refs.form.checkValidity()
this.nameState = valid ? 'valid' : 'invalid'
return valid
},
resetModal() {
this.name = ''
this.nameState = null
},
handleOk(bvModalEvt) {
bvModalEvt.preventDefault()
this.handleSubmit()
},
handleSubmit() {
if (!this.checkFormValidity()) {
return
}
this.submittedNames.push(this.name)
this.$nextTick(() => {
this.$refs.modal.hide()
})
}
}
}
</script>
Note: events ok
, cancel
, and close
are emitted by modal's built in OK, Cancel, and
header close (X) buttons respectively. These events will not be emitted, by default, if you have
provided your own buttons in the modal-footer
slot or have hidden the footer. In this case use the
hide
event to control cancelling of the modal close. Event hide
is always emitted, even if ok
,
cancel
, and close
are emitted.
The ok
, cancel
, close
and hide
event object (BvModalEvent
) contains several properties and
methods:
Property or Method |
Type |
Description |
preventDefault() |
Method |
When called prevents the modal from closing |
trigger |
Property |
Will be one of: ok (Default OK Clicked), cancel (Default Cancel clicked), esc (if the ESC key was pressed), backdrop (if the backdrop was clicked), headerclose (if the header X button was clicked), the first argument provided to the hide() method, or null otherwise. |
target |
Property |
A reference to the modal element |
vueTarget |
property |
A reference to the modal's Vue VM instance |
componentId |
property |
The modal's ID |
You can set the value of trigger
by passing an argument to the component's hide()
method for
advanced control (i.e. detecting what button or action triggered the modal to hide).
Note: ok
, cancel
, or close
events will be only emitted when the argument to hide()
is
strictly 'ok'
, 'cancel'
, or 'headerclose'
respectively. The argument passed to hide()
will
be placed into the trigger
property of the event object.
Modal content
Using the grid
Utilize the Bootstrap grid system within a modal by nesting <b-container fluid>
within the
modal-body. Then, use the normal grid system <b-row>
(or <b-form-row>
) and <b-col>
as you
would anywhere else.
Tooltips and popovers can be placed within modals as needed. When modals are closed, any tooltips
and popovers within are also automatically dismissed. Tooltips and popovers are automatically
appended to the modal element (to ensure correct z-indexing), although you can override where they
are appended by specifying a container ID (refer to tooltip and popover docs for details).
<div>
<b-button v-b-modal.modalPopover>Show Modal</b-button>
<b-modal id="modalPopover" title="Modal with Popover" ok-only>
<p>
This
<b-button v-b-popover="'Popover inside a modal!'" title="Popover">Button</b-button>
triggers a popover on click.
</p>
<p>
This <a href="#" v-b-tooltip title="Tooltip in a modal!">Link</a> will show a tooltip on
hover.
</p>
</b-modal>
</div>
Lazy loading and static modals
NEW in 2.0.0-rc.20
By default, modals will not render their content in the document until they are shown (lazily
rendered). Modals that, when visible, are rendered appended to the <body>
element. The <b-modal>
component will not affect layout, as they render as a placeholder comment node (<!---->
) in the
DOM position they are placed. Due to the portalling process, it can take two or more $nextTick
s to
render changes of the content into the target.
Modals can be rendered in-place in the document (i.e. where the <b-modal>
component is placed in
the document) by setting the static
prop to true
. Note that the content of the modal will be
rendered in the DOM even if the modal is not visible/shown when static
is true
. To make static
modals lazy rendered, also set the lazy
prop to true
. The modal will then appear in the document
only when it is visible. Note, when in static
mode, placement of the <b-modal>
component may
affect layout of your document and the modal.
The lazy
prop will have no effect if the prop static
is not true
(non-static modals will
always be lazily rendered).
Styling, options, and customization
Modal sizing
Modals have three optional sizes, available via the prop size
. These sizes kick in at certain
breakpoints to avoid horizontal scrollbars on narrower viewports. Valid optional sizes are sm
,
lg
, and xl
.
<div>
<b-button v-b-modal.modal-xl variant="primary">xl modal</b-button>
<b-button v-b-modal.modal-lg variant="primary">lg modal</b-button>
<b-button v-b-modal.modal-sm variant="primary">sm modal</b-button>
<b-modal id="modal-xl" size="xl" title="Extra Large Modal">Hello Extra Large Modal!</b-modal>
<b-modal id="modal-lg" size="lg" title="Large Modal">Hello Large Modal!</b-modal>
<b-modal id="modal-sm" size="sm" title="Small Modal">Hello Small Modal!</b-modal>
</div>
The size
prop maps the size to the .modal-<size>
classes.
Scrolling long content
When modals become too long for the user's viewport or device, they scroll independent of the page
itself. Try the demo below to see what we mean.
<div>
<b-button v-b-modal.modal-tall>Launch overflowing modal</b-button>
<b-modal id="modal-tall" title="Overflowing Content">
<p class="my-4" v-for="i in 20" :key="i">
Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis
in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
</p>
</b-modal>
</div>
You can also create a scrollable modal that allows the scrolling of the modal body by setting the
prop scrollable
to true
.
<div>
<b-button v-b-modal.modal-scrollable>Launch scrolling modal</b-button>
<b-modal id="modal-scrollable" scrollable title="Scrollable Content">
<p class="my-4" v-for="i in 20" :key="i">
Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis
in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros.
</p>
</b-modal>
</div>
Vertically centered modal
Vertically center your modal in the viewport by setting the centered
prop.
<div>
<b-button v-b-modal.modal-center>Launch centered modal</b-button>
<b-modal id="modal-center" centered title="BootstrapVue">
<p class="my-4">Vertically centered modal!</p>
</b-modal>
</div>
Feel free to mix vertically centered
with scrollable
.
Variants
Control the header, footer, and body background and text variants by setting the
header-bg-variant
, header-text-variant
, body-bg-variant
, body-text-variant
,
footer-bg-variant
, and footer-text-variant
props. Use any of the standard Bootstrap variants
such as danger
, warning
, info
, success
, dark
, light
, etc.
The variants for the bottom border of the header and top border of the footer can be controlled by
the header-border-variant
and footer-border-variant
props respectively.
<template>
<div>
<b-button @click="show=true" variant="primary">Show Modal</b-button>
<b-modal
v-model="show"
title="Modal Variants"
:header-bg-variant="headerBgVariant"
:header-text-variant="headerTextVariant"
:body-bg-variant="bodyBgVariant"
:body-text-variant="bodyTextVariant"
:footer-bg-variant="footerBgVariant"
:footer-text-variant="footerTextVariant"
>
<b-container fluid>
<b-row class="mb-1 text-center">
<b-col cols="3"></b-col>
<b-col>Background</b-col>
<b-col>Text</b-col>
</b-row>
<b-row class="mb-1">
<b-col cols="3">Header</b-col>
<b-col>
<b-form-select
v-model="headerBgVariant"
:options="variants"
></b-form-select>
</b-col>
<b-col>
<b-form-select
v-model="headerTextVariant"
:options="variants"
></b-form-select>
</b-col>
</b-row>
<b-row class="mb-1">
<b-col cols="3">Body</b-col>
<b-col>
<b-form-select
v-model="bodyBgVariant"
:options="variants"
></b-form-select>
</b-col>
<b-col>
<b-form-select
v-model="bodyTextVariant"
:options="variants"
></b-form-select>
</b-col>
</b-row>
<b-row>
<b-col cols="3">Footer</b-col>
<b-col>
<b-form-select
v-model="footerBgVariant"
:options="variants"
></b-form-select>
</b-col>
<b-col>
<b-form-select
v-model="footerTextVariant"
:options="variants"
></b-form-select>
</b-col>
</b-row>
</b-container>
<div slot="modal-footer" class="w-100">
<p class="float-left">Modal Footer Content</p>
<b-button
variant="primary"
size="sm"
class="float-right"
@click="show=false"
>
Close
</b-button>
</div>
</b-modal>
</div>
</template>
<script>
export default {
data() {
return {
show: false,
variants: ['primary', 'secondary', 'success', 'warning', 'danger', 'info', 'light', 'dark'],
headerBgVariant: 'dark',
headerTextVariant: 'light',
bodyBgVariant: 'light',
bodyTextVariant: 'dark',
footerBgVariant: 'warning',
footerTextVariant: 'dark'
}
}
}
</script>
You can also apply arbitrary classes to the modal dialog container, content (modal window itself),
header, body and footer via the modal-class
, content-class
, header-class
, body-class
and
footer-class
props, respectively. The props accept either a string or array of strings.
Disable open and close animation
To disable the fading transition/animation when modal opens and closes, just set the prop no-fade
on the <b-modal>
component.
You can disable the built-in footer buttons programmatically.
You can disable the Cancel and OK buttons individually by setting the cancel-disabled
and
ok-disabled
props, respectively, to true
. Set the prop to false
to re-enable the button.
To disable both Cancel and OK buttons at the same time, simply set the busy
prop to
true
. Set it to false
to re-enable both buttons.
Custom rendering with slots
ENHANCED in 2.0.0-rc.19
<b-modal>
provides several named slots (of which some are optionally scoped) that you can use to
customize the content of various sections of the modal.
Slot |
Optionally Scoped |
Description |
default |
Yes |
Main content of the modal |
modal-title |
Yes |
Content to place in the modal's title |
modal-header |
Yes |
Content to place in the header. Replaces the entire header including the close button |
modal-footer |
Yes |
Content to place in the footer. Replaces the entire footer including the button(s) |
modal-ok |
No |
Content to place inside the footer OK button |
modal-cancel |
No |
Content to place inside the footer CANCEL button |
modal-header-close |
No |
Content to place inside the header CLOSE (x ) button |
The scope available to the slots that support optional scoping are:
Method or Property |
Description |
ok() |
Closes the modal and fires the ok and hide events, with bvModalEvent.trigger = 'ok' |
cancel() |
Closes the modal and fires the cancel and hide events, with bvModalEvent.trigger = 'cancel' |
close() |
Closes the modal and fires the close and hide events, with bvModalEvent.trigger = 'headerclose' |
hide(trigger) |
Closes the modal and fires the hide event, with the bvModalEvent.trigger = trigger (trigger is optional) |
visible |
The visibility state of the modal. true if the modal is visible and false if not visible |
Example modal using custom scoped slots
<template>
<b-button @click="$bvModal.show('modal-scoped')">Open Modal</b-button>
<b-modal id="modal-scoped">
<template slot="modal-header" slot-scope="{ close }">
<b-button size="sm" variant="outline-danger" @click="close()">
Close Modal
</b-button>
<h5>Modal Header</h5>
</template>
<template slot="default" slot-scope="{ hide }">
<p>Modal Body with button</p>
<b-button @click="hide()">Hide Modal</b-button>
</template>
<template slot="modal-footer" slot-scope="{ ok, cancel, hide }">
<b>Custom Footer</b>
<b-button size="sm" variant="success" @click="ok()">
OK
</b-button>
<b-button size="sm" variant="danger" @click="cancel()">
Cancel
</b-button>
<b-button size="sm" variant="outline-secondary" @click="hide('forget')">
Forget it
</b-button>
</template>
</b-modal>
</template>
Multiple modal support
Unlike native Bootstrap v4, BootstrapVue supports multiple modals opened at the same time.
To disable stacking for a specific modal, just set the prop no-stacking
on the <b-modal>
component. This will hide the modal before another modal is shown.
<div>
<b-button v-b-modal.modal-multi-1>Open First Modal</b-button>
<b-modal id="modal-multi-1" size="lg" title="First Modal" ok-only no-stacking>
<p class="my-2">First Modal</p>
<b-button v-b-modal.modal-multi-2>Open Second Modal</b-button>
</b-modal>
<b-modal id="modal-multi-2" title="Second Modal" ok-only>
<p class="my-2">Second Modal</p>
<b-button v-b-modal.modal-multi-3 size="sm">Open Third Modal</b-button>
</b-modal>
<b-modal id="modal-multi-3" size="sm" title="Third Modal" ok-only>
<p class="my-1">Third Modal</p>
</b-modal>
</div>
Notes:
- Avoid nesting a
<b-modal>
inside another <b-modal>
, as it may get "constrained" to the
boundaries of the parent modal dialog (specifically when static modals are used).
- The opaque backdrop will appear progressively darker for each modal that is opened. This is
expected behaviour as each backdrop is opened over top the other modals and backdrops.
Modal message boxes
NEW in 2.0.0-rc.19
BootstrapVue provides a few built in Message Box methods on the exposed this.$bvModal
object.
These methods provide a way to generate simple OK and Confirm style modal messages, from anywhere in
your app without having to explicitly place a <b-modal>
component in your pages.
Method |
Description |
this.$bvModal.msgBoxOk(message, options) |
Open a modal with message as the content and a single OK button |
this.$bvModal.msgBoxConfirm(message, options) |
Open a modal with message as the content and CANCEL and OK buttons |
The options
argument is an optional configuration object for adding titles and styling the Message
Box modal. The object properties correspond to <b-modal>
props, except in camelCase
format instead of kebab-case.
Both methods return a Promise
(requires a polyfill for IE 11 and older browser support) which
resolve into a value when the modal hides. .msgBoxOk()
always resolves to the value true
, while
.msgBoxConfirm()
resolves to either true
(OK button pressed), false
(CANCEL button pressed),
or null
(if the modal was closed via backdrop click, ESC press, or some other means.
If message
is not provided, both methods will return immediately with the value undefined
.
You can use either the .then(..).catch(...)
or async await
code styles (async await
requires
modern browsers or a transpiler).
OK message box
Example OK Message boxes
<template>
<div>
<div class="mb-2">
<b-button @click="showMsgBoxOne">Simple msgBoxOk</b-button>
Return value: {{ String(boxOne) }}
</div>
<div class="mb-1">
<b-button @click="showMsgBoxTwo">msgBoxOk with options</b-button>
Return value: {{ String(boxTwo) }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
boxOne: '',
boxTwo: ''
}
},
methods: {
showMsgBoxOne() {
this.boxOne = ''
this.$bvModal.msgBoxOk('Action completed')
.then(value => {
this.boxOne = value
})
.catch(err => {
})
},
showMsgBoxTwo() {
this.boxTwo = ''
this.$bvModal.msgBoxOk('Data was submitted successfully', {
title: 'Confirmation',
size: 'sm',
buttonSize: 'sm',
okVariant: 'success',
headerClass: 'p-2 border-bottom-0',
footerClass: 'p-2 border-top-0',
centered: true
})
.then(value => {
this.boxTwo = value
})
.catch(err => {
})
}
}
}
</script>
Confirm message box
Example Confirm Message boxes
<template>
<div>
<div class="mb-2">
<b-button @click="showMsgBoxOne">Simple msgBoxConfirm</b-button>
Return value: {{ String(boxOne) }}
</div>
<div class="mb-1">
<b-button @click="showMsgBoxTwo">msgBoxConfirm with options</b-button>
Return value: {{ String(boxTwo) }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
boxOne: '',
boxTwo: ''
}
},
methods: {
showMsgBoxOne() {
this.boxOne = ''
this.$bvModal.msgBoxConfirm('Are you sure?')
.then(value => {
this.boxOne = value
})
.catch(err => {
})
},
showMsgBoxTwo() {
this.boxTwo = ''
this.$bvModal.msgBoxConfirm('Please confirm that you want to delete everything.', {
title: 'Please Confirm',
size: 'sm',
buttonSize: 'sm',
okVariant: 'danger',
okTitle: 'YES',
cancelTitle: 'NO',
footerClass: 'p-2',
hideHeaderClose: false,
centered: true
})
.then(value => {
this.boxTwo = value
})
.catch(err => {
})
}
}
}
</script>
Message box notes
- Message Boxes require
Promise
support in the browser. If targeting your app for older browsers,
such as IE 11, please include a polyfill that provides Promise
support. If Promise
support is
not detected, then the message box methods will immediately return undefined
.
- Message Boxes are an extension of the
<b-modal>
component, and hence support the majority of
<b-modal>
props (using camelCase format), with the exception of the following
props: lazy
, static
, busy
, visible
, noStacking
, okOnly
, okDisabled
, and
cancelDisabled
.
- When a
title
(or titleHtml
) is not provided in the options, the header will not be shown.
- When a
title
(or titleHtml
) is provided in the options, the header close button is not shown
by default. You can enable the header close button by setting hideHeaderClose: false
in the
options.
- Message Boxes will throw an error (promise rejection) if they are closed/destroyed before they are
hidden. Always include a
.catch(error => { /* handler code */ })
reject handler, event if using
the async await
style code.
- When using Vue Router (or similar), Message Boxes will close and reject if the route changes
before the modal hides.
- Message boxes cannot be generated during Server Side Rendering (SSR).
- The Message Box
message
currently does not support HTML strings, however, you can pass an array
of VNodes
as the message
for fine grained control of the markup. You can use Vue's
this.$createElement
method to generate VNodes. This can also be done for the modal title (by passing VNodes to the
title
option), OK button text (via the okTitle
option), and the CANCEL button text (via the
cancelTitle
option).
- The
this.$bvModal
injection is only available when using the full BootstrapVue plugin or the
Modal plugin. It is not available if importing just the b-modal
component.
- A new
$bvModal
injection (mixin) is created for each Vue virtual machine (i.e. each instantiated
component), and is not usable via direct access to the Vue.prototype
, as it needs access to the
instance's this
and $root
contexts.
Listening to modal changes via $root events
To listen to any modal opening, use:
export default {
mounted() {
this.$root.$on('bv::modal::show', (bvEvent, modalId) => {
console.log('Modal is about to be shown', bvEvent, modalId)
})
}
}
Refer to the Events section of documentation for the
full list of events emitted.
Accessibility
<b-modal>
provides several accessibility features, including auto focus, return focus, and
keyboard (tab) focus containment.
For aria-labelledby
and aria-described
by attributes to appear on the modal, you must supply
an id
attribute on <b-modal>
. aria-labelledby
will not be present if you have the header
hidden.
Auto focus on open
<b-modal>
will autofocus the modal container when opened.
You can pre-focus an element within the <b-modal>
by listening to the <b-modal>
shown
event,
and call the element's focus()
method. <b-modal>
will not attempt to autofocus if an element
already has focus within the <b-modal>
.
<b-modal @shown="focusMyElement">
<div>
<b-button>I Don't Have Focus</b-button>
</div>
<div>
<b-form-input></b-form-input>
</div>
<div>
<b-form-input ref="focusThis"></b-form-input>
</div>
<div>
<b-form-input></b-form-input>
</div>
</b-modal>
export default {
methods: {
focusMyElement(e) {
this.$refs.focusThis.focus()
}
}
}
Note: it is not recommended to autofocus an input inside a modal for accessibility reasons, as
screen reader users will not know the context of where the input is. It is best to let <b-modal>
focus the modal container.
Returning focus to the triggering element
For accessibility reasons, it is desirable to return focus to the element that triggered the opening
of the modal, when the modal closes.
<b-modal>
will try and automatically determine which element had focus before the modal was
opened, and will return the focus to that element when the modal has hidden if possible. However,
several methods and options are provided to allow you to specify the element to return focus to once
the modal has hidden.
Specify return focus element via the return-focus
prop
You can also specify an element to return focus to, when modal closes, by setting the return-focus
prop to one of the following:
- A CSS Query Selector string (or an element ID prepended with
#
)
- A component reference (which is mounted on a focusable element, such as
<b-button>
)
- A reference to a DOM element that is focusable
If the passed in element is not focusable, then the browser will determine what has focus (usually
<body>
, which is not desirable)
This method for returning focus is handy when you use the <b-modal>
methods show()
and hide()
,
or the v-model
prop. Note this property takes precedence over other methods of specifying the
return focus element.
Auto return focus
When <b-modal>
is opened via the v-b-modal
directive on an element, focus will be returned to
this element automatically when <b-modal>
closes, unless an element has been specified via the
return-focus
prop.
Specify return focus via event
When using the bv::show::modal
event (emitted on $root
), you can specify a second argument which
is the element to return focus to. This argument accepts the same types as the return-focus
prop.
this.$root.$emit('bv::show::modal', 'modal-1', '#focusThisOnClose')
Tip: if using a click event (or similar) to trigger modal to open, pass the event's target
property:
<div>
<b-button @click="$root.$emit('bv::show::modal', 'modal-1', $event.target)">Open Modal</b-button>
</div>
Note: If the <b-modal>
has the return-focus
prop set, then the element specified via the
event will be ignored.
Keyboard navigation
When tabbing through elements within a <b-modal>
, if focus attempts to leave the modal into the
document, it will be brought back into the modal.
In some circumstances, you may need to disable the enforce focus feature. You can do this by setting
the prop no-enforce-focus
.