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

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء السادس - إضافة الترتيب حسب الأعمدة Sort By Columns

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء السادس - إضافة الترتيب حسب الأعمدة Sort By Columns

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

في هذا المقال سوف نتعرف كيف يمكن عمل sort لكل عمود وذلك حسب الترتيب تصاعدي أو تنازلي.

إعدادات VueJS

للقيام بذلك سنحتاج إلى ما يلي :-

  • للتعديل على العناوين بجعله link وذلك لأننا سوف نستخدم الحدث click، وعند الضغط عليه سوف يتم تنفيذ دالة بإسم change_sort ونرسل معها باراميتر بإسم الحقل الذي نريد الترتيب من خلالة.
  • إضافة سهمين واحد للأعلى والأخر للأسفل.
<tr>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('id')">id</a>
        <span>&uarr;</span>
        <span>&darr;</span>
    </th>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('title')">title</a>
        <span>&uarr;</span>
        <span>&darr;</span>
    </th>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('body')">body</a>
        <span>&uarr;</span>
        <span>&darr;</span>
    </th>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('created_at')">created_at</a>
        <span>&uarr;</span>
        <span>&darr;</span>
    </th>
</tr>

بالتالي نحصل على هذا الشكل

نحتاج الأن لتعريف متغيرين في data وهما الترتيب الإفتراضي الذي ستكون علية البيانات

data(){
    return {
        posts:{},
        categories:{},
        category_id:'',
        sort_field:'created_at',
        sort_direction:'DESC',
    }
},

إضافة هذا المتغيرات للدالة getResults بداخل methods، بمعنى أن البيانات عندما يتم عرضها بالصفحة سيتم ترتيبها حسب حقل created_at وسيكون الترتيب بشكل DESC.

methods:{
    getResults(page = 1) {
        axios.get('/api/posts?page=' + page 
            + '&category_id='+this.category_id
            + '&sort_field='+this.sort_field
            + '&sort_direction='+this.sort_direction)
            .then(response => {
                this.posts = response.data;
            });
    }
}

إضافة الدالة change_sort في methods

methods:{
    change_sort(field){
      if(this.sort_field === field){
          this.sort_direction = this.sort_direction === 'asc' ? 'desc' : 'asc';
      }else {
          this.sort_field = field;
          this.sort_direction='asc';
      }
      this.getResults();
    },
    getResults(page = 1) {
        axios.get('/api/posts?page=' + page
            + '&category_id='+this.category_id
            + '&sort_field='+this.sort_field
            + '&sort_direction='+this.sort_direction)
            .then(response => {
                this.posts = response.data;
            });
    }
}

توضيح

  • الدالة change_sort تستقبل باراميتر بإسم الحقل الذي نريد الترتيب من خلالة.
  • نتحقق اذا كان إسم الحقل الذي تم إستقبالة يساوي قيمة المتغير sort_field الموجود في data، فإنه سوف يتم تغيير الترتيب اذا كان asc سيصبح desc.
  • اذا كان إسم الحقل الذي تم إستقبالة لا يساوي قيمة المتغير sort_field فإنه سوف يتم تغيير قيمة field بقيمة المتغير الذي تم إستقبالة، والترتيب سيكون asc.

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

نحتاج للتعديل على الدالة index في PostController

public function index()
{
    $sortField=\request('sort_field', 'created_at');
    if(!in_array($sortField,['id','title','body','created_at'])){
        $sortField = 'created_at';
    }
    $sortDirection=\request('sort_direction', 'desc');
    if(!in_array($sortDirection,['asc','desc'])){
        $sortDirection = 'desc';
    }
    $posts=Post::when(request('category_id','') !='',function ($q){
        $q->where('category_id',request('category_id'));
    })->orderBy($sortField,$sortDirection)
        ->paginate(10);
    return PostResource::collection($posts);
}

توضيح

  1. تم تعريف متغير بإسم sortField، حيث سوف يستقبل request بإسم sort_field وأن القيمة الإفتراضية له created_at.
  2. تم إستخدام الدالة in_array ووضع الحقول التي سيتم الترتيب من خلالها بداخلها، واذا كان هناك حقول أخرى تم إرسالها من front_end غير المعرفة بداخل المصفوفة، سيتم إعادة وضع قيمة المتغير sort_field تساوي created_at بمعنى ان الترتيب سيكون حسب حقل created_at، أما إذا كان قيمة request من ضمن المصفوفة، فإن قيمة sort_field ستكون حسب القيمة التي تم إستقبالها، بمعنى ان الترتيب سيكون حسب الحقول id,title,body,created_at فقط، تم عمل ذلك خوفا من عملية التلاعب.
  3. تم تعريف متغير بإسم sortDirection وسوف يستقبل request بإسم sort_direction والقيمة الإفتراضية له desc.
  4. تم إستخدام الدالة in_array ووضع الترتيبين asc,desc بداخلها للتحقق من الترتيب المرسل من قبل front_end، وإذا كان الترتيب غير هذين القيمتين سيكون الترتيب desc، أما إذا كان من ضمن المصفوفة فإن قيمة sortDirection ستكون حسب القيمة التي تم إستقبالها.
  5. تم إضافة orderBy إلى جملة eloquent ويتم الترتيب حسب قيمة المتغيرين sortFied, sortDirection.

بالتالي سوف نحصل على هذه النتيجة

من أجل تحسين تجربة المستخدم، يجب أن ان يكون arrow المفعل بلون، والأخر بلون أخر، للتوضيح أكثر، فإنه بالوضع الإفتراضي، ترتيب البيانات يكون حسب حقل created_at بشكل تنازلي ، فيجب ان يكون &arrow باللون الأسود و &darrow باللون السكني، وللقيام بذلك

نضيف coditional class يظهر حسب الحالة

<thead>
<tr>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('id')">id</a>
        <span :class="this.sort_field === 'id' && this.sort_direction === 'asc' ? 'text-dark' : 'text-secondary'">&uarr;</span>
        <span :class="this.sort_field === 'id' && this.sort_direction === 'desc' ? 'text-dark' : 'text-secondary'">&darr;</span>
    </th>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('title')">title</a>
        <span :class="this.sort_field === 'title' && this.sort_direction === 'asc' ? 'text-dark' : 'text-secondary'">&uarr;</span>
        <span :class="this.sort_field === 'title' && this.sort_direction === 'desc' ? 'text-dark' : 'text-secondary'">&darr;</span>
    </th>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('body')">body</a>
        <span :class="this.sort_field === 'body' && this.sort_direction === 'asc' ? 'text-dark' : 'text-secondary'">&uarr;</span>
        <span :class="this.sort_field === 'body' && this.sort_direction === 'desc' ? 'text-dark' : 'text-secondary'">&darr;</span>
    </th>
    <th scope="col">
        <a href="#" @click.prevent="change_sort('created_at')">created_at</a>
        <span :class="this.sort_field === 'created_at' && this.sort_direction === 'asc' ? 'text-dark' : 'text-secondary'">&uarr;</span>
        <span :class="this.sort_field === 'created_at' && this.sort_direction === 'desc' ? 'text-dark' : 'text-secondary'">&darr;</span>
    </th>
</tr>
</thead>

فنحصل على النتيجة التالية


إضافة تعليق
Loading...