В данном разделе мы собрали разные нестандартные подходы использования Select, которые вы можете модернизировать под свои нужды.
Async
Пример демонстрирует метод async, но при этом мы используем подход работы через asyncMethod.
Тем самым экономим время на создание контроллера и пишем реализацию прямо в ресурсе (или на странице):
protected function formFields(): iterable
{
return [
Select::make('Select')->async(
$this->getAsyncMethodUrl('selectOptions'),
)->asyncOnInit(),
]
}
public function selectOptions(): MoonShineJsonResponse
{
$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')),
]);
return MoonShineJsonResponse::make(data: $options->toArray());
}
protected function formFields(): iterable
{
return [
Select::make('Select')->async(
$this->getAsyncMethodUrl('selectOptions'),
)->asyncOnInit(),
]
}
public function selectOptions(): MoonShineJsonResponse
{
$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')),
]);
return MoonShineJsonResponse::make(data: $options->toArray());
}
protected function formFields(): iterable
{
return [
Select::make('Select')->async(
$this->getAsyncMethodUrl('selectOptions'),
)->asyncOnInit(),
]
}
public function selectOptions(): MoonShineJsonResponse
{
$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')),
]);
return MoonShineJsonResponse::make(data: $options->toArray());
}
protected function formFields(): iterable
{
return [
Select::make('Select')->async(
$this->getAsyncMethodUrl('selectOptions'),
)->asyncOnInit(),
]
}
public function selectOptions(): MoonShineJsonResponse
{
$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')),
]);
return MoonShineJsonResponse::make(data: $options->toArray());
}
protected function formFields(): iterable
{
return [
Select::make('Select')->async(
$this->getAsyncMethodUrl('selectOptions'),
)->asyncOnInit(),
]
}
public function selectOptions(): MoonShineJsonResponse
{
$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')),
]);
return MoonShineJsonResponse::make(data: $options->toArray());
}
Reactive
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
])->reactive(function (FieldsContract $fields, mixed $value, Select $ctx, array $values): FieldsContract {
$fields->findByColumn('dynamic_value')?->options((int) $value === 1 ? [
4 => 4,
] : [2 => 2]);
return $fields;
}),
Select::make('Dynamic value', 'dynamic_value')->options([4 => 4])->reactive(),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
])->reactive(function (FieldsContract $fields, mixed $value, Select $ctx, array $values): FieldsContract {
$fields->findByColumn('dynamic_value')?->options((int) $value === 1 ? [
4 => 4,
] : [2 => 2]);
return $fields;
}),
Select::make('Dynamic value', 'dynamic_value')->options([4 => 4])->reactive(),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
])->reactive(function (FieldsContract $fields, mixed $value, Select $ctx, array $values): FieldsContract {
$fields->findByColumn('dynamic_value')?->options((int) $value === 1 ? [
4 => 4,
] : [2 => 2]);
return $fields;
}),
Select::make('Dynamic value', 'dynamic_value')->options([4 => 4])->reactive(),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
])->reactive(function (FieldsContract $fields, mixed $value, Select $ctx, array $values): FieldsContract {
$fields->findByColumn('dynamic_value')?->options((int) $value === 1 ? [
4 => 4,
] : [2 => 2]);
return $fields;
}),
Select::make('Dynamic value', 'dynamic_value')->options([4 => 4])->reactive(),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
])->reactive(function (FieldsContract $fields, mixed $value, Select $ctx, array $values): FieldsContract {
$fields->findByColumn('dynamic_value')?->options((int) $value === 1 ? [
4 => 4,
] : [2 => 2]);
return $fields;
}),
Select::make('Dynamic value', 'dynamic_value')->options([4 => 4])->reactive(),
ShowWhen
За счет того, что по умолчанию ShowWhen удаляет скрытые элементы из DOM мы можем дублировать несколько Select с разными значениями и отображать их по условию
Мы добавили setNameAttribute, чтобы не было конфликта при сохранении формы
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_1')
->showWhen('company', '1')
->options([1 => 1, 2 => 2,]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_2')
->showWhen('company', '2')
->options([3 => 3, 4 => 4,]),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_1')
->showWhen('company', '1')
->options([1 => 1, 2 => 2,]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_2')
->showWhen('company', '2')
->options([3 => 3, 4 => 4,]),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_1')
->showWhen('company', '1')
->options([1 => 1, 2 => 2,]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_2')
->showWhen('company', '2')
->options([3 => 3, 4 => 4,]),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_1')
->showWhen('company', '1')
->options([1 => 1, 2 => 2,]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_2')
->showWhen('company', '2')
->options([3 => 3, 4 => 4,]),
Select::make('Company', 'company')->options([
1 => 'Laravel',
2 => 'CutCode',
3 => 'Symfony',
]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_1')
->showWhen('company', '1')
->options([1 => 1, 2 => 2,]),
Select::make('Dynamic value', 'dynamic_value')
->setNameAttribute('dynamic_value_2')
->showWhen('company', '2')
->options([3 => 3, 4 => 4,]),
onChangeMethod
Подход, в котором при изменении основного Select мы отправляем запрос и возвращаем html следующего Select, отображаем его в блоке по селектору:
public function selectValues(): MoonShineJsonResponse
{
$options = new Options([
new Option('Option 1', '1', false, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
new Option('Option 2', '2', true, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
]);
return MoonShineJsonResponse::make()
->html(
(string) Select::make('Next')->options($options)
);
}
protected function formFields(): iterable
{
return [
Select::make('Select')->options([
1 => 1,
2 => 2,
])->onChangeMethod('selectValues', selector: '.next-select'),
Div::make()->class('next-select'),
];
}
public function selectValues(): MoonShineJsonResponse
{
$options = new Options([
new Option('Option 1', '1', false, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
new Option('Option 2', '2', true, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
]);
return MoonShineJsonResponse::make()
->html(
(string) Select::make('Next')->options($options)
);
}
protected function formFields(): iterable
{
return [
Select::make('Select')->options([
1 => 1,
2 => 2,
])->onChangeMethod('selectValues', selector: '.next-select'),
Div::make()->class('next-select'),
];
}
public function selectValues(): MoonShineJsonResponse
{
$options = new Options([
new Option('Option 1', '1', false, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
new Option('Option 2', '2', true, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
]);
return MoonShineJsonResponse::make()
->html(
(string) Select::make('Next')->options($options)
);
}
protected function formFields(): iterable
{
return [
Select::make('Select')->options([
1 => 1,
2 => 2,
])->onChangeMethod('selectValues', selector: '.next-select'),
Div::make()->class('next-select'),
];
}
public function selectValues(): MoonShineJsonResponse
{
$options = new Options([
new Option('Option 1', '1', false, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
new Option('Option 2', '2', true, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
]);
return MoonShineJsonResponse::make()
->html(
(string) Select::make('Next')->options($options)
);
}
protected function formFields(): iterable
{
return [
Select::make('Select')->options([
1 => 1,
2 => 2,
])->onChangeMethod('selectValues', selector: '.next-select'),
Div::make()->class('next-select'),
];
}
public function selectValues(): MoonShineJsonResponse
{
$options = new Options([
new Option('Option 1', '1', false, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
new Option('Option 2', '2', true, new OptionProperty(image: 'https://cutcode.dev/images/platforms/youtube.png')),
]);
return MoonShineJsonResponse::make()
->html(
(string) Select::make('Next')->options($options)
);
}
protected function formFields(): iterable
{
return [
Select::make('Select')->options([
1 => 1,
2 => 2,
])->onChangeMethod('selectValues', selector: '.next-select'),
Div::make()->class('next-select'),
];
}
Fragments
Благодаря тому что Fragment вместе с запросом отправляет данные формы, мы при перезагрузке фрагмента можем изменить набор элементов Select:
protected function formFields(): iterable
{
$selects = [];
$value = request()->integer('_data.first', 1);
if($value === 1) {
$selects[] = Select::make('Second')->options([
1 => 1,
2 => 2,
]);
}
if($value === 2) {
$selects[] = Select::make('Third')->options([
1 => 1,
2 => 2,
]);
}
return [
Fragment::make([
Select::make('First')->options([
1 => 1,
2 => 2,
])->setValue($value)->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects')
),
...$selects,
])->name('selects'),
];
}
protected function formFields(): iterable
{
$selects = [];
$value = request()->integer('_data.first', 1);
if($value === 1) {
$selects[] = Select::make('Second')->options([
1 => 1,
2 => 2,
]);
}
if($value === 2) {
$selects[] = Select::make('Third')->options([
1 => 1,
2 => 2,
]);
}
return [
Fragment::make([
Select::make('First')->options([
1 => 1,
2 => 2,
])->setValue($value)->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects')
),
...$selects,
])->name('selects'),
];
}
protected function formFields(): iterable
{
$selects = [];
$value = request()->integer('_data.first', 1);
if($value === 1) {
$selects[] = Select::make('Second')->options([
1 => 1,
2 => 2,
]);
}
if($value === 2) {
$selects[] = Select::make('Third')->options([
1 => 1,
2 => 2,
]);
}
return [
Fragment::make([
Select::make('First')->options([
1 => 1,
2 => 2,
])->setValue($value)->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects')
),
...$selects,
])->name('selects'),
];
}
protected function formFields(): iterable
{
$selects = [];
$value = request()->integer('_data.first', 1);
if($value === 1) {
$selects[] = Select::make('Second')->options([
1 => 1,
2 => 2,
]);
}
if($value === 2) {
$selects[] = Select::make('Third')->options([
1 => 1,
2 => 2,
]);
}
return [
Fragment::make([
Select::make('First')->options([
1 => 1,
2 => 2,
])->setValue($value)->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects')
),
...$selects,
])->name('selects'),
];
}
protected function formFields(): iterable
{
$selects = [];
$value = request()->integer('_data.first', 1);
if($value === 1) {
$selects[] = Select::make('Second')->options([
1 => 1,
2 => 2,
]);
}
if($value === 2) {
$selects[] = Select::make('Third')->options([
1 => 1,
2 => 2,
]);
}
return [
Fragment::make([
Select::make('First')->options([
1 => 1,
2 => 2,
])->setValue($value)->onChangeEvent(
AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'selects')
),
...$selects,
])->name('selects'),
];
}