winter icon indicating copy to clipboard operation
winter copied to clipboard

hasOne relation in NestedForm

Open AIC-BV opened this issue 3 months ago • 4 comments

Winter CMS Build

dev-develop

PHP Version

8.4

Database engine

MySQL/MariaDB

Plugins installed

No response

Issue description

The type: relationmanager has an 'update' button you have to click before you can edit the model. Which is why I want to render my relation in a nestedform. That way you can edit it straight away from the main model without having to click on the update button and edit the record in a popup.

Case 1: The issue I'm encountering is that the nestedform is not being filled in. I can fill in data manually and save the main record. This creates/updates a leadtracker record. But the data is never displayed when loading in the page.

Case 2: To solve the displaying issue, I edited my fields.yaml but now the nestedform does not save/create/update anymore.

Steps to replicate

Case 1: Nestedform is not being filled in

public function boot()
    {
        UserModel::extend(function ($model) {

            // add relation
            $model->hasOne['leadtracker'] = ['Aic\LeadTracker\Models\Lead'];

            // // fill in the fields (because we use nestedForm instead of relationManager)
            // $model->bindEvent('model.form.filterFields', function ($formWidget, $fields, $context) use ($model) {

            //     $lead = $model->leadtracker;
            //     dd($fields->leadtracker);
            //     if ($lead) $fields->leadtracker->value = $lead->getAttributes();

            // });

        });

        UsersController::extendFormFields(function ($form, $model, $context) {

            // return if...
            if ($form->isNested) return;
            if (!$model instanceof UserModel) return;
            if (!$model->exists) return;
            if ($form->getContext() == 'create') return;
            
            // add fields
            $form->addTabFields([
                '_leadtracker_fields' => [
                    'tab' => 'aic.leadtracker::lang.title',
                    'type' => 'nestedform',
                    'usePanelStyles' => false,
                    'form' => '~/plugins/aic/leadtracker/models/lead/fields.yaml'
                ]
            ]);

            // // works but there is an "update" button
            // $form->addTabFields([
            //     'leadtracker' => [
            //         'tab' => 'aic.leadtracker::lang.title',
            //         'type' => 'relationmanager',
            //     ]
            // ]);
        });
    }
fields:
    from:
            label: aic.leadtracker::lang.from.title
            type: balloon-selector
            options: aic.leadtracker::lang.from.options
            default: 'kleurstalen'
            span: storm
            cssClass: col-xs-6
    log:
            type: repeater
            titleFrom: contacted_at
            style: collapsed
            span: storm
            cssClass: col-xs-12
            form:
                fields:
                    type:
                        label: aic.leadtracker::lang.log.type.title
                        type: balloon-selector
                        options: aic.leadtracker::lang.log.type.options
                        default: 'Call'
                        span: storm
                        cssClass: col-xs-12
                    ...
                    ...

Case 2: Nestedform is filled in but does not create/save anymore

$form->addTabFields([
    '_leadtracker' => [
        'tab' => 'aic.leadtracker::lang.title',
        'type' => 'nestedform',
        'usePanelStyles' => false,
        'form' => '~/plugins/aic/leadtracker/models/lead/fields_nestedform.yaml'
    ]
]);
fields:

    leadtracker[from]:
        label: aic.leadtracker::lang.from.title
        type: balloon-selector
        options: aic.leadtracker::lang.from.options
        default: 'kleurstalen'
        span: storm
        cssClass: col-xs-6
      ...
      ...

AIC-BV avatar Sep 26 '25 10:09 AIC-BV

$model->bindEvent('model.afterFetch', function () use ($model) {
    dd($model->leadtracker->attributes);
});
Image All data is filled in...

Yet the form remains empty

Image

AIC-BV avatar Sep 29 '25 08:09 AIC-BV

$model->bindEvent('model.form.filterFields', function ($formWidget, $fields, $context) use ($model) {
                
    if (isset($fields->leadtracker)) {
        $lead = $model->leadtracker;
        $fields->leadtracker->value = $lead->getAttributes();
        $fields->leadtracker->attributes = $lead->getAttributes();
        // dd($fields->leadtracker);
    }

});

This sets the value & attributes but does not fill in the form either

AIC-BV avatar Sep 29 '25 08:09 AIC-BV

The OCMS documentation shows a variable https://octobercms.com/docs/api/backend/formwidgets/nestedform#userelation but its not on WCMS which probably fixes this issue...

AIC-BV avatar Sep 29 '25 08:09 AIC-BV

Praise the lord Found the workaround... Avoid the NestedForm and add each field individually (or modify and parse YAML to add them all in one line, creating 2 'field' files. One for the relation, one for the model)

UsersController::extendFormFields(function ($form, $model, $context) {
    ...
    $form->addTabFields(Yaml::parseFile(plugins_path('aic/leadtracker/models/lead/fields_nestedform.yaml')));
}
leadtracker[from]:
    tab: aic.leadtracker::lang.title
    label: aic.leadtracker::lang.from.title
    type: balloon-selector
    options: aic.leadtracker::lang.from.options
    default: 'kleurstalen'
    span: storm
    cssClass: col-xs-6

AIC-BV avatar Sep 29 '25 09:09 AIC-BV