In this part, we will make categories "reorderable" with drag-drop behavior.

In this part, we will make categories "reorderable" with drag-drop behavior.

While you follow along and encountred some errors as I did, I suggest you to make some amendments.
To seed position rows. Amend in CategoryFactory.php:
ublic function definition(): array
{
$country = fake()->unique()->country();
return [
'name' => $country,
'slug' => Str::slug($country),
'position' => fake()->numberBetween(1, 10),
];
}
Import namespace in CategoriesList.php
use Illuminate\Support\Collection;
For better UX and Web accessibility aspect, change buton cursor class to cursor-move in categories-list.blade.php:
<button wire:sortable.handle class="cursor-move">
// ...
</button>
Where and how can we dump $list array to see what's inside?
If we paginate 10 the $categories per page, how can we drag and drop 11 category to the first position?
If an item will be positioned in another page than page 1, order number begins from 1. This causes that there are 2 categories with the same position number. The refactoring in CategoriesList helped me to achieve the problem.
class CategoriesList extends Component
{
// ...
public $currentPage = 1;
public $perPage = 10;
// ...
public function updateOrder($list)
{
foreach ($list as $item) {
$cat = $this->categories->firstWhere('id', $item['value']);
$order = $item['order'] + (($this->currentPage - 1) * $this->perPage);
if ($cat['position'] != $order) {
Category::where('id', $item['value'])->update(['position' => $order]);
}
}
}
// ...
public function render()
{
$cats = Category::orderBy('position')->paginate($this->perPage);
$links = $cats->links();
$this->currentPage = $cats->currentPage();
$this->categories = collect($cats->items());
// ...
}
CategoryFactory position will increase in order.
public function definition(): array
{
$name = $this->faker->sentence(5);
static $position = 1;
return [
'name' => $name,
'slug' => function (array $attributes) {
return Str::slug($attributes['name']);
},
'is_active' => $this->faker->boolean,
'position' => $position++
];
}
```
foreach ($list as $item) {
$cat = $this->categories->firstWhere('id', $item['value']);
if ($cat['position'] != $item['order']) {
Category::where('id', $item['value'])->update(['position' => $item['order']]);
}
}
Why did you not use the variable $cat inside the if? Why did you fetch Category::where...? I assume there are some advantages but i can't figure it out.
It is used inside the if, but you might be confusing this because it looks like a database query.
The $cat variable comes from a collection, not the databse in this case (it's missing the categories()) and that makes it work with the data that is already loaded as a relationship.
hi dos the 'position' in categories table migration had to be nullable by default.it is showing error when i migrate:fresh and insert seed data
I think by default its value is 0, but can't guarantee: what is the actual error test and what seed data are you using?
I made the position default to 9999, so new Categories will be at the end. Or if you default to 0 it will be very first category