Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi select with dynamic values doesn't load selected values on page edit #2622

Closed
shabaz-ejaz opened this issue Jun 25, 2024 · 4 comments
Closed

Comments

@shabaz-ejaz
Copy link

Description

When using Multi select with dynamic values, I have got the data saving fine, however when reloading the form, the selected values are not being checked in the form by default.

Steps to reproduce

I have a pivot table which joins a pianos table with itself to create 'comparable_pianos'.

Pivot model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class PianoComparable extends Model
{
    protected $table = 'piano_comparables';

    protected $fillable = [
        'piano_id',
        'comparable_piano_id',
    ];

    // Define the relationship with the Piano model
    public function piano()
    {
        return $this->belongsTo(Piano::class, 'piano_id');
    }

    // Define the relationship with the Comparable Piano model (same Piano model)
    public function comparablePiano()
    {
        return $this->belongsTo(Piano::class, 'comparable_piano_id');
    }
}

PianoController:

<?php

namespace App\Http\Controllers\Admin;

use A17\Twill\Http\Controllers\Admin\ModuleController;
use App\Models\Piano;
use App\Models\PianoComparable;
use App\Repositories\PianoRepository;
class PianoController extends ModuleController
{
    protected $moduleName = 'pianos';


    protected $indexOptions = [
        'create' => true,
        'edit' => true,
        'publish' => true,
        'duplicate' => true,
        'bulkPublish' => true,
        'feature' => false,
        'bulkFeature' => false,
        'restore' => true,
        'bulkRestore' => true,
        'delete' => true,
        'bulkDelete' => true,
        'reorder' => true,
        'permalink' => true,
        'bulkEdit' => true,
        'editInModal' => false,
        'forceDelete' => true,
        'bulkForceDelete' => true,
    ];

    protected function formData($request)
    {
        return [
            'comparable_pianos' => app()->make(PianoRepository::class)->listAll()
        ];
    }

}

PianoRepository:

<?php

namespace App\Repositories;

use A17\Twill\Repositories\Behaviors\HandleBlocks;
use A17\Twill\Repositories\Behaviors\HandleSlugs;
use A17\Twill\Repositories\Behaviors\HandleMedias;
use A17\Twill\Repositories\Behaviors\HandleFiles;
use A17\Twill\Repositories\Behaviors\HandleRevisions;
use A17\Twill\Repositories\ModuleRepository;
use App\Models\Piano;

class PianoRepository extends ModuleRepository
{
    use HandleBlocks, HandleSlugs, HandleMedias, HandleFiles, HandleRevisions;

    public function __construct(Piano $model)
    {
        $this->model = $model;
    }

    public function afterSave($object, $fields)
    {
        $object->comparablePianos()->sync($fields['comparable_pianos'] ?? []);

        parent::afterSave($object, $fields);
    }

}

Blade file:


// omitted irrelevant form data

@formField('multi_select', [
    'name' => 'comparable_pianos',
    'label' => 'Comparable Pianos',
    'options' => $comparable_pianos
    ])

Expected result

I expect the multiselect to have pre-selected values based on the ones in the database on form edit. However I only ever see the options with all of them unchecked.

Actual result

The values do save in the database, however are not shown as selected when reading from the table int he form.

Screenshot 2024-06-25 at 12 04 18

Versions

Twill version: 2.0.1
Laravel version: 7.30.6
PHP version: 7.4.33
Database engine: MySQL InnoDB

@zeezo887
Copy link
Collaborator

zeezo887 commented Jul 1, 2024

@shabaz-ejaz I see the relation's name in your Piano model is called comparablePianos but in the multi-select field it is in snake-case comparable_pianos.
Twill uses eager loading when accessing model relationships so, $item>comparable_pianos would return null because it is not a property of the Piano model. Updating your multi-select field to

@formField('multi_select', [
  'name' => 'comparablePianos',
  'label' => 'Comparable Pianos',
  'options' => $comparable_pianos
])

will work fine

@shabaz-ejaz
Copy link
Author

@zeezo887 Thanks, I've tried that and now it doesn't actually save the the values in the pivot table.

Weirdly it did save when I have it like this:

@formField('multi_select', [
    'name' => 'comparable_pianos',
    'label' => 'Comparable Pianos',
    'options' => $comparable_pianos2,
    ])

@zeezo887
Copy link
Collaborator

zeezo887 commented Jul 1, 2024

@shabaz-ejaz you should update your PianoRepository too

public function afterSave($object, $fields)
    {
        $object->comparablePianos()->sync($fields['comparablePianos'] ?? []);

        parent::afterSave($object, $fields);
    }

@shabaz-ejaz
Copy link
Author

@zeezo887 That's what it was! That works great now thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants