Reputation: 206
Elaboration on Question:
I'm using a bootstrap modal dialogue, and I only want it to work if the user is logged in.
While vue.js can make this element disappear entirely if a user is not logged in, or handle links of any kind, 'data-target' is giving me trouble.
Goal: Check if a user is logged in before activating modal. If a user is NOT logged in, I handle it somewhere else in the code (details there are not germane to this question IMO, but involve activating a completely separate modal).
If the user IS logged in, then allow the modal to be activated via 'data-target'
Problem: Currently, when a user is NOT logged in, the 'reportModalIdWithHash' is activated before the 'checkForLogin()'
Code:
<span
class="float-right text-muted smaller-font make-clickable"
data-toggle="modal"
:data-target="reportModalIdWithHash"
v-on:click="checkForLogin()"
>
Report
</span>
Note About Preferred Solution:
I'd like to have "checkForLogin()" to happen before the modal is triggered by "data-target".
While I can always make elements dissappear with Vue.js, I want the user to see the option and then when they click on it, if they're not logged in, then present a login instead of the report modal.
Is it possible to intercept and re-fire 'data-target'?
Upvotes: 1
Views: 1518
Reputation: 90038
Why not use a dynamic data-target
?
:data-target="`#${isLoggedIn ? 'fancy' : 'login'}-modal`"
new Vue({
el: '#app',
data: () => ({
isLoggedIn: false
}),
methods: {
handleLogin() {
// replace this with an async API call...
this.isLoggedIn = true;
// and switch modals...
['fancy', 'login'].forEach(name => $(`#${name}-modal`).modal('toggle'));
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" ></script>
<div id="app" class="container">
<div class="form-check p-3">
<input class="form-check-input" type="checkbox" v-model="isLoggedIn" id="check">
<label class="form-check-label" for="check">
<code>isLoggedIn</code> (click to change)
</label>
</div>
<div class="btn btn-primary" data-toggle="modal"
v-text="`Open Report`"
:data-target="`#${isLoggedIn ? 'fancy' : 'login'}-modal`"></div>
<div class="modal fade" tabindex="-1" role="dialog" id="login-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Login modal</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Login modal content goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" @click="handleLogin" data-dismiss="modal" >Login</button>
</div>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" role="dialog" id="fancy-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Fancy report</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Fancy report goes here.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Meh...</button>
<button type="button" class="btn btn-primary">OK</button>
</div>
</div>
</div>
</div>
</div>
Note: this is a simple proof of concept, not production ready code:
With BootstrapVue, your button would look more like this:
<b-btn v-b-modal[`${isLoggedIn ? 'fancy' : 'login'}-modal`]> Open Modal</b-btn>
...or, if you want to handle it in a method:
<b-btn @click="handleOpenModal">Open modal</b-btn>
and:
methods: {
handleOpenModal() {
this.$bvModal.open(this.isLoggedIn ? 'fancy-modal' : 'login-modal');
}
}
Upvotes: 3