لارافيل, VueJs / 2024-05-13

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء التاسع - التحقق من المدخلات وإظهار الرسائل للمستخدمين، ومنع إرسال البيانات أكثر من مرة

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء التاسع - التحقق من المدخلات وإظهار الرسائل للمستخدمين، ومنع إرسال البيانات أكثر من مرة

2024-05-13 وقت القراءه : 5 دقائق

في المقال السابق قمنا بإرسال البيانات من front end بإستخدام vuejs إلى backend بإستخدام laravel، وتم إدخال وحفظ البيانات بنجاح وكذلك التحقق من البيانات المرسلة، لكن هذه العملية تحتاج لبعض التحسينات مثل إظهار رسالة خطأ للمستخدمين، منع عمل إرسال أكثر من مره لنفس الفورم، إظهار رسالة نجاح عملية الإدخال، ففي هذه المقال سوف نتعرف على كل ذلك بمشيئة الله.


التحقق وإظهار رسائل الخطأ للمستخدمين.

لو حاولنا إرسال البيانات دون أن يتم تعبئة الحقول فإن البيانات لن يتم إدخالها، ولن يظهر للمستخدم رسالة تفيد بذلك لكن، لو قمنا بفتح network tab فإننا سنرى ما يلي

كما نرى ان رسالة الخطأ هي بخصوص ان هذه الحقول إجبارية، ولكي نقوم بإظهار هذه الرسائل للمستخدم

نذهب للملف create.js الموجود في المسار resources/js/components/Posts/create.vue ونقوم بما يلي :

  • بداخل الدالة data نقوم بإضافة متغير جديد ليكن مثلا بإسم errors ويكون فارغ.
data(){
    return {
        categories:{},
        fields:{
            title:'',
            text:'',
            category_id:''
        },
        errors:{},
    }
},
  • في الدالة submit_form في methods نستخدم catch مع axios 
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>




منع إرسال البيانات أكثر من. مرة Prevent Double Submit

يمكننا ذلك من خلال إضافة 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"/>

فيصبح لدينا الشكل التالي


إضافة SweetAlert

من أجل تحسين تجربة المستخدم 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>
إضافة تعليق
Loading...