Bruno Predot

Finalisation de la fogique du composant MovieCommentForm avec la gestion de la v…

…alidation au submit + la création d'un event pour remonter les data au parent pour gestion.
1 <script lang="ts" setup> 1 <script lang="ts" setup>
  2 +//#region --Import--.
2 import { useVuelidate } from "@vuelidate/core"; 3 import { useVuelidate } from "@vuelidate/core";
3 -import { helpers, maxLength, minLength, required, minValue, maxValue } from "@vuelidate/validators"; 4 +import { helpers, maxLength, maxValue, minLength, minValue, required } from "@vuelidate/validators";
  5 +//#endregion
4 6
5 -// type FormData = { 7 +//#region --Emit--.
6 -// username: string 8 +const emit = defineEmits(['event:submit']);
7 -// message: string 9 +//#endregion
8 -// rating: number  
9 -// };  
10 10
11 -type FormData = { [key: string]: string|number }; 11 +//#region --Props--.
  12 +defineProps({
  13 + isSubmitting: {
  14 + type: Boolean,
  15 + required: false,
  16 + nullable: false,
  17 + default: false,
  18 + },
  19 +});
  20 +//#endregion
12 21
13 //#region --Data/ref--. 22 //#region --Data/ref--.
14 const initialState = { 23 const initialState = {
@@ -33,11 +42,11 @@ const rules = { @@ -33,11 +42,11 @@ const rules = {
33 minLength: helpers.withMessage("Le message doit contenir au moins 3 caractères", minLength(3)), 42 minLength: helpers.withMessage("Le message doit contenir au moins 3 caractères", minLength(3)),
34 maxLength: helpers.withMessage("Le message ne peut pas dépasser 500 caractères", maxLength(500)), 43 maxLength: helpers.withMessage("Le message ne peut pas dépasser 500 caractères", maxLength(500)),
35 }, 44 },
36 - rating:{ 45 + rating: {
37 required: helpers.withMessage("La notation est requise", required), 46 required: helpers.withMessage("La notation est requise", required),
38 minValue: helpers.withMessage("Le message ne être inférieure à 0", minValue(0)), 47 minValue: helpers.withMessage("Le message ne être inférieure à 0", minValue(0)),
39 maxValue: helpers.withMessage("Le message ne être suppérieur à 10", maxValue(10)), 48 maxValue: helpers.withMessage("Le message ne être suppérieur à 10", maxValue(10)),
40 - } 49 + },
41 }; 50 };
42 51
43 const formData = reactive({ 52 const formData = reactive({
@@ -46,28 +55,27 @@ const formData = reactive({ @@ -46,28 +55,27 @@ const formData = reactive({
46 const v$ = useVuelidate(rules, formData); 55 const v$ = useVuelidate(rules, formData);
47 //#endregion 56 //#endregion
48 57
49 -function submitComment() { 58 +//#region --Function--.
50 - console.log("Submit !") 59 +async function submitComment() {
  60 + emit('event:submit', formData);
51 } 61 }
52 62
53 -function clear () { 63 +function clear() {
54 v$.value.$reset(); 64 v$.value.$reset();
55 formData.username = initialState.username; 65 formData.username = initialState.username;
56 formData.message = initialState.message; 66 formData.message = initialState.message;
57 formData.rating = initialState.rating; 67 formData.rating = initialState.rating;
58 } 68 }
59 69
60 -// :error-messages="getErrors('username', $v.username)" :counter="10" label="username" 70 +//#endregion
61 -// :error-messages="getErrors('message', $v.message)"  
62 </script> 71 </script>
63 72
64 <template> 73 <template>
65 <section> 74 <section>
66 - movie comment form 75 + <VForm>
67 - <VForm @submit.prevent="submitComment">  
68 <v-text-field 76 <v-text-field
69 v-model="formData.username" 77 v-model="formData.username"
70 - :error-messages="v$.username.$errors.map(e => e.$message)" 78 + :error-messages="v$.username.$errors.map((e) => e.$message)"
71 label="nom d'utilisateur" 79 label="nom d'utilisateur"
72 placeholder="nom d'utilisateur" 80 placeholder="nom d'utilisateur"
73 required 81 required
@@ -76,7 +84,7 @@ function clear () { @@ -76,7 +84,7 @@ function clear () {
76 /> 84 />
77 <v-textarea 85 <v-textarea
78 v-model="formData.message" 86 v-model="formData.message"
79 - :error-messages="v$.message.$errors.map(e => e.$message)" 87 + :error-messages="v$.message.$errors.map((e) => e.$message)"
80 label="message" 88 label="message"
81 placeholder="Saisissez votre commentaire" 89 placeholder="Saisissez votre commentaire"
82 required 90 required
@@ -85,7 +93,7 @@ function clear () { @@ -85,7 +93,7 @@ function clear () {
85 /> 93 />
86 <v-text-field 94 <v-text-field
87 v-model="formData.rating" 95 v-model="formData.rating"
88 - :error-messages="v$.rating.$errors.map(e => e.$message)" 96 + :error-messages="v$.rating.$errors.map((e) => e.$message)"
89 label="Note (1-10)" 97 label="Note (1-10)"
90 placeholder="" 98 placeholder=""
91 required 99 required
@@ -93,7 +101,25 @@ function clear () { @@ -93,7 +101,25 @@ function clear () {
93 @blur="v$.rating.$touch" 101 @blur="v$.rating.$touch"
94 @input="v$.rating.$touch" 102 @input="v$.rating.$touch"
95 /> 103 />
96 - <v-btn class="mr-4">submit</v-btn> 104 + <v-btn
  105 + class="mt-6 mr-4"
  106 + color="primary"
  107 + @click="
  108 + async () => {
  109 + const validForm = await v$.$validate();
  110 + if (validForm) {
  111 + submitComment();
  112 + }
  113 + }
  114 + "
  115 + >
  116 + <span v-if="isSubmitting" class="flex items-center justify-center">
  117 + <span class="w-5 h-5 border-2 border-white border-t-transparent rounded-full animate-spin mr-2" />
  118 + Envoi en cours...
  119 + </span>
  120 + <span v-else>Publier le commentaire</span>
  121 + </v-btn>
  122 + <v-btn class="mt-6 mr-4" color="primary" @click="clear"> effacer </v-btn>
97 </VForm> 123 </VForm>
98 </section> 124 </section>
99 </template> 125 </template>
@@ -19,6 +19,7 @@ const { currentRoute } = useRouter(); @@ -19,6 +19,7 @@ const { currentRoute } = useRouter();
19 19
20 //#region --Data/ref--. 20 //#region --Data/ref--.
21 const isLoading = ref(true); 21 const isLoading = ref(true);
  22 +const isSubmitting = ref(false);
22 //#endregion 23 //#endregion
23 24
24 //#region --Computed--. 25 //#region --Computed--.
@@ -177,7 +178,7 @@ onMounted(() => { @@ -177,7 +178,7 @@ onMounted(() => {
177 </div> 178 </div>
178 </div> 179 </div>
179 <!-- Comments form. --> 180 <!-- Comments form. -->
180 - <form-movie-comment-form /> 181 + <form-movie-comment-form @event:submit="console.log('submitted !', $event)" />
181 </section> 182 </section>
182 </div> 183 </div>
183 </div> 184 </div>