Hướng tiếp cận dynamic_fields use post (ok)

Hướng tiếp cận cho tất cả post dạng chung

app\Http\Controllers\Admin\DynamicFieldController.php

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\DynamicField;
class DynamicFieldController extends Controller
{
  /**
   * Display a listing of the resource.
   */
  public function index()
  {
    $fields = DynamicField::orderBy('order')->get();
    return view('admin.dynamic-fields.index', compact('fields'));
  }
  /**
   * Show the form for creating a new resource.
   */
  public function create()
  {
    //
  }
  /**
   * Store a newly created resource in storage.
   */
  public function store(Request $request)
  {
    $request->validate([
      'label' => 'required',
      'name' => 'required|alpha_dash',
      'type' => 'required|in:text,textarea,image'
    ]);
    DynamicField::create($request->only(['label', 'name', 'type']));
    return back()->with('success', 'Thêm trường thành công');
  }
  /**
   * Display the specified resource.
   */
  public function show(string $id)
  {
    //
  }
  /**
   * Show the form for editing the specified resource.
   */
  public function edit(string $id)
  {
    //
  }
  /**
   * Update the specified resource in storage.
   */
  public function update(Request $request, string $id)
  {
    //
  }
  public function updateOrder(Request $request)
  {
    foreach ($request->order as $index => $id) {
      DynamicField::where('id', $id)->update(['order' => $index]);
    }
    return response()->json(['success' => true]);
  }
  /**
   * Remove the specified resource from storage.
   */
  public function destroy(string $id)
  {
    //
  }
}

app\Models\DynamicField.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DynamicField extends Model
{
  protected $fillable = [
    'label',
    'name',
    'type',
    'order'
  ];
}

resources\views\admin\dynamic-fields\index.blade.php

@extends('layouts.admin')
@section('content')
<div class="container">
  <h2>Quản lý Field</h2>
  @if(session('success'))
  <div class="alert alert-success">{{ session('success') }}</div>
  @endif
  <form method="POST" action="{{ route('dynamic-fields.store') }}">
    @csrf
    <div class="mb-3">
      <input type="text" name="label" placeholder="Nhãn" class="form-control">
      <input type="text" name="name" placeholder="Tên (slug)" class="form-control mt-2">
      <select name="type" class="form-control mt-2">
        <option value="text">Text</option>
        <option value="textarea">Textarea</option>
        <option value="image">Image</option>
      </select>
    </div>
    <button type="submit" class="btn btn-success">Thêm Field</button>
  </form>
  <ul id="sortable" class="list-group mt-4">
    @foreach ($fields as $field)
    <li class="list-group-item" data-id="{{ $field->id }}">
      {{ $field->label }} ({{ $field->type }})
    </li>
    @endforeach
  </ul>
</div>
@endsection
@push('scripts')
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
<script>
  $('#sortable').sortable({
    update: function(event, ui) {
      let order = $(this).sortable('toArray', {
        attribute: 'data-id'
      });
      $.post("{{ route('dynamic-fields.order') }}", {
        order: order
        , _token: "{{ csrf_token() }}"
      });
    }
  });
</script>
@endpush

routes\web.php

// Dynamic Fields
Route::prefix('admin')->group(function () {
  Route::get('dynamic-fields', [DynamicFieldController::class, 'index'])->name('dynamic-fields.index');
  Route::post('dynamic-fields', [DynamicFieldController::class, 'store'])->name('dynamic-fields.store');
  Route::post('dynamic-fields/order', [DynamicFieldController::class, 'updateOrder'])->name('dynamic-fields.order');
});

app\Models\DynamicField.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DynamicField extends Model
{
  protected $fillable = [
    'label',
    'name',
    'type',
    'order'
  ];
}

database\migrations\2025_06_01_191514_create_dynamic_fields_table.php

Schema::create('dynamic_fields', function (Blueprint $table) {
      $table->id();
      $table->string('label');
      $table->string('name');
      $table->string('type'); // text, textarea, image
      $table->integer('order')->default(0);
      $table->timestamps();
    });

database\migrations\2025_06_01_193317_create_posts_table.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
  /**
   * Run the migrations.
   */
  public function up(): void
  {
    Schema::create('posts', function (Blueprint $table) {
      $table->id();
      $table->string('title');
      $table->string('slug')->unique();
      $table->json('fields')->nullable();
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   */
  public function down(): void
  {
    Schema::dropIfExists('posts');
  }
};

app\Models\Post.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
  protected $casts = [
    'fields' => 'array',
  ];
  protected $fillable = ['title', 'slug', 'fields'];
}

app\Http\Controllers\Admin\PostController.php

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
  /**
   * Display a listing of the resource.
   */
  public function index()
  {
    $posts = Post::latest()->get();
    return view('admin.posts.index', compact('posts'));
  }
  /**
   * Show the form for creating a new resource.
   */
  public function create()
  {
    return view('admin.posts.create');
  }
  /**
   * Store a newly created resource in storage.
   */
  public function store(Request $request)
  {
    $request->validate([
      'title' => 'required|string|max:255',
      'slug' => 'required|string|max:255|unique:pages,slug',
    ]);
    Post::create([
      'title' => $request->title,
      'slug' => $request->slug,
      'fields' => $request->fields ?? [],
    ]);
    return redirect()->route('admin.posts.index')->with('success', 'Bài viết đã được tạo.');
  }
  /**
   * Display the specified resource.
   */
  public function show(Post $post)
  {
    //
  }
  /**
   * Show the form for editing the specified resource.
   */
  public function edit(Post $post)
  {
    //
  }
  /**
   * Update the specified resource in storage.
   */
  public function update(Request $request, Post $post)
  {
    $request->validate([
      'title' => 'required|string|max:255',
      'slug' => 'required|string|max:255|unique:posts,slug,' . $post->id,
    ]);
    $post->update([
      'title' => $request->title,
      'slug' => $request->slug,
      'fields' => $request->fields ?? [],
    ]);
    return redirect()->route('admin.posts.index')->with('success', 'Cập nhật thành công');
  }
  /**
   * Remove the specified resource from storage.
   */
  public function destroy(Post $post)
  {
    //
  }
}

Hướng tiếp cận cho tất cả post dạng riêng

app\Models\Post.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
  protected $casts = [
    'fields' => 'array',
  ];
  protected $fillable = ['title', 'slug', 'fields'];
  public function fieldGroup()
  {
    return $this->belongsTo(DynamicFieldGroup::class, 'field_group_id');
  }
}

app\Models\DynamicFieldGroup.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class DynamicFieldGroup extends Model
{
  public function fields()
  {
    return $this->hasMany(DynamicField::class, 'group_id');
  }
}

Last updated

Was this helpful?