I have a modal component that displays a form:
<template>
<div ref="modal" class="modal fade" :id="id" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title h5">New Ladder</h1>
<button type="button" class="btn-close" aria-label="Close"
data-bs-dismiss="modal"></button>
</div>
<div ref="alert"></div>
<form @submit.prevent="handleSubmit">
<div class="modal-body">
<div class="mb-1">
<label for="addLadderName" class="form-label" hidden>Name</label>
<input type="text" class="form-control" id="addLadderName" placeholder="Enter name"
v-model.trim="addLadderForm.name"/>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary me-auto"
data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">
{{ processing ? 'One moment please...' : 'Create' }}
</button>
</div>
</form>
</div>
</div>
</div>
</template>
On submission, I set the processing
flag to true
, and set it back to false
once I receive a response from the server.
const modal = ref(null);
const alert = ref(null);
const processing = ref(false);
const addLadderForm = reactive({name: ''});
function handleSubmit() {
if (processing.value) {
return;
}
processing.value = true
const payload = {
name: addLadderForm.name,
};
addLadder(payload);
}
function addLadder(payload) {
const path = 'http://localhost:5001/new-ladder';
axios.post(path, payload)
.then(() => {
processing.value = false;
Modal.getInstance(modal.value).hide();
})
.catch((error) => {
console.log(error);
showAlert('danger', error.toString());
processing.value = false;
});
}
While waiting for the server response, I would like to force the modal to stay open, even if the user attempts to close it.
I have tried v-bind
ing various data-bs-*
properties to temporarily get the desired effect:
<template>
<div ref="modal" class="modal fade" :id="id" tabindex="-1" role="dialog"
:data-bs-backdrop="processing ? 'static' : 'true'"
:data-bs-keyboard="processing ? 'static' : 'true'">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title h5">New Ladder</h1>
<button type="button" class="btn-close" aria-label="Close"
:data-bs-dismiss="modal"></button>
</div>
<div ref="alert"></div>
<form @submit.prevent="handleSubmit">
<div class="modal-body">
<div class="mb-1">
<label for="addLadderName" class="form-label" hidden>Name</label>
<input type="text" class="form-control" id="addLadderName" placeholder="Enter name"
v-model.trim="addLadderForm.name"/>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary me-auto"
:data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">
{{ processing ? 'One moment please...' : 'Create' }}
</button>
</div>
</form>
</div>
</div>
</div>
</template>
But that doesn’t seem to work; I can still close the modal during a hard-coded 10-second pause on the server side. It occurs to me that I could wire a bunch of the UI into to my own closeModal
and do the appropriate checks within instead of relying on data-bs-dismiss
. However, that seems like a duplication of existing work, especially since I’d have to figure out how to replicate whatever data-bs-backdrop="static"
does.
I am using Vue 3.4.29 and Bootstrap 5.3.3, but not bootstrap-vue
.
tallow_amnesty is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1