skip to Main Content

I need to customize some Laravel Filament v3 Resource Form Fields/Elements by the current page type index/create/edit/view. For example, hide some action Fields on a view page.

Resource PHP file (Bar)

<?php
namespace AppFilamentResources;

use AppFilamentResourcesBarResourcePages;
use FilamentFormsComponentsTextInput;
use FilamentFormsForm;

class BarResource extends FilamentResourcesResource
{
    public static function getPages(): array
    {
        return [
            'index' => PagesListBars::route('/'),
            'create' => PagesCreateBar::route('/create'),
            'edit' => PagesEditBar::route('/{record:uuid}/edit'),
            'view' => PagesViewBar::route('/{record:uuid}/view'),
        ];
    }
    
    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                TextInput::make('name')
                    ->hidden(function () {
                        //do something in cases of edit/view states, something like $state
                        /*switch ($state) {
                            case 'view':
                                return true;
                                break;
                        }*/
                    }),
            ]);
    }
}

Any ideas how to implement switching (get current) resource page type in a form?

2

Answers


  1. Chosen as BEST ANSWER

    💡 I got an ideas that solves the issue.

    Examples below are based on edit context. ⚠️ Keep in mind: also you have to make it with create/view/index contexts. Let's create a public property $crud that determines wich context is backed in a given resource class.

    1️⃣ VIA MIDDLE CLASSES

    1. CreateRecord class

      AppOverrideFilamentResourcesPagesCreateRecord

    2. EditRecord class

      AppOverrideFilamentResourcesPagesEditRecord

    3. ViewRecord class

      AppOverrideFilamentResourcesPagesViewRecord

    4. ListRecords class

      AppOverrideFilamentResourcesPagesListRecords

    EditRecord child class

    appOverrideFilamentResourcesPagesEditRecord.php

    <?php
    namespace AppOverrideFilamentResourcesPages;
    
    use FilamentResourcesPagesEditRecord as BaseEditRecord;
    
    class EditRecord extends BaseEditRecord
    {
        public string $crud = 'edit';
    }
    

    Bar Edit

    appFilamentResourcesBarResourcePagesEditBar.php

    <?php
    namespace AppFilamentResourcesBarResourcePages;
    
    use AppOverrideFilamentResourcesPagesEditRecord;
    
    class EditBar extends EditRecord
    {
        //your edit resource code
    }
    

    2️⃣ VIA TRAITS

    1. CreateRecord trait

      AppTraitsFilamentResourcesPagesCreateRecord

    2. EditRecord trait

      AppTraitsFilamentResourcesPagesEditRecord

    3. ViewRecord trait

      AppTraitsFilamentResourcesPagesViewRecord

    4. ListRecords trait

      AppTraitsFilamentResourcesPagesListRecords

    EditRecord trait

    appTraitsFilamentResourcesPagesEditRecord.php

    <?php
    
    namespace AppTraitsFilamentResourcesPages;
    
    trait EditRecord
    {
        public $crud = 'edit';
    }
    

    Bar Edit

    appFilamentResourcesBarResourcePagesEditBar.php

    <?php
    namespace AppFilamentResourcesBarResourcePages;
    
    use FilamentResourcesPagesEditRecord;
    
    class EditBar extends EditRecord
    {
        //our trait
        use AppTraitsFilamentResourcesPagesEditRecord;
        
        //your edit resource code
    }
    

    💯 RESULT 💎

    Bar Resource

    appFilamentResourcesBarResource.php

    Now you can switch $form->getLivewire()->crud to get a current form context.

    <?php
    namespace AppFilamentResources;
    
    use FilamentFormsForm;
    use FilamentResourcesResource;
    
    class BarResource extends Resource
    {
        //your code...
        
        public static function form(Form $form): Form
        {
            $context = $form->getLivewire()->crud;
            return $form
                ->schema([
                    TextInput::make('name')
                        ->hidden(function () use ($context) {
                            switch ($context) {
                                case 'edit':
                                    //code for edit
                                    break;
                                case 'view':
                                    //code for view
                                    break;
                            }
                        }),
                ]);
        }
    }
    

  2. Great that you solve the problem, and nice to see to achieve this with flexible method.

    On the other hand though, there are two ways available by Filament.

    First:

    ->hidden(fn($operation) => $operation == 'view')
    

    or

    ->visible(fn($operation) => $operation == 'edit')
    

    Read more from the Docs

    Second:

    ->hiddenOn('edit')
    

    or

    ->visibleOn('create')
    

    Read more from the Doc

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search