How to sort elements with children elements in Laravel Voyager?

25 views Asked by At

I'm designing a model which has these fields:

title -> VARCHAR(255)
description -> TEXT
order -> FLOAT
parent_id -> INTEGER

As you see, this model has a field named as parent_id which refers the model itself with "Belongs To" relationship. So I'm trying to make a parent-child relationship in Laravel Voyager Admin Panel.

I also want to sort these elements with their parents. Usually we set INTEGER to order field type. But this is for "1,2,3,4,5,..." sorting. I want to sort them with their parent. So it should be like "1.1, 1.2, 1.3, 1.4, 2.1, 2.2, 3.1, 3.2, 3.3, ...". I set FLOAT to order because of this reason.

But as I see, Voyager only allows to make integer-like sorting. Is there any way to sort the records of the model with float-like? I mean sorting in the admin panel.

Thanks.

1

There are 1 answers

0
Chanchal Kumar Mahto On

I think helpful for development

in Laravel Voyager based on the provided database structure, where you have a parent_id column to establish hierarchical relationships,

you can use these steps:

  1. Define Model Relationships: Define the relationships in your models to represent the parent-child hierarchy.

like this code of model

// Category.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    public function children()
    {
        return $this->hasMany(Category::class, 'parent_id');
    }
    
    public function parent()
    {
        return $this->belongsTo(Category::class, 'parent_id');
    }
}
  1. Voyager BREAD: Set up the BREAD configuration for the Category model in Voyager. Include the necessary fields such as title, description, order, parent_id. order is a FLOAT type field.

look my controller code in this use some Sorting logic to handle sorting of elements with children elements in your controller

// CategoryController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Category;

class CategoryController extends Controller
{
    public function sortCategories(Request $request)
    {
        $sortedCategories = $request->input('categories');

        // Call method to recursively update the sorting order
        $this->updateCategoryOrder($sortedCategories);

        return response()->json(['message' => 'Categories sorted successfully']);
    }

    private function updateCategoryOrder($categories, $parentId = null)
    {
        foreach ($categories as $index => $category) {
            $categoryId = $category['id'];

            // Update the order of the category
            Category::where('id', $categoryId)->update(['order' => $index]);

            // Recursively update the order of child categories
            if (isset($category['children'])) {
                $this->updateCategoryOrder($category['children'], $categoryId);
            }
        }
    }
}

now you can use Voyager BREAD view to include the necessary elements for sorting. You may use Vue.js with libraries like vuedraggable to implement drag-and-drop functionality for sorting categories.

I hope you understand Thank you.