question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

<b-modal>: Parameterized modals using scoped slots

See original GitHub issue

Background

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:open
  • Created 5 years ago
  • Reactions:3
  • Comments:17 (12 by maintainers)

github_iconTop GitHub Comments

2reactions
tmorehousecommented, Apr 29, 2020

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.

2reactions
tmorehousecommented, Nov 25, 2018

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):

<b-modal id="listSelector" title="Pick a value...">
  <template slot-scope="{hide, data: { foo, bar }}">
    <p>{{foo}} {{bar}}</p>
  </template>
  <template slot="footer" slot-scope="{ hide }">
    <!-- No need to use this.$refs.modal.hide(...) -->
    <b-button @click="hide('ok')">OK</b-button>
    <b-button @click="hide('cancel')">Cancel</b-button>
  </template>
</b-modal>

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 the BvEvent object, or a second argument.

We are also contemplating making modal always lazy, so that it never appears in document until needed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Build a Reusable Modal Component Using Vue 3 ... - YouTube
In this video we build out a dynamic & reusable modal component using vue 3. We create this using the composition api, slots...
Read more >
Slots - Vue.js
Render Scope #. Slot content has access to the data scope of the parent component, because it is defined in the parent. For...
Read more >
Scoped Slots - Vue Final Modal
Vue Final Modal is a renderless, stackable, detachable and lightweight modal component.
Read more >
lme4: Linear Mixed-Effects Models using 'Eigen' and S4
Model -based (Semi-)Parametric Bootstrap for Mixed Models ... A fitted model of class merMod has a devcomp slot as described in the value ......
Read more >
An introduction to Slots and Scoped Slots | Geoblink Tech blog
We are going to create a modal with 3 different parts; header, ... With a scoped slot we can send data from the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found