Twill: Select options using getFormFields

Created on 5 Feb 2019  路  9Comments  路  Source: area17/twill

Hi,

Love twill, and making some good progress on my first project using the package - thank you for the hard work.

I have successfully added browser fields to modules and am reasonably confident in their use. I'm now looking to add a select field which can be used to save a belongsTo relationship.

If possible I'm looking for an example or guidance on using getFormFields to get an modules' items into the select options array, and then save the user selection in the relationship table.

Thanks

documentation

Most helpful comment

I found select fields to be quite nice to work with. You just need to define the data available to your form view. An example of a one-to-many relationship could look like this:

The model defining the relationship:

class Lesson extends Model
{
    protected $fillable = [
        'title',
        'level_id',
    ];

    public function level()
    {
        return $this->belongsTo(Level::class);
    }
}

The controller populating the form data:

class LessonController extends ModuleController
{
    /*
     * Relations to eager load for the form view
     * Add relationship used in multiselect and resource form fields
     */
    protected $formWith = [
        'level'
    ];

    /*
     * Add anything you would like to have available in your module's form view
     * For example, relationship lists for multiselect form fields
     */
    protected function formData($request)
    {
        return [
            'levelList' => app(LevelRepository::class)->listAll()
        ];
    }
}

And the form itself populating the select:

@section('contentFields')
    @formField('select', [
        'name' => "level_id",
        'label' => "Level",
        'native' => true,
        'options' => $levelList,
        'placeholder' => 'Select a level',
    ])
@stop

All 9 comments

I found select fields to be quite nice to work with. You just need to define the data available to your form view. An example of a one-to-many relationship could look like this:

The model defining the relationship:

class Lesson extends Model
{
    protected $fillable = [
        'title',
        'level_id',
    ];

    public function level()
    {
        return $this->belongsTo(Level::class);
    }
}

The controller populating the form data:

class LessonController extends ModuleController
{
    /*
     * Relations to eager load for the form view
     * Add relationship used in multiselect and resource form fields
     */
    protected $formWith = [
        'level'
    ];

    /*
     * Add anything you would like to have available in your module's form view
     * For example, relationship lists for multiselect form fields
     */
    protected function formData($request)
    {
        return [
            'levelList' => app(LevelRepository::class)->listAll()
        ];
    }
}

And the form itself populating the select:

@section('contentFields')
    @formField('select', [
        'name' => "level_id",
        'label' => "Level",
        'native' => true,
        'options' => $levelList,
        'placeholder' => 'Select a level',
    ])
@stop

Dear Philipp,

I appreciate you taking the time to share your example. I have implemented a couple of select fields and they are working as described - thanks.

Additional Q: If I were to add a select field inside a repeater is there a controller where I could retrieve relationship information for a model and get the select options the same way?

Thanks

Haven't really had to work with repeaters yet. The source code of the HandleRepeaters trait and its getFormFieldsForRepeater method might help. The docs have a section on implementing these methods inside your repositories. Might be off on a wrong path here, though, so best if someone at area17 chipped in.

Hi @layout-lab @philippdaun

Considering that repeaters and blocks forms are generated Vue components, initializing values from dynamic content is not viable from the original Blade file.

However, I think 2 ways are possible:

  • using the remote (ajax) option of the vselect component under our select field. This should be working already, I'll have to check.
  • implementing in Twill a way to init repeaters fields from values provided in their corresponding module controller's formData function.

even the guide to place the selected option is not in the documentation :(

Our upcoming updates to the documentation include implementation details for each form field and compatibility with its context (form, block, repeater, repeater in a block, settings). Thanks for sharing your snippets @philippdaun!

@philippdaun , following this as need to implement something similar but when I setup...

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

I get the following error:

Method AppHttpControllersAdminPropertyController::listAll does not exist.

What do I need to declare to get access to listAll() ?

It looks like you are resolving a controller for some reason, not the repository which has the listAll method.

Doh! Inded that was it. Cheers ;)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

milewski picture milewski  路  4Comments

dafyd picture dafyd  路  3Comments

manuelsofia picture manuelsofia  路  4Comments

madsem picture madsem  路  4Comments

newvladimirov picture newvladimirov  路  3Comments