Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Filament: Custom Page to Edit a Single Record [2024]

You must be very familiar with the Filament for CRUD operation in the resources. It’s very easy, isn’t it? But what about Editing a Single Record without updating the entire resource? Let’s get started with some basic information.

In this example, I will be making an Edit General Settings custom page for my Laravel application.

Before starting the whole process here is how the final output is going to look.

Custom Page to Edit a Single Record

Prepare a Custom Page

Creating a custom page rather than a full resource is sometimes very useful when you only have one piece of data. You can pick these individually (packages) and use them directly in your Livewire components, even without the whole Filament framework. This lets you build custom interfaces without needing the full Filament setup. Think of it like Lego bricks for your Livewire projects!

To start, create a custom page using the following artisan command:

 php artisan make:filament-page EditGeneralSettings --type=custom

Remember, when making a custom page, don’t specify any associated Resource just hit enter.

Now, implement the necessary interface and add a trait to enable Filament forms in your custom page class (EditGeneralSettings):

use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Concerns\InteractsWithForms;

class EditGeneralSettings extends Page implements HasForms {
  use InteractsWithForms;
}

Your custom page can now seamlessly use Filament Forms. Let’s proceed by adding a form to this page:

app/Filament/Pages/EditGeneralSettings.php:

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;

class EditGeneralSettings extends Page implements HasForms {
  use InteractsWithForms;
  
  public ?array $data = [];
  
  // ... (Other properties)

  public function form(Form $form): Form {
    return $form
      ->schema([
        TextInput::make('name')->required(),
      ])
      ->statePath('data');
  }
}

Now, we need to render the form in the Blade file.

resources/views/filament/pages/edit-general-settings.blade.php:

<x-filament-panels::page>
  <x-filament-panels::form>
    {{ $this->form }}
  </x-filament-panels::form>
</x-filament-panels::page>

After visiting the Edit General Settings page, you’ll be greeted with an empty form with one text input box, ready for further customization.

Filling and Submitting the Form

Before proceeding with filling and submitting the form, let’s populate the form input with General Settings. For that, firstly you will need to import your model.

app/Filament/Pages/EditGeneralSettings.php:

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use App\Models\GeneralSettings;


class EditGeneralSettings extends Page implements HasForms {
  use InteractsWithForms;
  
  public ?array $data = [];

  public GeneralSettings $post;

  public $name= '';

  // ... (Other properties)

  public function form(Form $form): Form {
    return $form
      ->schema([
        TextInput::make('name')->required(),
      ])
      ->statePath('data');
  }
}

Update the mount method in the EditGeneralSettings class:

app/Filament/Pages/EditGeneralSettings.php:

use Filament\Forms\Form;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Concerns\InteractsWithForms;
use App\Models\GeneralSettings;


class EditGeneralSettings extends Page implements HasForms {
  use InteractsWithForms;
  
  public ?array $data = [];

  public GeneralSettings $post;

  public $name= '';

  // ... (Other properties)

 public function mount(): void
    {
        // Retrieve the most recently created or updated record
        $this->post = GeneralSettings::latest()->firstOrNew();

        // Fill the form with data
        $this->form->fill($this->post->toArray());
    }

  public function form(Form $form): Form {
    return $form
      ->schema([
        TextInput::make('name')->required(),
      ])
      ->statePath('data');
  }
}

Now, let’s add a submit button to the form:

app/Filament/Pages/EditGeneralSettings.php:

use Filament\Actions\Action;

class EditGeneralSettings extends Page implements HasForms {

  // ... (Other methods)

    protected function getFormActions(): array
    {
        return [
            Action::make('save')
                ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
                ->submit('save'),
        ];
    }
}

resources/views/filament/pages/edit-general-settings.blade.php:

<x-filament-panels::page>
  <x-filament-panels::form>
    {{ $this->form }}
    <x-filament-panels::form.actions :actions="$this->getFormActions()" />
  </x-filament-panels::form>
</x-filament-panels::page>

Upon revisiting the Edit Company page, you’ll notice the form is now populated with the latest data if available, with a submit button.

Updating Data and Adding Notifications

The final steps involve updating the general settings data and adding a success notification message. Implement the save method in the EditGeneralSettings class:

app/Filament/Pages/EditGeneralSettings.php:

use Filament\Support\Exceptions\Halt;
use Filament\Notifications\Notification;

class EditGeneralSettings extends Page implements HasForms
{
  // ... (Other methods)
public function save(): void
    {
        try {
            $GeneralSettings = GeneralSettings::latest()->firstOrNew(); // Retrieve the most recently created or updated record, or instantiate a new one

            $GeneralSettings->fill($this->form->getState()); // Fill the model with form data

            $GeneralSettings->save(); // Save the model to the database

        } catch (Halt $exception) {
            return;
        }
        Notification::make()
            ->success()
            ->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'))
            ->send();

    }
}

Update the Blade file to include the wire:submit directive.

resources/views/filament/pages/edit-general-settings.blade.php:

<x-filament-panels::page>
    <x-filament-panels::form wire:submit="save">
        {{ $this->form }}

        <x-filament-panels::form.actions :actions="$this->getFormActions()" />
    </x-filament-panels::form>
</x-filament-panels::page>

Now, upon successful submission, a notification will be displayed, signaling the data of the general settings is updated. If no data was previously available new record will be automatically added.

Final Codes :

app/Filament/Pages/EditGeneralSettings.php:

<?php

namespace App\Filament\Pages;

use App\Models\GeneralSettings;
use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Actions\Action;
use Filament\Support\Exceptions\Halt;
use Filament\Notifications\Notification;


class EditGeneralSettings extends Page implements HasForms
{
    use InteractsWithForms;

    public ?array $data = [];

    protected static string $view = 'filament.pages.general-settings';

    public GeneralSettings $post;

    public $site_title = '';

    public function mount(): void
    {

        // Retrieve the most recently created or updated record
        $this->post = GeneralSettings::latest()->firstOrNew();

        // Fill the form with data
        $this->form->fill($this->post->toArray());


    }

    public function form(Form $form): Form
    {

        return $form
            ->schema([
                TextInput::make('name')
                    ->required(),
            ])->statePath('data');
    }

    protected function getFormActions(): array
    {
        return [
            Action::make('save')
                ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label'))
                ->submit('save'),
        ];
    }

    public function save(): void
    {
        try {
            $GeneralSettings = GeneralSettings::latest()->firstOrNew(); // Retrieve the most recently created or updated record, or instantiate a new one

            $GeneralSettings->fill($this->form->getState()); // Fill the model with form data

            $GeneralSettings->save(); // Save the model to the database

        } catch (Halt $exception) {
            return;
        }
        Notification::make()
            ->success()
            ->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title'))
            ->send();

    }

}

resources/views/filament/pages/edit-general-settings.blade.php:

<x-filament-panels::page>
    <x-filament-panels::form wire:submit="save">
        {{ $this->form }}

        <x-filament-panels::form.actions :actions="$this->getFormActions()" />
    </x-filament-panels::form>
</x-filament-panels::page>

GeneralSettings Migration:

<?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('general_settings', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('general_settings');
    }
};

Conclusion

This guide crafted a unique edit form for one record, just for you! No more cookie-cutter solutions. Follow the steps, customize to your heart’s content, and say goodbye to clunky workflows. Love Filament? Comment below! 😄

Leave a Comment