Поля

Select

Основы

Содержит все Базовые методы.

use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2',
])
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>
<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 select

Основные методы

Значение по умолчанию

Если необходимо указать значение по умолчанию, вы можете воспользоваться методом default().

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

Также вы можете указывать опции через объект Options.

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'),
),
])
)
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

Как и у всех полей, если необходимо сохранять NULL, то нужно добавить метод nullable().

nullable(Closure|bool|null $condition = null)
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()
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2',
])
->nullable()
<x-moonshine::form.select
:nullable="true"
/>
<x-moonshine::form.select
:nullable="true"
/>

select nullable select nullable

Placeholder

Метод placeholder() позволяет задать у поля атрибут placeholder.

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

Группы

Можно объединять значения в группы.

use MoonShine\UI\Fields\Select;
 
Select::make('City', 'city_id')
->options([
'Italy' => [
1 => 'Rome',
2 => 'Milan',
],
'France' => [
3 => 'Paris',
4 => 'Marseille',
]
])
use MoonShine\UI\Fields\Select;
 
Select::make('City', 'city_id')
->options([
'Italy' => [
1 => 'Rome',
2 => 'Milan',
],
'France' => [
3 => 'Paris',
4 => 'Marseille',
]
])
use MoonShine\UI\Fields\Select;
 
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'),
])),
])
)
use MoonShine\UI\Fields\Select;
 
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 select group

Выбор нескольких значений

Для выбора нескольких значений используйте метод multiple().

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

В базе данных поле должно быть типа "text" или "json". Также необходимо указать cast — "array", "json" или "collection".

select multiple select multiple

Если необходимо добавить поиск среди значений, то нужно добавить метод searchable().

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

searchable searchable

Асинхронный поиск

У поля Select так же можно организовать асинхронный поиск. Для это необходимо методу async() передать url, на который будет отправляться запрос с query параметром для поиска.

async(
Closure|string|null $url = null,
string|array|null $events = null,
?AsyncCallback $callback = null,
)
async(
Closure|string|null $url = null,
string|array|null $events = null,
?AsyncCallback $callback = null,
)
  • $url - url или функция для обработки асинхронного запроса,
  • $events - список событий после выполнения запроса (нужна ссылка на раздел с событиями),
  • $callback - Callback после выполнения запроса.

Параметры $events и $callback не являются обязательными.

Возвращаемый ответ с результатами поиска должен быть в формате json.

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

Также можно воспользоваться объектом Options.

public function selectOptions(): JsonResponse
{
$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 JsonResponse::make(data: $options->toArray());
}
public function selectOptions(): JsonResponse
{
$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 JsonResponse::make(data: $options->toArray());
}

Ответ будет:

[{
"value": "1",
"label": "Option 1",
"selected": true,
"properties": {
"image": "https:\/\/cutcode.dev\/images\/platforms\/youtube.png"
}
}, {
"value": "2",
"label": "Option 2",
"selected": false,
"properties": {
"image": "https:\/\/cutcode.dev\/images\/platforms\/youtube.png"
}
}]
[{
"value": "1",
"label": "Option 1",
"selected": true,
"properties": {
"image": "https:\/\/cutcode.dev\/images\/platforms\/youtube.png"
}
}, {
"value": "2",
"label": "Option 2",
"selected": false,
"properties": {
"image": "https:\/\/cutcode.dev\/images\/platforms\/youtube.png"
}
}]
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2',
])
->async('/search')
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
'value 1' => 'Option Label 1',
'value 2' => 'Option Label 2',
])
->async('/search')
<x-moonshine::form.select asyncRoute='/search' />
<x-moonshine::form.select asyncRoute='/search' />

Если необходимо сразу же после отображения страницы отправить запрос на значения, тогда необходимо добавить метод asyncOnInit(whenOpen: false).

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

При пустом asyncOnInit() или asyncOnInit(whenOpen: true) запрос будет отправляться после клика на Select. И если необходимо, чтобы показывался "Загрузчик", перед открытием Select, то можно добавить asyncOnInit(withLoading: true).

Не забудьте обработать query при использовании async, иначе поиск всегда будет выдавать одинаковые значения.

События при изменении

При изменении значения Select, вы можете вызвать события через метод onChangeEvent().

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')
),
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')
),

Если Select находится в форме, то по умолчанию при вызове события с запросом будут отправлены все данные формы. Если форма большая, то может потребоваться исключить набор полей. Исключить можно через параметр exclude.

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

Также можно полностью исключить отправку данных через параметр withoutPayload.

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

Редактирование в режиме preview

Метод updateOnPreview() позволяет редактировать поле Select в режиме "preview".

updateOnPreview(
?Closure $url = null,
?ResourceContract $resource = null,
mixed $condition = null,
array $events = [],
)
updateOnPreview(
?Closure $url = null,
?ResourceContract $resource = null,
mixed $condition = null,
array $events = [],
)
  • $url - url для обработки асинхронного запроса,
  • $resource - ModelResource, на который ссылается отношение,
  • $condition - условие выполнения метода,
  • $events - список событий когда выполняются? (нужна ссылка на раздел с событиями).

Параметры не являются обязательными и их необходимо передавать, если поле работает вне ресурса.

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

Значения с изображением

Метод optionProperties() позволяет добавить изображение к значению.

optionProperties(Closure|array $data)
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'],
])
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'],
])

Или через объект Options:

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'),
),
])
)
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 belongs to image

Для кастомизации изображений передавайте в OptionPropery объект OptionImage вместо строки:

new OptionProperty(
new OptionImage(
src: 'https://cutcode.dev/images/platforms/youtube.png',
height: 6,
width: 6,
objectFit: ObjectFit::CONTAIN
)
),
new OptionProperty(
new OptionImage(
src: 'https://cutcode.dev/images/platforms/youtube.png',
height: 6,
width: 6,
objectFit: ObjectFit::CONTAIN
)
),
  • $src - url изображения,
  • $height - высота изображения (используется для подстановки в класс h-{x}, где x в диапазоне от 1 до 10),
  • $width - ширина изображения (используется для подстановки в класс w-{x}, где x в диапазоне от 1 до 10),
  • $objectFit - одно из значений перечисления ObjectFit (см. object-fit).

Опции

Все опции Сhoices.js доступны для изменения через 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
])
use MoonShine\UI\Fields\Select;
 
Select::make('Country', 'country_id')
->options([
1 => 'Andorra',
2 => 'United Arab Emirates',
])
->customAttributes([
'data-max-item-count' => 2
])

За более подробной информацией обратитесь к Choices.js.

Нативный режим отображения

Метод native() отключает библиотеку Choices.js и выводит Select в нативном режиме.

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

Смотрите также рецепты по использованию Select.

Плагины

Метод addPlugin(array|string $plugin, array $pluginOptions = []) добавляет плагин в Select.

use MoonShine\UI\Fields\Select;
 
Select::make('Type')
->addPlugin(['plugin_1', 'plugin_2'])
 
Select::make('Type')
->addPlugin('plugin_1', [
'foo' => 'bar',
...
])
->addPlugin('plugin_2', [
'foo' => 'bar',
...
])
use MoonShine\UI\Fields\Select;
 
Select::make('Type')
->addPlugin(['plugin_1', 'plugin_2'])
 
Select::make('Type')
->addPlugin('plugin_1', [
'foo' => 'bar',
...
])
->addPlugin('plugin_2', [
'foo' => 'bar',
...
])

Все официальные плагины.

Вы также можете очень легко создавать свои собственные плагины.

<script>
document.addEventListener('moonshine:select_init', function({ detail: { createPlugin } }) {
createPlugin('myPlugin', function(pluginOptions) {
console.log(pluginOptions, this.getValue())
 
this.on('change', value => {
//
})
})
})
</script>
<script>
document.addEventListener('moonshine:select_init', function({ detail: { createPlugin } }) {
createPlugin('myPlugin', function(pluginOptions) {
console.log(pluginOptions, this.getValue())
 
this.on('change', value => {
//
})
})
})
</script>

Далее, подключаем плагин, как показано выше.

Полная документация по созданию плагинов.

Пользовательские настройки

Метод settings() разрешает использовать все пользовательские настройки Tom select.

use MoonShine\Support\DTOs\Select\Settings;
settings(array|Settings $settings)
use MoonShine\Support\DTOs\Select\Settings;
settings(array|Settings $settings)
use MoonShine\UI\Fields\Select;
use MoonShine\Support\DTOs\Select\Settings;
 
Select::make('Type')
->settings(
Settings::make()
->maxOptions(10)
->highlight(false)
);
use MoonShine\UI\Fields\Select;
use MoonShine\Support\DTOs\Select\Settings;
 
Select::make('Type')
->settings(
Settings::make()
->maxOptions(10)
->highlight(false)
);

Все доступные настройки.

Для всех именных настроек, есть очень удобный метод fieldsNames()

use MoonShine\Support\DTOs\Select\FieldsNames;
fieldsNames(FieldsNames $names)
use MoonShine\Support\DTOs\Select\FieldsNames;
fieldsNames(FieldsNames $names)
use MoonShine\UI\Fields\Select;
use MoonShine\Support\DTOs\Select\FieldsNames;
 
Select::make('Type')
->fieldsNames(
FieldsNames::make()
->value('id')
->label('name')
->children('children')
);
use MoonShine\UI\Fields\Select;
use MoonShine\Support\DTOs\Select\FieldsNames;
 
Select::make('Type')
->fieldsNames(
FieldsNames::make()
->value('id')
->label('name')
->children('children')
);

Для дополнительной настройки асинхронности, можно воспользоваться методом asyncSettings()

use MoonShine\Support\DTOs\Select\AsyncSettings;
asyncSettings(array|AsyncSettings $settings)
use MoonShine\Support\DTOs\Select\AsyncSettings;
asyncSettings(array|AsyncSettings $settings)
use MoonShine\UI\Fields\Select;
use MoonShine\Support\DTOs\Select\AsyncSettings;
 
Select::make('Type')
->asyncSettings(
AsyncSettings::make()
// Можно менять название поля поиска
->queryKey('q')
 
// Можно отправить текущие активные значения, просто указываем название
->selectedValuesKey('name')
 
// Если результат обернуть, например, в data, то указываем этот ключ
->resultKey('data')
 
// Если хотите, чтобы вместе с запросом, шли все поля текущей формы
->withAllFields()
);
use MoonShine\UI\Fields\Select;
use MoonShine\Support\DTOs\Select\AsyncSettings;
 
Select::make('Type')
->asyncSettings(
AsyncSettings::make()
// Можно менять название поля поиска
->queryKey('q')
 
// Можно отправить текущие активные значения, просто указываем название
->selectedValuesKey('name')
 
// Если результат обернуть, например, в data, то указываем этот ключ
->resultKey('data')
 
// Если хотите, чтобы вместе с запросом, шли все поля текущей формы
->withAllFields()
);

Для переключения в режим "создания новых опции", можно воспользоваться методом selectCreatable()

selectCreatable(
?string $filterRegex = null,
bool $persist = true,
bool $createOnBlur = false,
bool $duplicates = false,
bool $addPrecedence = false,
)
selectCreatable(
?string $filterRegex = null,
bool $persist = true,
bool $createOnBlur = false,
bool $duplicates = false,
bool $addPrecedence = false,
)
use MoonShine\UI\Fields\Select;
 
Select::make('Type')
->selectCreatable(
/^\d+$/
);
use MoonShine\UI\Fields\Select;
 
Select::make('Type')
->selectCreatable(
/^\d+$/
);

Более подробно описано здесь.

Если нужно ограничить максимальный выбор опции, можно воспользоваться методом selectMaxItems()

selectMaxItems(
?int $limit = null,
?string $text = null // По умолчанию "Максимальное количество элементов: :count"
)
selectMaxItems(
?int $limit = null,
?string $text = null // По умолчанию "Максимальное количество элементов: :count"
)
use MoonShine\UI\Fields\Select;
 
Select::make('Type')
->selectMaxItems(5);
use MoonShine\UI\Fields\Select;
 
Select::make('Type')
->selectMaxItems(5);