Bonjour,

Je débute avec Laravel et InertiaJS et j'ai besoins d'un conseil pour valider les données d'un formulaire multi-pages.

Ce que je fais

Le formulaire est sous la forme de 3 template avec un ID step1 et step2.

<form @submit.prevent="submit" class="grid grid-cols-1 gap-y-6 sm:grid-cols-2 sm:gap-x-8 mt-6">
                    <template id="step1" v-if="currentStep === 1">
                        <div>
                            <label for="firstname" class="block text-sm text-lime-600">
                                First name <span class="text-red-500"> *</span>
                            </label>
                            <div class="mt-1">
                                <input type="text" name="firstname" id="firstname" v-model="form.firstname"
                                       autocomplete="given-name"
                                       class="py-1 px-2 text-sm font-light block w-full shadow-sm focus:ring-lime-700 focus:border-lime-500 border-gray-300" required>
                                <div v-if="form.errors.firstname">{{ form.errors.firstname }}</div>
                            </div>
                        </div>
                        <div>
                            <label for="lastname" class="block text-sm text-lime-600">
                                Last name <span class="text-red-500"> *</span>
                            </label>
                            <div class="mt-1">
                                <input type="text" name="lastname" id="lastname" v-model="fields.lastname"
                                       autocomplete="given-name"
                                       class="py-1 px-2 text-sm font-light block w-full shadow-sm focus:ring-lime-700 focus:border-lime-500 border-gray-300">
                                <div v-if="errors && errors.lastname" class="text-red-500 text-sm">
                                    {{ errors.lastname[0] }}</div>
                            </div>
                        </div>
                        <div class="sm:col-span-2">
                            <label for="email" class="block text-sm text-lime-600">
                                Email <span class="text-red-500"> *</span>
                            </label>
                            <div class="mt-1">
                                <input id="email" name="email" type="email" v-model="fields.email" autocomplete="email"
                                       class="py-1 px-2 text-sm font-light block w-full shadow-sm focus:ring-lime-700 focus:border-lime-500 border-gray-300">
                                <div v-if="errors && errors.email" class="text-red-500 text-sm">
                                    {{ errors.email[0] }}</div>
                            </div>
                            <p class="mt-1 text-sm text-gray-500">
                                A confirmation e-mail will be sent to this address.
                            </p>
                        </div>
                        <div class="sm:col-span-2">
                            <label for="phone" class="block text-sm text-lime-600">Mobile phone</label>
                            <div class="mt-1 relative rounded-md shadow-sm">
                                <input type="text" name="phone" id="phone" v-model="fields.phone" autocomplete="tel"
                                       class="py-1 px-2 text-sm font-light block w-full shadow-sm focus:ring-lime-700 focus:border-lime-500 border-gray-300" placeholder="+41 12 345 67 89">
                            </div>
                        </div>
                        <div class="flex items-center mt-4">
                            <p class="inline-flex items-center py-1 font-light text-sm">
                                <span class="text-red-500 "> * </span>&nbsp; Required fields
                            </p>
                        </div>
                        <div class="flex items-center justify-end mt-4">
                            <button type="submit" :disabled="form.processing" @click.prevent="submit(2)"
                                    class="inline-flex items-center justify-center px-2 py-1 border border-transparent rounded-md shadow-sm text-white text-sm bg-lime-600 hover:bg-lime-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-lime-500">
                                Continue
                            </button>
                        </div>
                    </template>
                    <template id="step2" v-if="currentStep === 2">
                        <div class="sm:col-span-2">
                            <label for="club_name" class="block text-sm text-lime-600">
                                Club name <span class="text-red-500"> *</span>
                            </label>
                            <div class="mt-1">
                                <input type="text" name="club_name" id="club_name" autocomplete="given-name"
                                       class="py-1 px-2 block w-full shadow-sm focus:ring-lime-700 focus:border-lime-500 border-gray-300 rounded-md">
                            </div>
                        </div>
                        <div>
                            <label for="domain" class="block text-sm text-lime-600">
                                Domain <span class="text-red-500"> *</span>
                            </label>
                            <div class="mt-1">
                                <input id="domain" name="domain" type="text" v-model="fields.domain" autocomplete="domain"
                                       class="py-1 px-2 block w-full shadow-sm focus:ring-lime-700 focus:border-lime-500 border-gray-300 rounded-md">
                            </div>
                        </div>
                        <div class="pt-7">
                            .gesticlub.ch
                        </div>
                    </template>
                </form>

Inertia + Vue code qui valide correctement la première page, mais je voudrais utiliser les fonctionnalités de Inertia plutôt qu'Axios...

import JetAuthenticationCard from "@/Jetstream/AuthenticationCard";
import JetAuthenticationCardLogo from "@/Jetstream/AuthenticationCardLogo";
import JetButton from "@/Jetstream/Button";
import JetInput from "@/Jetstream/Input";
import JetCheckbox from "@/Jetstream/Checkbox";
import JetLabel from "@/Jetstream/Label";
import JetValidationErrors from "@/Jetstream/ValidationErrors";

export default {
    name: "SignupLayout",

    components: {
        JetAuthenticationCard,
        JetAuthenticationCardLogo,
        JetButton,
        JetInput,
        JetCheckbox,
        JetLabel,
        JetValidationErrors,
    },

    template: {
        '#step1': {
            props: [
                'currentStep',
                'step1'
            ]
        },
        '#step2': {
            props: [
                'currentStep',
                'step2'
            ]
        },
    },

    data() {
        return {
            fields: {},
            errors: {},

            form: this.$inertia.form({
                firstname: null,
                lastname: null,
                email: false,
            }),
            //  For form steps
            //  ======================
            currentStep: 1,
            step1: {
                firstname: '',
                lastname: '',
                email: '',
                phone: '',
            },
            step2: {
                clubName: '',
                Domain: ''
            },
            //  ======================
        }
    },
    methods: {
        submit(step) {
            this.errors = {};
            axios.post(
                '/validateForm',
                this.fields
            ).then(response => {
               if (response.data.currentStep === 2) {
                   this.currentStep = 2 // Passe à la page 2 si le formulaire est validé.
               }
            }).catch(error => {
                if (error.response.status === 422) {
                    this.errors = error.response.data.errors || {};
                }
            });
        },
    },
}
</script>

Ce que je veux

Je veux valider les données du formulaire de la première page Step1 puis celles de la page 2 sans avoir à créer une Route par page. Ce qui arrivera si je poursuis avec Axios.

Ce que j'obtiens

Les données de la page 1 sont correctement validées par le controller et le formulaire passe correctement en page 2, malheureusement avec ce code ci je suis, il me semble obligé de créer une nouvelle Route pour la page 2 avec une nouvelle fonction dans le controller.

Merci d'avance pour votre aide et vos conseils.
Meilleures salutations

2 réponses


Franco
Auteur
Réponse acceptée

Bonjour Aashan,
je te remercie pour ta réponse, entre temps c'est un peu ce que j'ai fait...
J'ai passé une première requête Inertia.post(...) ave les champs de la step1 puis dans le controlleur je n'effectue qu'une validation des données.
Dans la 2ème step, j'envois le formulaire en entier puis dans le controller je valide les données de la step2 et les entre dans la base de données.

Tout fonctionne bien, même si je ne suis pas persuadé que c'est la meilleure solution.
Merci encore et bonne fin de semaine.

Bonjour,

Si j'ai bien compris, je peux te proposer de passer la step en paramètre de ta requète axios et d'effectuer le traitement dans ta fonction avec une petite condition "if".