Hello everyone! Currently, I'm involved in a Laravel project where I am using laravel/breeze VueJS with Inertia. The login functionality is implemented using a bootstrap modal component. While validation and authentication are working smoothly, the only issue I'm facing is that after successful authentication, the modal closes but the backdrop remains visible.
I've noticed that the form onSuccess does not trigger any emit function. Interestingly, when I used console.log, it worked perfectly fine.
Below you can find the code snippets for reference...
Header.vue
<script setup>
import { ref } from 'vue';
import Modal from '@/Components/Modal.vue'
let thisModal = ref(null)
function showModal() {
thisModal.value.show()
}
function closeModal() {
thisModal.value.close()
}
</script>
<template>
<header class="shadow-sm">
<Modal v-if="! $page.props.auth.user" ref="thisModal">
<template #body>
<Login @closeParent="closeModal" @showParent="showModal" />
<Register />
</template>
</Modal>
</header>
</template>
Modal.vue
<script setup>
import { onMounted, ref } from 'vue'
import { Modal } from 'bootstrap'
defineProps({
title: String
})
let modalEle = ref(null)
let thisModalObj = null
onMounted(() => {
thisModalObj = new Modal(modalEle.value)
})
function _show() {
thisModalObj.show()
}
function _close() {
thisModalObj.hide()
}
defineExpose({ show: _show, close: _close })
</script>
<template>
<div class="modal fade" tabindex="-1" role="dialog" ref="modalEle">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header bg-secondary">
<slot name="header" />
</div>
<div class="modal-body tab-content py-4">
<slot name="body" />
</div>
<slot name="footer" />
</div>
</div>
</div>
</template>
Login.vue (Form location)
<script setup>
import { Link, useForm } from '@inertiajs/vue3'
import Checkbox from '@/Components/Checkbox.vue'
import InputError from '@/Components/InputError.vue'
import InputLabel from '@/Components/InputLabel.vue'
import PrimaryButton from '@/Components/PrimaryButton.vue'
import TextInput from '@/Components/TextInput.vue'
import PasswordToggle from '@/Components/PasswordToggle.vue'
defineProps({
canResetPassword: {
type: Boolean,
},
status: {
type: String,
},
})
const form = useForm({
email: '',
password: '',
remember: false,
})
const emit = defineEmits()
const submit = () => {
form.post(route('login'), {
onFinish: () => form.reset('password'),
// onBefore hides the modal
onBefore: () => emit('closeParent'),
// onError shows the modal
onError: () => emit('showParent'),
// Use onSuccess instead
onSuccess: () => emit('closeParent')
})
}
</script>
<template>
<form @submit.prevent="submit" id="login-tab" class="tab-pane fade show active" autocomplete="off" novalidate>
<!-- Form fields here -->
</form>
</template>
The above code works such that the modal is hidden upon clicking the Sign in button and will reappear if there is an error like validation failure or incorrect credentials. However, I want it to close only when authentication is successful. The problem may lie in the fact that the onSuccess method receives an Inertia response as shown in the controller below:
AuthenticatedSessionController.php
/**
* Handle an incoming authentication request.
*/
public function store(LoginRequest $request) // : RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
Also, I'd like to mention that the modal code was shared by @OJay in response to a query posted here.