Laravel vue inertia show sweetalert message on form success

520 Views Asked by At

So I have this component included in my main layout file, it looks like this:

<script setup>
import {usePage} from "@inertiajs/vue3";
import {computed} from "vue";

const page = usePage()
const message = computed(() => page.props.flash.message)

if (message) {
  Swal.fire({
    text: 'Success!',
    icon: 'success',
    toast: true,
    showConfirmButton: false,
    position: 'bottom',
    timer: 3500
  });
}
</script>

The above is something I have been playing around with. Right now it shows the flash message immediately before even submitting any forms. I want to show it only on a successful form submission. The best thing I reckon is to only include the component just once after a successful form submit. But since the message always shows immediately I have been trying with the above without success so far.

From my controller I am redirecting back with a flash message like so:

return redirect()->route('user.dashboard')->withMessage('It works');

In my HandleInertiaRequests middleware I added:

return array_merge(parent::share($request), [
    'flash' => [
        'message' => session('message')
    ]
]);

I know I can display the message in a div like so, and this is working:

<div v-if="$page.props.flash.message">{{ $page.props.flash.message }}</div>

But that's not what I want, I want to show the sweetalert message, and only show it once.

2

There are 2 best solutions below

2
Forge On BEST ANSWER

in your app.blade.php file add this

<!-- sweetalert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>

in your HandleInertiaRequests.php add this

public function share(Request $request): array
{
    return array_merge(parent::share($request), [
    //add this
        'flash' => [
            'status'=> session('status')
        ]
    ]);
}

then create Swal.vue

<template></template>
<script setup>
import { onMounted, onUpdated } from 'vue';
const props = defineProps({
    status: {
        type: Object,
        default: {}
    },
});

function showSwal() {
    Swal.fire(
        props.status.action,
        props.status.text,
        props.status.type
    )
}

onMounted(() => {
    if (props.status) {
        showSwal()
    }
})

onUpdated(() => {
    if (props.status) {
        showSwal()
    }
})
</script>

then add this to your layout file

<Swal v-if="$page?.props.flash?.status" :status="$page?.props.flash?.status" />

finally to use it just use this

return back()->with('status', ['type' => 'success', 'action' => 'type of acction', 'text' => 'your text here']);
4
Jeyhun Rashidov On

If I understand correctly, you want to display alert once. This codes the SweetAlert should pop up only when the component is mounted.

<script setup>
import { usePage } from "@inertiajs/vue3";
import { onMounted, computed } from "vue";

const page = usePage();
const message = computed(() => page.props.flash.message);

onMounted(() => {
  if (message.value) {
    Swal.fire({
      text: message.value,
      icon: 'success',
      toast: true,
      showConfirmButton: false,
      position: 'bottom',
      timer: 3500
    });
  }
});
</script>

However, you should clear the flash message after showing the SweetAlert.