UNPKG

16.6 kBMarkdownView Raw
1# Modals
2
3> Modals are streamlined, but flexible dialog prompts powered by JavaScript and CSS. They
4support a number of use cases from user notification to completely custom content and
5feature a handful of helpful sub-components, sizes, variants, accessibility, and more.
6
7```html
8<div>
9 <b-btn v-b-modal.modal1>Launch demo modal</b-btn>
10
11 <!-- Modal Component -->
12 <b-modal id="modal1" title="Bootstrap-Vue">
13 <p class="my-4">Hello from modal!</p>
14 </b-modal>
15</div>
16
17<!-- modal-1.vue -->
18```
19
20## Overview
21`<b-modal>`, by default, has an **OK** and **Cancel** buttons in the footer. These buttons can
22be customized by setting various props on the component. You can customize the size of the buttons,
23disable buttons, hide the **Cancel** button (i.e. OK Only), choose a variant (e.g. `danger`
24for a red OK button) using the `ok-variant` and `cancel-variant` props, and provide custom
25button content using the `ok-title` and `cancel-title` props, or using the named
26slots `modal-ok` and `modal-cancel`.
27
28`<b-modal>` supports close on ESC (enabled by default), close on backdrop click (enabled by default), and
29the `X` close button in the header (enabled by default). These features may be disabled by setting the the
30props `no-close-on-esc`, `no-close-on-backdrop`, and `hide-header-close` respectively.
31
32You can override the modal title via the named slot `modal-title`, override the
33header completely via the `modal-header` slot, and override the footer completely
34via the `modal-footer` slot.
35
36**Note**: when using the `modal-footer` slot, the default **OK** and **Cancel** buttons will not
37be present. Also, if you use the `modal-header` slot, the default header `X` close button will
38not be present, nor can you use the `modal-title` slot.
39
40## Toggle Modal Visibility
41
42There are several methods that you can employ to toggle the visibility of `<b-modal>`.
43
44### Using `v-b-modal` directive (recommended)
45
46Other elements can easily show modals using the `v-b-modal` directive.
47
48```html
49<div>
50 <!-- Using modifiers -->
51 <b-btn v-b-modal.myModal>Show Modal</b-btn>
52
53 <!-- Using value -->
54 <b-btn v-b-modal="'myModal'">Show Modal</b-btn>
55
56 <!-- the modal -->
57 <b-modal id="myModal">
58 Hello From My Modal!
59 </b-modal>
60 </div>
61
62 <!-- modal-directive-1.vue -->
63```
64
65Focus will automatically be returned to the trigger element once the modal closes.
66See the **Accessibility** section below for details.
67
68### Using `show()` and `hide()` component methods
69
70You can access modal using `ref` attribute and then call the `show()` or `hide()` methods.
71
72```html
73<template>
74 <div>
75 <b-button @click="showModal">
76 Open Modal
77 </b-button>
78 <b-modal ref="myModalRef" hide-footer title="Using Component Methods">
79 <div class="d-block text-center">
80 <h3>Hello From My Modal!</h3>
81 </div>
82 <b-btn class="mt-3" variant="outline-danger" block @click="hideModal">Close Me</b-btn>
83 </b-modal>
84 </div>
85</template>
86
87<script>
88export default {
89 methods: {
90 showModal () {
91 this.$refs.myModalRef.show()
92 },
93 hideModal () {
94 this.$refs.myModalRef.hide()
95 }
96 }
97}
98</script>
99
100<!-- modal-methods-1.vue -->
101```
102
103The `hide()` method accepts an optional argument. See section **Prevent Closing**
104below for details.
105
106### Using `v-model` property
107
108`v-model` property is always automatically synced with `<b-modal>` visible state
109and you can show/hide using `v-model`.
110
111```html
112<template>
113 <div>
114 <b-button @click="modalShow = !modalShow">
115 Open Modal
116 </b-button>
117 <b-modal v-model="modalShow">
118 Hello From Modal!
119 </b-modal>
120 </div>
121</template>
122
123<script>
124export default {
125 data () {
126 return {
127 modalShow: false
128 }
129 }
130}
131</script>
132
133<!-- modal-v-model-1.vue -->
134```
135
136When using the `v-model` property, do not use the `visible` property at the same time.
137
138
139### Emitting Events on $root
140
141You can emit `bv::show::modal` and `bv::hide::modal` event on `$root` with the first
142argument set to the modal's id. An optional second argument can specify the element
143to return focus to once the modal is closed. The second argument can be a CSS selector,
144an element reference, or a component reference.
145
146```html
147<div>
148 <b-button @click="showModal" ref="btnShow">
149 Open Modal
150 </b-button>
151 <b-modal @hidden="onHidden">
152 <div class="d-block">Hello From My Modal!</div>
153 <b-btn @click="hideModal">Close Me</b-btn>
154 </b-modal>
155</div>
156```
157
158```js
159methods: {
160 showModal () {
161 this.$root.$emit('bv::show::modal','modal1')
162 },
163 hideModal () {
164 this.$root.$emit('bv::hide::modal','modal1')
165 },
166 onHidden (evt) {
167 // Return focus to our Open Modal button
168 // See accessibility below for additional return-focus methods
169 this.$refs.btnShow.$el.focus()
170 }
171}
172```
173
174
175## Prevent Closing
176
177To prevent `<b-modal>` from closing (for example when validation fails). you can call
178the `preventDefault()` method of the event object passed to your `ok` (**OK** button),
179`cancel` (**Cancel** button) and `hide` event handlers.
180
181```html
182<template>
183 <div>
184 <b-btn v-b-modal.modalPrevent>Launch demo modal</b-btn>
185 <!-- Main UI -->
186 <div class="mt-3 mb-3">
187 Submitted Names:
188 <ul>
189 <li v-for="n in names">{{n}}</li>
190 </ul>
191 </div>
192 <!-- Modal Component -->
193 <b-modal id="modalPrevent"
194 ref="modal"
195 title="Submit your name"
196 @ok="handleOk"
197 @shown="clearName">
198 <form @submit.stop.prevent="handleSubmit">
199 <b-form-input type="text"
200 placeholder="Enter your name"
201 v-model="name"></b-form-input>
202 </form>
203 </b-modal>
204 </div>
205</template>
206
207<script>
208export default {
209 data () {
210 return {
211 name: '',
212 names: []
213 }
214 },
215 methods: {
216 clearName () {
217 this.name = ''
218 },
219 handleOk (evt) {
220 // Prevent modal from closing
221 evt.preventDefault()
222 if (!this.name) {
223 alert('Please enter your name')
224 } else {
225 this.handleSubmit()
226 }
227 },
228 handleSubmit () {
229 this.names.push(this.name)
230 this.clearName()
231 this.$refs.modal.hide()
232 }
233 }
234}
235</script>
236
237<!-- modal-prevent-1.vue -->
238```
239
240**Note**: events `ok` and `cancel` are emitted by modal's built in **OK** and **Cancel**
241buttons respectively. These events will not be emitted, by default, if you have provided your own
242buttons in the `modal-footer` slot or have hidden the footer. In this case use the `hide` event
243to control cancelling of the modal close. Event `hide` is always emitted, even if `ok` and `cancel`
244are emitted.
245
246The `ok`, `cancel`, and `hide` event object contains several properties and methods:
247
248| Property or Method | Type | Description
249| ------------ | ------ | --------------------------------------------
250| `e.preventDefault()` | Method | When called prevents the modal from closing
251| `trigger` | Property | Will be one of: `ok` (Default **OK** Clicked), `cancel` (Default **Cancel** clicked), `esc` (if the <kbd>ESC</kbd> key was pressed), `backdrop` (if the backdrop was clicked), `headerclose` (if the header X button was clicked), the argument provided to the `hide()` method, or `undefined` otherwise.
252| `target` | Property | A reference to the modal element
253| `vueTarget` | property | A reference to the modal's Vue VM instance
254
255You can set the value of `trigger` by passing an argument to the component's
256`hide()` method for advanced control.
257
258**Note:** `ok` and `cancel` events will be only emitted when the argument to `hide()` is strictly `'ok'`
259or `'cancel'` respectively. The argument passed to `hide()` will be placed into the
260`trigger` property of the event object.
261
262
263## Modal sizing
264Modals have two optional sizes, available via the prop `size`. These sizes kick in at certain
265breakpoints to avoid horizontal scrollbars on narrower viewports. Valid optional sizes are
266`lg`, or `sm`.
267
268```html
269<div>
270 <b-btn v-b-modal.modallg variant="primary">Large modal</b-btn>
271 <b-btn v-b-modal.modalsm variant="primary">Small modal</b-btn>
272
273 <b-modal id="modallg" size="lg" title="Large Modal">
274 Hello Modal!
275 </b-modal>
276 <b-modal id="modalsm" size="sm" title="Small Modal">
277 Hello Modal!
278 </b-modal>
279</div>
280
281<!-- modal-sizes.vue -->
282```
283
284
285## Vertically centering
286Vertically center your modal in the viewport by setting the `centered` prop.
287
288```html
289<div>
290 <b-btn v-b-modal.modal-center>Launch centered modal</b-btn>
291
292 <!-- Modal Component -->
293 <b-modal id="modal-center" centered title="Bootstrap-Vue">
294 <p class="my-4">Vertically centered modal!</p>
295 </b-modal>
296</div>
297
298<!-- modal-center-v.vue -->
299```
300
301## Using the grid
302Utilize the Bootstrap grid system within a modal by nesting `<b-container fluid>` within
303the modal-body. Then, use the normal grid system `<b-row>` (or `<b-form-row>`) and `<b-col>`
304as you would anywhere else.
305
306
307## Tooltips and popovers
308Tooltips and popovers can be placed within modals as needed. When modals are closed, any tooltips
309and popovers within are also automatically dismissed. Tooltips and popovers are automatically
310appended to the modal element (to ensure correct z-indexing), although you can override where
311they are appended by specifying a container ID (refer to tooltip and popover docs for details).
312
313```html
314<div>
315 <b-btn v-b-modal.modalPopover>Show Modal</b-btn>
316 <b-modal id="modalPopover" title="Modal with Popover" ok-only>
317 <p>
318 This
319 <b-btn v-b-popover="'Popover inside a modal!'" title="Popover">
320 Button
321 </b-btn>
322 triggers a popover on click.
323 </p>
324 <p>
325 This <a href="#" v-b-tooltip title="Tooltip in a modal!">Link</a>
326 will show a tooltip on hover.
327 </p>
328 </b-modal>
329</div>
330
331<!-- modal-popover.vue -->
332```
333
334
335## Variants
336Control the header, footer, and body background and text variants by setting the
337`header-bg-variant`, `header-text-variant`, `body-bg-variant`, `body-text-variant`,
338`footer-bg-variant`, and `footer-text-variant` props. Use any of the standard Bootstrap
339variants such as `danger`, `warning`, `info`, `success`, `dark`, `light`, etc.
340
341The variants for the bottom border of the header and top border of the footer can be
342controlled by the `header-border-variant` and `footer-border-variant` props respectively.
343
344```html
345<template>
346 <div>
347 <b-btn @click="show=true" variant="primary">Show Modal</b-btn>
348 <b-modal v-model="show"
349 title="Modal Variants"
350 :header-bg-variant="headerBgVariant"
351 :header-text-variant="headerTextVariant"
352 :body-bg-variant="bodyBgVariant"
353 :body-text-variant="bodyTextVariant"
354 :footer-bg-variant="footerBgVariant"
355 :footer-text-variant="footerTextVariant">
356 <b-container fluid>
357 <b-row class="mb-1 text-center">
358 <b-col cols="3"> </b-col>
359 <b-col>Background</b-col>
360 <b-col>Text</b-col>
361 </b-row>
362 <b-row class="mb-1">
363 <b-col cols="3">Header</b-col>
364 <b-col><b-form-select :options="variants" v-model="headerBgVariant" /></b-col>
365 <b-col><b-form-select :options="variants" v-model="headerTextVariant" /></b-col>
366 </b-row>
367 <b-row class="mb-1">
368 <b-col cols="3">Body</b-col>
369 <b-col><b-form-select :options="variants" v-model="bodyBgVariant" /></b-col>
370 <b-col><b-form-select :options="variants" v-model="bodyTextVariant" /></b-col>
371 </b-row>
372 <b-row>
373 <b-col cols="3">Footer</b-col>
374 <b-col><b-form-select :options="variants" v-model="footerBgVariant" /></b-col>
375 <b-col><b-form-select :options="variants" v-model="footerTextVariant" /></b-col>
376 </b-row>
377 </b-container>
378 <div slot="modal-footer" class="w-100">
379 <p class="float-left">Modal Footer Content</p>
380 <b-btn size="sm" class="float-right" variant="primary" @click="show=false">
381 Close
382 </b-btn>
383 </div>
384 </b-modal>
385 </div>
386</template>
387
388<script>
389export default {
390 data () {
391 return {
392 show: false,
393 variants: [
394 'primary', 'secondary', 'success', 'warning', 'danger', 'info', 'light', 'dark'
395 ],
396 headerBgVariant: 'dark',
397 headerTextVariant: 'light',
398 bodyBgVariant: 'light',
399 bodyTextVariant: 'dark',
400 footerBgVariant: 'warning',
401 footerTextVariant: 'dark'
402 }
403 }
404}
405</script>
406
407<!-- modal-variant-1.vue -->
408```
409
410
411## Lazy loading
412Modal will always render its HTML markup in the document at the location that
413the `<b-modal>` component is placed (even if it is not shown). You can hide
414the modal markup from being in the DOM while modal is in the hidden state by
415setting the `lazy` prop.
416
417
418## Disable open and close animation
419To disable the fading transition/animation when modal opens and closes, just set the prop
420`no-fade` on the `<b-modal>` component.
421
422
423## Disabling built-in buttons
424You can disable the built-in footer buttons programatically.
425
426You can disable the **Cancel** and **OK** buttons individually by setting the `cancel-disabled`
427and `ok-disabled` props, respectively, to `true`. Set the prop to `false` to re-enable
428the button.
429
430To disable both **Cancel** and **OK** buttons at teh same time, simply set the `busy`
431prop to `true`. Set it to `false` to re-enable both buttons.
432
433
434## Accessibility
435
436`<b-modal>` provides several accessibility features, including auto focus, return
437focus, and keyboard (tab) _focus containment_.
438
439For `aria-labelledby` and `aria-described` by attributes to appear on the
440modal, you **must** supply an `id` attribute on `<b-modal>`. `aria-labelledby` will
441not be present if you have the header hidden.
442
443## Auto Focus on open
444
445`<b-modal>` will autofocus the modal container when opened.
446
447You can pre-focus an element within the `<b-modal>` by listening to the `<b-modal>` `shown` event, and
448call the element's `focus()` method. `<b-modal>` will not attempt to autofocus if
449an element already has focus within the `<b-modal>`.
450
451```html
452<b-modal @shown="focusMyElement">
453 <b-button>I Don't Have Focus</b-button>
454 <br>
455 <b-form-input type="text"></b-form-input>
456 <br>
457 <!-- element to gain focus when modal is opened -->
458 <b-form-input ref="focusThis" type="text"></b-form-input>
459 <br>
460 <b-form-input type="text"></b-form-input>
461</b-modal>
462```
463
464```js
465methods: {
466 focusMyElement (e) {
467 this.$refs.focusThis.focus()
468 }
469}
470```
471
472## Returning focus to the triggering element
473
474For accessibility reasons, it is desirable to return focus to the element
475that triggered the opening of the modal, when the modal closes. `<b-modal>`
476provides several methods and options for returning focus to the triggering element.
477
478### Specify Return Focus Element via the `return-focus` Prop
479
480You can also specify an element to return focus to, when modal closes, by setting
481the `return-focus` prop to one of the following:
482
483- A CSS Query Selector string (or an element ID prepended with `#`)
484- A component reference (which is mounted on a focusable element, such as `<b-button>`)
485- A reference to a DOM element that is focusable
486
487If the passed in element is not focusable, then the browser will determine
488what has focus (usually `<body>`, which is not desireable)
489
490This method for returning focus is handy when you use the `<b-modal>` methods `show()`
491and `hide()`, or the `v-model` prop. Note this property takes
492precedence over other methods of specifying the return focus element.
493
494### Auto Return Focus
495
496When `<b-modal>` is opened via the `v-b-modal` directive on an element, focus will be
497returned to this element automatically when `<b-modal>` closes, unless an element has
498been specified via the `return-focus` prop.
499
500### Specify Return Focus via Event
501
502When using the `bv::show::modal` event (emitted on `$root`), you can specify a second argument
503which is the element to return focus to. This argument accepts the same types
504as the `return-focus` prop.
505
506```js
507this.$root.$emit('bv::show::modal', 'modal1', '#focusThisOnClose');
508```
509
510*Tip:* if using a click event (or similar) to trigger modal to open, pass the
511event's `target` property:
512
513```html
514<b-btn @click="$root.$emit.('bv::show::modal', 'modal1', $event.target)">
515 Open Modal
516</b-btn>
517```
518
519**Note:** If the `<b-modal>` has the `return-focus` prop set, then the element specified
520via the event will be ignored.
521
522
523## Keyboard Navigation
524
525When tabbing through elements within a `<b-modal>`, if focus attempts to leave the modal into the document,
526it will be brought back into the modal.
527
528In some circumstances, you may need to disable the enforce focus feature. You can do this
529by setting the prop `no-enforce-focus`.
530
531
532## Component Reference