Reputation: 829
In my custom CMS I have created CRUD menu and in the frontend I'm displaying it successfully.
Now I'm trying to find any solution to change order by dragging these menu items in the admin section, but still no luck. Does anyone knows how to achieve this with Laravel? Also I use third party Laravel translatable, so I'll explain in my following code:
Menu model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Dimsav\Translatable\Translatable;
class Menu extends Model
{
use Translatable;
public $translatedAttributes = ['title', 'url', 'status'];
}
MenuTranslation model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MenuTranslation extends Model
{
//
}
create_menus_table migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMenusTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('menus', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('menus');
}
}
create_menus_translations_table migration:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMenuTranslationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('menu_translations', function (Blueprint $table) {
$table->increments('id');
$table->integer('menu_id')->unsigned();
$table->string('locale')->index();
// The actual fields to store the content of your entity. You can add whatever you need.
$table->string('title');
$table->string('url')->nullable();
$table->string('status');
$table->unique(['menu_id', 'locale']);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('menu_translations');
}
}
My view index menu:
@extends('layouts.admin')
@section('content')
@if(session()->has('success_message'))
<div class="alert alert-success">
{{ session()->get('success_message') }}
</div>
@endif
<h1>Users</h1>
<a class="btn btn-primary" href="{{ route('menus.create') }}">Create new menu</a>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Status</th>
<th>Created</th>
<th>Operations</th>
</tr>
</thead>
<tbody>
@foreach($menus as $menu)
<tr>
<td>{{ $menu->id }}</td>
<td>{{ $menu->title }}</td>
<td>{{ $menu->status ? 'Active' : 'Disabled' }}</td>
<td>{{ $menu->created_at->diffForHumans() }}</td>
<td>
<a class="btn btn-primary btn-edit" href="{{ route('menus.edit' , $menu->id) }}">Edit</a>
<form action="{{ route('menus.destroy', $menu->id) }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<input type="submit" class="btn btn-danger btn-delete" value="Delete">
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection
As you can see in the view menu index I'm displaying the created menu items. The key is to use some js and Ajax I guess and with dragging to change the id's in the menus table or to create a new column in the database (order).
So, the question again is: how can I drag these menu items and change order in the database by using Laravel?
Upvotes: 4
Views: 6309
Reputation: 829
I've finally solved the problem!
I'm using this plugin for Laravel: https://github.com/boxfrommars/rutorika-sortable
It's great for sorting eloquent. With some tweaks, lot of reading and testing, now it works great. :)
Upvotes: 2
Reputation: 602
Well, it is all not laravel specific question but here is the answer.
So, For the frontend part, you'll need to use a plugin for Drag and Drop. E.g. Sortable
Sortable plugin gives you all the events of drag and drop. So you can simply create a hidden field or just create a variable in the javascript and pass that sorted value in the POST request when click on save function.
Now, you will need to add that data in a table sorted by menu_id
.
And by clicking on save order, you will send all the newly ordered elements with their respective id.
And on the backend side, you will just need to loop through and update those elements.
Like this:
foreach($newSort as $key => $value):
$menuTranslation = MenuTranslation::findOrFail($key);
$menuTranslation->update(['menu_id' => $value]);
@endforeach;
All the best.
Upvotes: 3