في المقال السابق قمنا بإرسال البيانات من front end بإستخدام vuejs إلى backend بإستخدام laravel، وتم إدخال وحفظ البيانات بنجاح وكذلك التحقق من البيانات المرسلة، لكن هذه العملية تحتاج لبعض التحسينات مثل إظهار رسالة خطأ للمستخدمين، منع عمل إرسال أكثر من مره لنفس الفورم، إظهار رسالة نجاح عملية الإدخال، ففي هذه المقال سوف نتعرف على كل ذلك بمشيئة الله.
لو حاولنا إرسال البيانات دون أن يتم تعبئة الحقول فإن البيانات لن يتم إدخالها، ولن يظهر للمستخدم رسالة تفيد بذلك لكن، لو قمنا بفتح network tab فإننا سنرى ما يلي
كما نرى ان رسالة الخطأ هي بخصوص ان هذه الحقول إجبارية، ولكي نقوم بإظهار هذه الرسائل للمستخدم
نذهب للملف create.js الموجود في المسار resources/js/components/Posts/create.vue ونقوم بما يلي :
data(){ return { categories:{}, fields:{ title:'', text:'', category_id:'' }, errors:{}, } },
methods:{ submit_form(){ axios.post('/api/posts',this.fields) .then(response => { this.$router.push('/'); }).catch(error=>{ if(error.response.status === 422){ this.errors = error.response.data.errors; } }); } }
تم إستخدام الدالة catch وبداخلها سنتحقق أنه إذا كان الخطأ ب status code = 422 وهو كود التحقق من البيانات المدخلة، فإن المتغير error الموجود في المتغير data سوف تخزن الأخطاء بداخلة.
لإظهار رسالة الخطأ في html فإننا بحاجة لإضافة div مخصص للأخطاء، وإذا كان هناك أخطاء يتم إظهار هذا الدف من خلال إستخدام v-if dirictive
<input type="text" v-model="fields.title" class="form-control"><br/> <div class="alert alert-danger" v-if="errors && errors.title"> {{ errors.title[0]}} </div>
كما نلاحظ أنه تحققنا إذا كان خطأ وإذا كان الخطأ يحتوي على title.
إضافة التحقق للحقول الأخرى
Post Text:<br/> <textarea rows="10" v-model="fields.body" class="form-control"></textarea><br/> <div class="alert alert-danger" v-if="errors && errors.body"> {{ errors.title[1]}} </div> Category:<br/> <select class="form-control" v-model="fields.category_id"> <option value="">==Please Choose Categories ==</option> <option v-for="category in categories" :value="category.id">{{ category.name}}</option> </select> <div class="alert alert-danger" v-if="errors && errors.category_id"> {{ errors.title[2]}} </div>
يمكننا ذلك من خلال إضافة disabled property إلى زر الإدخال وفي المتغير data نعرف متغير مثلا بإسم form_submiting ونعطيها قيمة false وهي القيمة الإفتراضية، وفي حال تفعيل دالة submiting_post لإرسال البيانات نغير حالتها إلى true
<input type="submit" :disabled="form_submiting" value="Save" class="btn btn-primary"/>
data(){ return { categories:{}, fields:{ title:'', text:'', category_id:'' }, errors:{}, form_submiting:false } },
methods:{ submit_form(){ this.form_submiting=true; axios.post('/api/posts',this.fields) .then(response => { this.$router.push('/'); this.form_submiting = false; }).catch(error=>{ if(error.response.status === 422){ this.errors = error.response.data.errors; this.form_submiting=false; } }); } }
نلاحظ هنا في دالة submit_form أنه سيتم تغيير قيمة form_submiting إلى true وبعد إنتهاء الإتصال سيتم إعادة قيمتها إلى false.
ميزة أخرى يمكن إضافتها، وهي تغيير value أي الكتابة على button إنه في حال إدخال البيانات إظهار loading أو تغيير النص إلى saving post... وللقيام بذلك نستخدم نفس المتغير form_submiting مع الـ value property
<input type="submit" :disabled="form_submiting" :value="form_submiting ? 'Saving Post...' : 'Save'" class="btn btn-primary"/>
فيصبح لدينا الشكل التالي
من أجل تحسين تجربة المستخدم user experience يجب إظهار رسالة تأكيد أنه تم إضافة، مقال، حذف مقال، وواحده من أفضل المكتبات التي يمكن إستخدامها هي مكتبة sweetalert، ولكن كيف:
تضمين المكتبة في الملف welcome.blade.php
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
في إضافة post بداخل الدالة form_submiting إستدعاء الدالة، في حال وجود إستجابة بإدخال البيانات
methods:{ submit_form(){ this.form_submiting=true; axios.post('/api/posts',this.fields) .then(response => { swal({ title:"تم التعديل بنجاح", icon: "success", button: "إغلاق", }) this.$router.push('/'); this.form_submiting = false; }).catch(error=>{ swal({ title:"There is an error", icon: "error", button: "Close", }) if(error.response.status === 422){ this.errors = error.response.data.errors; this.form_submiting=false; } }); } }
الكود بالكامل
<template> <div> <form @submit.prevent="submit_form"> Post Title:<br/> <input type="text" v-model="fields.title" class="form-control"><br/> <div class="alert alert-danger" v-if="errors && errors.title"> {{ errors.title[0]}} </div> Post Text:<br/> <textarea rows="10" v-model="fields.body" class="form-control"></textarea><br/> <div class="alert alert-danger" v-if="errors && errors.body"> {{ errors.title[0]}} </div> Category:<br/> <select class="form-control" v-model="fields.category_id"> <option value="">==Please Choose Categories ==</option> <option v-for="category in categories" :value="category.id">{{ category.name}}</option> </select> <div class="alert alert-danger" v-if="errors && errors.category_id"> {{ errors.title[0]}} </div> <br/> <input type="submit" :disabled="form_submiting" :value="form_submiting ? 'Saving Post...' : 'Save'" class="btn btn-primary"/> </form> </div> </template> <script> export default { data(){ return { categories:{}, fields:{ title:'', text:'', category_id:'' }, errors:{}, form_submiting:false } }, mounted() { axios.get('/api/category') .then(response => { this.categories = response.data.data; }); }, methods:{ submit_form(){ this.form_submiting=true; axios.post('/api/posts',this.fields) .then(response => { swal({ title:"Post Added Successfully", icon: "success", button: "Close", }) this.$router.push('/'); this.form_submiting = false; }).catch(error=>{ if(error.response.status === 422){ swal({ title:"There is an error", icon: "error", button: "Close", }) this.errors = error.response.data.errors; this.form_submiting=false; } }); } } } </script>