<b-modal>: Parameterized modals using scoped slots
See original GitHub issueBackground
When using bootstrap vue, I noticed that I often end-up with a modal that I want to reuse across multiple places. For instance, I am currently trying to reproduce the Android modal style select picker, but with some added filtering for long lists of values. Basically, a modal with a dynamic list of radio buttons in it. For this I am using a lazy bootstrap modal, global to my application, that I trigger with a $root event.
Current solution
To get this to work, I had to wrap the modal in a component with a bunch of extra logic to get the context out of the event and set it into the modal when it loads. In the end, I basically wrap the show and hide methods/events.
Better solution
This feels like stuff that could be included in the bootstrap vue modal out of the box in a much more interesting way. What I would like to see is support for the vuejs scoped slots feature. That way, we could do something like this:
<!-- Assuming this modal definition -->
<b-modal id="listSelector" title="Pick a value...">
<template slot-scope="{ foo, bar }">
<p>{{foo}} {{bar}}</p>
</template>
</b-modal>
<!-- We could display it in these manners... -->
<!-- Show with directive and modifier -->
<b-button v-b-modal.listSelector="{ foo: 42, bar: 'stuff' }">Pick...</b-button>
<!-- Show with directive but no modifier. -->
<!-- Can still support the old string param when no context is needed. -->
<b-button v-b-modal="{ $modal: 'listSelector', foo: 42, bar: 'stuff' }">Pick...</b-button>
<!-- Show with this.$refs.myModalRef.show({ foo: 42, bar: 'stuff' }) -->
<b-button ref="myModalRef">Pick...</b-button>
<!-- Show with <b-modal v-model="context">...</b-modal> -->
<!-- Accept any truthy value instead boolean. -->
<b-button @click="context = { foo: 42, bar: 'stuff' }">Pick...</b-button>
<!-- Show with a root event. -->
<!-- Same as the no modifier directive so accepts either a string or object. -->
<b-button @click="$root.$emit('bv::show::modal', { $modal: 'listSelector', foo: 42, bar: 'stuff' })">Pick...</b-button>
Obviously, since these modals are declared using a template, they would have to be lazy.
Thoughts
What are you thoughts? Does this looks like a good idea? I am considering writing a wrapper for my project to enable this in my project. Would you be interested in including it inside this library or would you prefer to include the feature straight in the b-modal component?
Issue Analytics
- State:
- Created 5 years ago
- Reactions:3
- Comments:17 (12 by maintainers)
Another possibility might be to have an option to render the modal dialog container as a
<form>
element, and provide a prop(s) to set attributes/listeners on the form.This sounds like an interesting idea.
We are in the process of reviewing modal (and a few other components) to be able to use default/named scoped-slots (besides plan named slots) to pass methods down (like the
.hide(..)
method to make it easier to close the modal when using one’s own header and footer contents).It might be possible to merge these two ideas together and pass both the modal methods and scoped data (passing data in a
data
property):And it may even be possible for the
.hide(...) method
to accept a second argument (the first argument is used to signify what closed the modal, i.e. ok, cancel, close, backdrop, esc, etc), which could be passed back to any@hidden
/@hide
event handlers on the modal via theBvEvent
object, or a second argument.We are also contemplating making modal always lazy, so that it never appears in document until needed.