nova-flexible-content icon indicating copy to clipboard operation
nova-flexible-content copied to clipboard

The dependent field disappears when dependent on an external field.

Open fenestron opened this issue 3 years ago • 3 comments

Code example:

Text::make('Recipient')
    ->readonly()
    ->dependsOn(
        ['type'],
        function (Text $field, NovaRequest $request, FormData $formData) {
            if ($formData->type === 'gift') {
                $field->readonly(false)->rules(['required', 'email']);
            }
        }
    ),

Flexible::make('Content')
    ->addLayout('Simple content section', 'wysiwyg', [
        Text::make('Recipient')
            ->readonly()
            ->dependsOn(
                ['type'],
                function (Text $field, NovaRequest $request, FormData $formData) {
                    if ($formData->type === 'gift') {
                        $field->readonly(false)->rules(['required', 'email']);
                    }
                }
            ),
    ]),

Select::make('Purchase Type', 'type')
    ->options([
        'personal' => 'Personal',
        'gift' => 'Gift',
    ])
    ->default('personal'),

Field behavior:

Laravel - Create Test

P.S. Example taken from documentation

fenestron avatar Apr 13 '22 15:04 fenestron

Related #338

fenestron avatar Apr 13 '22 16:04 fenestron

The fixes from the related issue stop the field from disappearing. But I'm not yet sure how to have Flexible content fields dependant on external fields.

Nova uses a unique form id for the base form, which has to then be set uniquely again on a per-repeated-layout basis. As such fields in the base form will have a different unique id to fields in any repeated layout, and won't listen for the change event.

Unsure if there is a simple way to remedy this as it's really just a symptom of things working as expected (ensuring you changing the dropdown on Layout 2 doesn't affect the dependant field on Layout 1 for example).

Initial thoughts are that it might be out of scope, but that's a decision for the maintainers.

ianrobertsFF avatar Apr 15 '22 22:04 ianrobertsFF

For a similar issue, like toggling read only, I used the Nova Dependency Container package to get around.

Fields\Boolean::make('Modifier?', 'sync_websites')
    ->hideWhenCreating()
    ->showOnUpdating(fn() => $this->model()->isWriteable('websites')),

DependencyContainer::make([
    // Readonly
    Flexible::make('Sites web', 'websites')
        ->addLayout(...Layouts\Websites::make($this->model(), readonly: true))
        ->limit(0)
        ->hideFromIndex(),
])->dependsOnIn('sync_websites', [false, null]),

DependencyContainer::make([
    // User wants to edit
    Flexible::make('Sites web', 'websites')
        ->addLayout(...Layouts\Websites::make($this->model()))
        ->limit(20)
        ->button('Ajouter un site web')
        ->hideFromIndex(),
])->dependsOn('sync_websites', true),

Please bare in mind I added some custom code, like the Layouts\Websites::make(...$args) is a wrapper for the Layout class from this package. The readonly argument allows to add the readonly() call on all Layout Fields.

Also, my sync_website Bool field is automatically discarded in a ModelObserver during the saving model event.

phlisg avatar Dec 15 '22 13:12 phlisg