كيفية إضافة عدد لا نهائي من الأقسام بشكل دايناميكي على شكل شجره في لارافيل

كيفية إضافة عدد لا نهائي من الأقسام بشكل دايناميكي على شكل شجره في لارافيل

2024-10-31 وقت القراءه : 3 دقائق

في بعض الأحيان وبالأخص في مواقع البيع، نحتاج لأن يتحكم صاحب الموقع بإضافة لا نهائي من الأقسام والأقسام الداخلية، في هذه المقالة سوف نتعرف سوية كيف يمكننا القيام بذلك.

بداية من ملف migraton

public function up()
{
    Schema::create('cats', function (Blueprint $table) {
        $table->id();
        $table->string('title',120);
        $table->unsignedBigInteger('parent')->nullable();
        $table->timestamps();
        $table->softDeletes();
    });
}

هنا نحتاج id, name, parent ، حقل parent هو من سيحدد لنا الأقسام الرئيسية والأقسام التي تتبع لها، حيث إنه إذا كان الحقل Null سيكون قسم رئيسي. وكل قسم فرعي يكون parent هو id القسم الأب.

نحتاج لتحديد العلاقه بين بين الأقسم والأبناء في الـ model

class cat extends Model
{
    use HasFactory;


    public function childs() {
        return $this->hasMany(self::class,'parent','id') ;
    }
}

الأن إستخراج هذه الأقسام من خلال جملة eloquent

public function index(){
    $cats = Cat::whereNull('parent')->with('childs')->get();
    return view('admin.cats.indexcats',compact('cats'));
}

في العرض (ملف blade)

@if($cats->count() > 0)
    @foreach ($cats as $cat)
            <div class="cat row">
                <div class="w-40">{{ $cat->title }}</div>
                <div class="w-20">{{ $cat->created_at }}</div>
            </div>
            @if (count($cat->childs))
                @include('admin.cats.child_category',['childs' => $cat->childs,'mr'=>50])
            @endif
    @endforeach
@else
    <div class="alert alert-danger">No Cats</div>
@endif

كما نرى بالكود أعلاه، قمنا بعرض الأقسام الرئيسية، والأقسام الفرعية يتم عرضها في ملف منفصل من خلال @include، لكن الجزء المهم في الملف admin.cats.child_category فإنه سوف يستخدم تضمين بعدد الأقسام الفرعية لنفسة لنفسة.

@foreach($childs as $child)
    <div class="cat row mr-{{ $mr }}">
        <div class="w-40-{{ $mr }}">{{ $child->title }}</div>
        <div class="w-20">{{ $child->created_at }}</div>
    </div>
    @if(count($child->childs))
        <?php $newMr = $mr+50; ?>
        @include('admin.cats.child_category',['childs' => $child->childs,'mr'=>$newMr])
    @endif
@endforeach

كما نرى أنه تم تمرير قيمة mr=50 للملف وفي الملف يتم زيادة قيمة mr بـ 50 في كل مرة يتم إستدعاء الملف بها.

تعبر قيمة mr عن margin-right في css حيث يجب تعريفها بشكل مسبق في css مثلا mr-100=margin-right:100 وهكذا ..

.mr-100{
    margin-right: 100px;
}
.mr-150{
    margin-right: 150px;
}
.mr-200{
    margin-right: 200px;
}


إضافة الأقسام

فورم الإضافة

<input required="required" type="text" name="title"/>
<select>
    <option value="">رئيسي</option>
    @foreach ($cats as $item)
        <option value="{{ $item->id }}">{{ $item->title }}</option>
        @if (count($item->childs))
             @include('admin.cats.selecttree',['childs' => $item->childs,'mr'=>1])
        @endif
    @endforeach
</select>

كما نلاحظ أن القسم الرئيسي يتم تحديده من خلال قيمة null،  والأقسام الأخرى تأخذ id القسم الأعلى، وبداخل foreach تم إستدعاء ملف admin.cats.selecttree وذلك كما بالأعلى حتى يستدعي نفسة في كل child 

@foreach($childs as $child)
    <option value="{{ $child->id }}"> {{ str_repeat('-', $mr) }} {{ $child->title }}</option>
    @if(count($child->childs))
    <?php $newMr = $mr+1 ; ?>
            @include('admin.cats.selecttree',['childs' => $child->childs,'mr'=>$newMr])
        @endif
@endforeach

كذلك تم تمرير قيمة mr=1 وتم إستبدالها بـ -، وفي كل مرة يعمل بها الملف include لنفسة يتم زيادة قيمتها بـ ١، فنحصل على هذا الشكل

كود eloquent للإدخال إلى قاعدة البيانات

public function store(Request $request){
    $cat=new cat();
    $cat->title=$request->title;
    $cat->parent=$request->parent;
    $cat->save();
}

التعليقات
زائر
منذ 3 سنوات

مشكور على هذا المقال كنا بحاجة له

moemen
منذ 3 سنوات

معلومات قيمة للغاية جزاك الله كل خير ربنا يوفقك يا باش مهندس

يوسف
منذ سنتين

مشكور جزاك الله كل خير

tohami
منذ سنة

رووووعة عاش نضاال الشعب الفلسطيني

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