Multi Select

screenshot

1MultiSelect::make()
2 ->min(1)
3 ->max(1)
4 ->searchable()
5 ->options(
6 Options::make([
7 Option::make('value', 'label'),
8 ...
9 ])
10 );
1@php
2 $options = [
3 [
4 'value' => 'arts',
5 'label' => 'Arts & Culture'
6 ],
7 [
8 'value' => 'finance',
9 'label' => 'Banking & Finance'
10 ],
11 [
12 'value' => 'civic',
13 'label' => 'Civic & Public'
14 ],
15 [
16 'value' => 'design',
17 'label' => 'Design & Architecture'
18 ],
19 [
20 'value' => 'education',
21 'label' => 'Education'
22 ]
23 ];
24@endphp
25 
26<x-twill::multi-select
27 name="sectors"
28 label="Sectors"
29 :min="1"
30 :max="1"
31 :options="$options"
32/>
1@formField('multi_select', [
2 'name' => 'sectors',
3 'label' => 'Sectors',
4 'min' => 1,
5 'max' => 2,
6 'options' => [
7 [
8 'value' => 'arts',
9 'label' => 'Arts & Culture'
10 ],
11 [
12 'value' => 'finance',
13 'label' => 'Banking & Finance'
14 ],
15 [
16 'value' => 'civic',
17 'label' => 'Civic & Public'
18 ],
19 [
20 'value' => 'design',
21 'label' => 'Design & Architecture'
22 ],
23 [
24 'value' => 'education',
25 'label' => 'Education'
26 ]
27 ]
28])
Option Description Type/values Default value
name Name of the field string
label Label of the field string
min Minimum number of selectable options integer
max Maximum number of selectable options integer
options Array of options for the dropdown, must include value and label array
unpack Defines if the multi select will be displayed as an open list of options boolean true
columns Aligns the options on a grid with a given number of columns integer 0 (off)
searchable Filter the field values while typing boolean false
taggable If new items can be added (only works with endpoint) boolean false
endpoint The url with the api to get options string
note Hint message displayed above the field string
placeholder Text displayed as a placeholder in the field string
required Displays an indicator that this field is required
A backend validation rule is required to prevent users from saving
boolean false
disabled Disables the field boolean false

There are several ways to implement a multi_select form field.

Multi select with static values

Sometimes you just have a set of values that are static.

In this case that it can be implemented as follows:

  • Create the database migration to store a JSON or LONGTEXT:
1Schema::table('posts', function (Blueprint $table) {
2 ...
3 $table->json('sectors')->nullable();
4 ...
5});
6 
7// OR
8Schema::table('posts', function (Blueprint $table) {
9 ...
10 $table->longtext('sectors')->nullable();
11 ...
12});
  • In your model add an accessor and a mutator:
1public function getSectorsAttribute($value)
2{
3 return collect(json_decode($value))->map(function($item) {
4 return ['id' => $item];
5 })->all();
6}
7 
8public function setSectorsAttribute($value)
9{
10 $this->attributes['sectors'] = collect($value)->filter()->values();
11}
  • Cast the field to array:
1protected $casts = [
2 'sectors' => 'array'
3]

Multi select with dynamic values

Sometimes the content for the multi_select is coming from another model.

In this case that it can be implemented as follows:

1php artisan twill:make:module sectors
  • Create a migration for a pivot table.
1php artisan make:migration create_post_sector_table
  • Use Twill's createDefaultRelationshipTableFields to set it up:
1public function up()
2{
3 Schema::create('post_sector', function (Blueprint $table) {
4 createDefaultRelationshipTableFields($table, 'sector', 'post');
5 $table->integer('position')->unsigned()->index();
6 });
7}
  • In your model, add a belongsToMany relationship:
1public function sectors() {
2 return $this->belongsToMany('App\Models\Sector');
3}
  • In your repository, make sure to sync the association when saving:
1public function afterSave($object, $fields)
2{
3 $object->sectors()->sync($fields['sectors'] ?? []);
4 
5 parent::afterSave($object, $fields);
6}
  • In your controller, add to the formData the collection of options:
1protected function formData($request)
2{
3 return [
4 'sectors' => app()->make(SectorRepository::class)->listAll()
5 ];
6}
  • In the form, we can now add the field:
1<x-twill::multi-select
2 name="sectors"
3 label="Sectors"
4 :options="$sectors"
5/>

When used in a block, no migration is needed.

Multi Select Inline

screenshot

1MultiSelect::make()
2 ->inline()
3 ->options(
4 Options::make([
5 Option::make('value', 'label'),
6 ...
7 ])
8 );
1@php
2 $options = [
3 [
4 'value' => 'arts',
5 'label' => 'Arts & Culture'
6 ],
7 [
8 'value' => 'finance',
9 'label' => 'Banking & Finance'
10 ],
11 [
12 'value' => 'civic',
13 'label' => 'Civic & Public'
14 ],
15 [
16 'value' => 'design',
17 'label' => 'Design & Architecture'
18 ],
19 [
20 'value' => 'education',
21 'label' => 'Education'
22 ]
23 ];
24@endphp
25 
26<x-twill::multi-select
27 name="sectors"
28 label="Sectors"
29 :unpack="false"
30 :options="$options"
31/>
1@formField('multi_select', [
2 'name' => 'sectors',
3 'label' => 'Sectors',
4 'unpack' => false,
5 'options' => [
6 [
7 'value' => 'arts',
8 'label' => 'Arts & Culture'
9 ],
10 [
11 'value' => 'finance',
12 'label' => 'Banking & Finance'
13 ],
14 [
15 'value' => 'civic',
16 'label' => 'Civic & Public'
17 ],
18 [
19 'value' => 'design',
20 'label' => 'Design & Architecture'
21 ],
22 [
23 'value' => 'education',
24 'label' => 'Education'
25 ]
26 ]
27])

See Multi select for more information on how to implement the field with static and dynamic values.