Dynamic Page Reordering with Laravel Livewire and Up/Down Arrows.
Enhance the visual appeal and organization of your website by incorporating a neatly arranged list/page/menu in the footer area. You have the option to display it in alphabetical order or based on unique identifiers. Strategically placing vital links at the top can captivate user attention, while the rest gracefully follow below. This practice is particularly beneficial when working on expansive projects, as it ensures that key links are showcased prominently and arranged in a meaningful order, contributing to a more engaging and user-friendly experience.
Reordering the list using Laravel Livewire
Here we are not using any Laravel packages for changing the position of the list. Just the arrows to move one step up or down to rearrange the position.
If you like to use the packages get any of them:
- Sortable jQuery UI drag-and-drop
- Sortable JS drag-and-drop
- Browser drag and drop
- Add sortable behavior to Laravel Eloquent models
- See the Livewire method to do the same
For this example, we are using the page model. So you have to add the position
column in the page table. $table->unsignedInteger()
because we do not want the negative numbers to be stored.
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pages', function (Blueprint $table) {
$table->id();
$table->unsignedInteger('position')->nullable();
$table->string('title');
$table->text('description');
$table->timestamps();
});
}
Make Livewire component: php artisan make:livewire page-list
Implement the logic:
// app/Http/Livewire/PageList.php
class PageList extends Component
{
public $pages = [];
public function mount()
{
$this->pages = Page::orderBy('position')->get();
}
public function moveUp($pageId)
{
$page = Page::find($pageId);
$previousPage = Page::where('position', '<', $page->position)->orderBy('position', 'desc')->first();
if ($previousPage) {
$tempPosition = $page->position;
$page->position = $previousPage->position;
$previousPage->position = $tempPosition;
$page->save();
$previousPage->save();
$this->pages = Page::orderBy('position')->get();
}
}
public function moveDown($pageId)
{
$page = Page::find($pageId);
$previousPage = Page::where('position', '>', $page->position)->orderBy('position', 'asc')->first();
if ($previousPage) {
$tempPosition = $page->position;
$page->position = $previousPage->position;
$previousPage->position = $tempPosition;
$page->save();
$previousPage->save();
$this->pages = Page::orderBy('position')->get();
}
}
public function render()
{
return view('livewire.page-list');
}
}
Create the blade view:
<table>
<thead>
<tr>
<th>Title</th>
<th>Position</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach ($pages as $page)
<tr>
<td>{{ $page->title }}</td>
<td>{{ $page->position }}</td>
<td>
@if ($page->position > 1)
<button wire:click="moveUp({{ $page->id }})">↑</button>
@endif
@if ($page->position < $pages->max('position'))
<button wire:click="moveDown({{ $page->id }})">↓</button>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>
Include the component in your view:
// In your main view or layout
<div>
@livewire('page-list')
</div>