Fields

Select

Basics

The Select field includes all basic methods for creating a field.

use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
<x-moonshine::form.wrapper label="Country">
<<x-moonshine::form.select>
<x-slot:options>
<option value="1">Option 1</option>
<option selected value="2">Option 2</option>
</x-slot:options>
</x-moonshine::form.select>
</x-moonshine::form.wrapper>

select

Default value

You can use the default() method if you need to specify a default value for the field.

default(mixed $default)
use MoonShine\UI\Fields\Select;
 
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
->default('value 2')

You can also specify options via the Options object:

Select::make('Select')->options(
new Options([
new Option(label: 'Option 1', value: '1', selected: true, properties: new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
new Option(label: 'Option 2', value: '2', properties: new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
]
)
)

Nullable

As with all fields, if you need to store NULL, you need to add the nullable() method.

nullable(Closure|bool|null $condition = null)
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
->nullable()

select nullabledark

Placeholder

The placeholder() method allows you to set the placeholder attribute for the field.

placeholder(string $value)
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country')
->nullable()
->placeholder('Country')

Groups

You can group values together.

use MoonShine\UI\Fields\Select;
 
Select::make('City', 'city_id')
->options([
'Italy' => [
1 => 'Rome',
2 => 'Milan'
],
'France' => [
3 => 'Paris',
4 => 'Marseille'
]
])
Select::make('City')->options(
new Options([
new OptionGroup('Italy', new Options([
new Option('Rome', '1'),
new Option('Milan', '2'))
])),
 
new OptionGroup('France', new Options([
new Option('Paris', '3'),
new Option('Marseille', '4')
]))
])
),

select group dark

Multiple values selection

To enable multiple values selection, use the multiple() method.

multiple(Closure|bool|null $condition = null)
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
->multiple()
}
 
//...

When using multiple() for Eloquent models, it is necessary to use the text or json type in the database. Also, you need to add cast - json, array, collection.

select multiple dark.

If you need to add search functionality among values, then you need to add the searchable() method.

searchable()
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
->searchable()

searchable

Asynchronous search

The Select field can also be set up for asynchronous searching. To do this, you need to pass a url to the async() method, which will handle a request with the query parameter for the search.

async(Closure|string|null $url = null, string|array|null $events = null, ?AsyncCallback $callback = null)
  • $url - url or function to handle the asynchronous request.
  • $events - list of events after the request has been executed (need a link to the events section).
  • $callback - Callback after the request has been executed.

The parameters $events and $callback are not mandatory.

The response returned with the search results must be in json format.

[
{
"value": 1,
"label": "Option 1"
},
{
"value": 2,
"label": "Option 2"
}
]

You can also use the Options object:

public function selectOptions(): MoonShineJsonResponse
{
$options = new Options([
new Option(label: 'Option 1', value: '1', selected: true, properties: new OptionProperty('https://cutcode.dev/images/platforms/youtube.png')),
new Option(label: 'Option 2', value: '2', properties: new OptionProperty('https://cutcode.dev/images/platforms/youtube.png')),
]);
 
return MoonShineJsonResponse::make(data: $options->toArray());
}
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
->async('/search')

If you need to send the request for values immediately after the page is displayed, then you need to add the asyncOnInit() method

use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
->async('/search')
->asyncOnInit()

Don't forget to handle the query when using async, otherwise, the search will always return the same values.

Change events

When the Select value changes, you can trigger events using the onChangeEvent method:

use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2'
])
->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects')
),

If the Select is in a form, then by default, all form data will be sent with the event when triggered. If the form is large, you may need to exclude a set of fields. Exclusions can be made through the exclude parameter:

->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects'),
exclude: ['text', 'description']
)

You can also completely exclude sending data through the withoutPayload parameter:

->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects'),
withoutPayload: true
)

Editing in preview mode

The updateOnPreview() method allows you to edit the Select field in preview mode.

updateOnPreview(?Closure $url = null, ?ResourceContract $resource = null, mixed $condition = null, array $events = [])
  • $url - url for handling asynchronous request.
  • $resource - the model resource that the relationship points to.
  • $condition - condition for executing the method.
  • $events - list of events when executed? (need a link to the events section).

Parameters are not mandatory and should be passed if the field operates outside of a resource.

use MoonShine\UI\Fields\Select;
 
Select::make(Country)
->updateOnPreview()

Values with images

The optionProperties() method allows you to add an image to the value.

optionProperties(Closure|array $data)
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
1 => 'Andorra',
2 => 'United Arab Emirates',
//...
])->optionProperties(fn() => [
1 => ['image' => 'https://moonshine-laravel.com/images/ad.png'],
2 => ['image' => 'https://moonshine-laravel.com/images/ae.png'],
//...
])

Or via the Options object:

Select::make('Select')->options(
new Options([
new Option(label: 'Option 1', value: '1', selected: true, properties: new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
new Option(label: 'Option 2', value: '2', properties: new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
]
)
)

belongs to image dark

Options

All Choices.js options are available for modification through data attributes:

use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
1 => 'Andorra',
2 => 'United Arab Emirates',
//...
])->customAttributes([
'data-max-item-count' => 2
])

For more detailed information refer to the Choices.js.

Native display mode

The native() method disables the Choices.js library and outputs the select in native mode.

use MoonShine\UI\Fields\Select;
 
Select::make('Type')->native()

Using in blade

Basics

<x-moonshine::form.select>
<x-slot:options>
<option value="1">Option 1</option>
<option selected value="2">Option 2</option>
</x-slot:options>
</x-moonshine::form.select>

You can group values together.

<x-moonshine::form.select
:searchable="true"
/>

You can pass additional parameters to the component:

  • searchable - search through the values
  • nullable - can have a value of NULL

To asynchronously load values, you need to specify the url in the asyncRoute attribute that will return data in JSON format.

<x-moonshine::form.select asyncRoute='url' />

Also see recipes for using Select