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

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء الثامن - إدخال البيانات وعمل Form Submit

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء الثامن - إدخال البيانات وعمل Form Submit

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

بعد أن قمنا بإنشاء  route، والإنتهاء من عرض البيانات، سوف نتعرف على كيفية إنشاء form والإتصال مع api وإدخال البيانات في قاعدة البيانات.


تحضير VueJs

في ال component الذي قمنا بإنشاؤه، وهو resources/js/components/Posts/create.vue قمنا بإنشاء form وهو مكون من ثلاث حقول (العنوان، النص، القسم)، لذلك يجب علينا أن نقوم بجلب الأقسام categories من قاعدة البيانات.

للقيام بذلك بداخل الدالة mounted يجب إنشاء إلإتصال مع قاعدة البيانات، ووضعها بمتغير في يكون معرف مسبقا في الدالة data هنا قمت بعمل متغير إسمه categories، وفي html يتم عمل loop عليه من خلال v-for directive.

<template>
    <div>
        <form>
            Post Title:<br/>
            <input type="text" class="form-control"><br/>
            Post Text:<br/>
            <textarea rows="10" class="form-control"></textarea><br/>
            Category:<br/>
            <select class="form-control">
                <option value="">==Please Choose Categories ==</option>
                <option v-for="category in categories" :value="category.id">{{ category.name}}</option>
            </select>
            <br/>
            <button class="btn btn-primary">Save Post</button>
        </form>
    </div>
</template>
<script>
export default {
    data(){
        return {
            categories:{}
        }
    },
    mounted() {
        axios.get('/api/category')
            .then(response => {
                this.categories = response.data.data;
            });
    }
}
</script>

كما نعلم جميعنا أنه في كل حقل يجب أن يتم تعريف property بإسم name مثلا name=title حتى نستطيع الوصول لهذا الـ text، لكن في vueJs نستخدم v-model مثلا إذا أردنا تعريف حقل title نستخدم v-model="title" وهكذا.

لذلك نحن الأن بحاجة لتعريف جميع الحقول بواسطة v-model directive

<input type="text" v-model="fields.title" class="form-control"><
<textarea rows="10" v-model="fields.body" class="form-control"></textarea><
<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>

هذه الحقول التي تم تعريفها يجب أن يتم عمل لها initial value بداخل data

data(){
    return {
        categories:{},
        fields:{
            title:'',
            text:'',
            category_id:''
        }
    }
},

الأن عند حدوث أي تغيير في الـ fields فإن المتغيرات بداخل الـ data ستتغير قيمتها إلى قمية المدخلات، مثلا اذا تم كتابة how create vue js app في حقل title فإن المتغير title في الداخلة fields سوف تصبح قميمته تساوي how create vue js app وهكذا.


إنشاء دالة إرسال البيانات إلى api

نحتاج لإنشاء دالة لإرسال البيانات، سوف أسمي هذه الدالة بإسم submit_form، فيجب تعريف هذه الدالة في داخل methods

methods:{
    submit_form(){
        axios.post('/api/posts',this.fields)
            .then(response => {
                this.$router.push('/');
            });
    }
}

نلاحظ إنه تم إستخدام axios وهو من نوع post ومن ثم وضع رابط api وهو ما سيتم تعريفه في laravel route api، ومن ثم إرسال الحقول، وإذا تم إدخال البيانات سيتم تحويلنا للصفحة الرئيسية بإستخدام الدالة $router.push.


إستدعاء الدالة submit_form 

من إجل تنفيذ هذه الدالة عند الضغط على الـ button وهو زر الإدخال، فإنه يجب ان يتم تعريف دالة submit.prevent ولكن على مستوى الـ form

<form @submit.prevent="submit_form">

كما نلاحظ إنه تم عمل @submit.prevent وهنا تم إتخدام prevent وذلك لمنع التصرف التلقائي للمتصفح default behavior.


إعدادات لارافيل

إنشاء route

في المقالات السابقة كان هناك route لجلب البيانات، لكن بإمكاننا إستخدام apiResource حيث يقوم بإنشاء 5 route وهم (index, store, show, update, destroy)، ففي الملف api.php يجب تعريف هذا الـ route.

Route::apiResource('posts', PostController::class);
Route::get('category', [CategoryController::class, 'index']);


التحقق من البيانات

للتحقق من البيانات المدخلة فإننه يفضل إنشاء FormRequest فهنا سأقوم بإنشاء StorePostRequest من خلال الأمر

php artisan make:request StorePostRequest

حيث سيتم إنشاء كلاس بإسم StorePostReuest في المسار app/Http/Requests/StorePostRequest.php وهو يحتوي على دالتين الأولى authorize يجب تغيير قميتها إلى true والدالة الأخرى rules وهنا يتم وضع الحقول وعمليات التحقق

class StorePostRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'title'=>'required',
            'body'=>'required',
            'category_id'=>'required',
        ];
    }
}

عملية التحقق هنا، أن الحقول إجبارية فقط.


إدخال البيانات 

في دالة store في PostController يجب إستخدام StorePostReuest عوضا عن Request الإفتراضية، وذلك حتى تتم عملية التحقق.

public function store(StorePostRequest $request)
{
    $post=Post::create($request->validated());
    return new PostResource($post);
}

وبذلك يمكننا إدخال البيانات بنجاح


الأكواد بالكامل

كود VueJs

<template>
    <div>
        <form @submit.prevent="submit_form">
            Post Title:<br/>
            <input type="text" v-model="fields.title" class="form-control"><br/>
            Post Text:<br/>
            <textarea rows="10" v-model="fields.body" class="form-control"></textarea><br/>
            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>
            <br/>
            <button class="btn btn-primary">Save Post</button>
        </form>
    </div>
</template>
<script>
export default {
    data(){
        return {
            categories:{},
            fields:{
                title:'',
                text:'',
                category_id:''
            }
        }
    },
    mounted() {
        axios.get('/api/category')
            .then(response => {
                this.categories = response.data.data;
            });
    },
    methods:{
        submit_form(){
            axios.post('/api/posts',this.fields)
                .then(response => {
                    this.$router.push('/');
                });
        }
    }
}
</script>


كود لارافيل

كود route في ملف api.php

<?php
use App\Http\Controllers\Api\CategoryController;
use App\Http\Controllers\Api\PostController;
use Illuminate\Support\Facades\Route;

Route::apiResource('posts', PostController::class);
Route::get('category', [CategoryController::class, 'index']);


كود التحقق

<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StorePostRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'title'=>'required',
            'body'=>'required',
            'category_id'=>'required',
        ];
    }
}

كود الإدخال

public function store(StorePostRequest $request)
{
    $post=Post::create($request->validated());
    return new PostResource($post);
}
إضافة تعليق
Loading...