|
| 1 | +--- |
| 2 | +title: Custom Select |
| 3 | +sort: 8 |
| 4 | +--- |
| 5 | + |
| 6 | +## Introduction |
| 7 | + |
| 8 | +Heavily based on [Tailwind UI's custom selects](https://tailwindui.com/components/application-ui/forms/select-menus), the `custom-select` component provides a nice alternative |
| 9 | +to the native select menu. Using this menu will provide your select menus with search functionalities and |
| 10 | +custom option markup while still providing usability functionalities such as keyboard navigation. |
| 11 | + |
| 12 | +## Installation |
| 13 | + |
| 14 | +The custom select component requires Alpine.js, as well as some custom JavaScript written into the package to work. |
| 15 | +Ensure you have the proper [directives](/docs/laravel-form-components/v1/installation#directives) in your layout file. |
| 16 | +In production, we recommend you install and compile the JavaScript libraries before you deploy: |
| 17 | + |
| 18 | +- [Alpine.js](https://github.com/alpinejs/alpine) `^2.7` |
| 19 | + |
| 20 | +## Basic Usage |
| 21 | + |
| 22 | +You can use the select menu by providing some basic options. |
| 23 | + |
| 24 | +```html |
| 25 | +<x-custom-select :options="['foo', 'bar']" /> |
| 26 | +``` |
| 27 | + |
| 28 | +This will output a custom select menu with options for `foo` and `bar`. The menu is toggled open and closed by using a `<button` element, |
| 29 | +and renders each option in an `<li>` tag inside of a `<ul>`. We have done our best to include all of the necessary aria attributes for |
| 30 | +accessiblity, but we are by no means accessibility experts. If you notice any accessibility issues, please submit a PR to the github |
| 31 | +repository to fix them. |
| 32 | + |
| 33 | +## Options |
| 34 | + |
| 35 | +There are multiple ways ot provide options to the component. The primary way is to provide an array of options via the `options` attribute. |
| 36 | +If you provide an array of strings, the component will use the strings as both the key and values of the options. For most cases however, you |
| 37 | +should provide an array of keyed arrays for each option, or you can even pass in an array of Eloquent models as options. |
| 38 | + |
| 39 | +```html |
| 40 | +<x-custom-select :options="[ |
| 41 | + ['value' => 'foo', 'text' => 'Foo'], |
| 42 | + ['value' => 'bar', 'text' => 'Bar'], |
| 43 | +]" /> |
| 44 | + |
| 45 | +<!-- using models --> |
| 46 | +<x-custom-select :options="[\App\Models\User::get(['id', 'name'])]" value-key="id" text-key="name" /> |
| 47 | +``` |
| 48 | + |
| 49 | +### Option Values & Text |
| 50 | + |
| 51 | +By default, the component will look for a `value` key for the option value, and a `text` key for the option text. When you are using Eloquent models |
| 52 | +for options, most of the time this won't work. For this reason, you can specify which keys the option should use for the value and text |
| 53 | +of the option via `value-key` and `text-key`. |
| 54 | + |
| 55 | +### Manually Creating Options |
| 56 | + |
| 57 | +Instead of passing in options to the custom select component, you can also create your own options via the default slot in the component by |
| 58 | +using the `custom-select-option` component. This component accepts an `option` attribute, and optionally a `value-key` attribute for the |
| 59 | +option's value, and `text-key` attribute for the option's text content. |
| 60 | + |
| 61 | +```html |
| 62 | +<x-custom-select-option :option="$user" value-key="id" text-key="name" /> |
| 63 | +``` |
| 64 | + |
| 65 | +The `custom-select-option` also has a default slot which will allow you to customize the markup of the content of the option. |
| 66 | + |
| 67 | +```html |
| 68 | +<x-custom-select-option :option="$user" value-key="id" text-key="name"> |
| 69 | + {{ $user->name }} <span class="text-xs">@{{ $user->email }}</span> |
| 70 | +</x-custom-select-option> |
| 71 | +``` |
| 72 | + |
| 73 | +In either case, you still need to provide the `option` attribute, and then any value/text mapping you need. The `option` attribute |
| 74 | +is used by the package's JavaScript to help with keyboard navigation and also for local [filtering](#server-side-filtering) of options if you |
| 75 | +have filters enabled on the select. |
| 76 | + |
| 77 | +**Note:** Any content you place inside of the option will also be displayed on the button when the option is selected. |
| 78 | + |
| 79 | +### Disabling Options |
| 80 | + |
| 81 | +You may disable specific options by providing a boolean value of true to the component: |
| 82 | + |
| 83 | +```html |
| 84 | +<x-custom-select-option :option="$option" disabled /> |
| 85 | +``` |
| 86 | + |
| 87 | +### Opt Groups |
| 88 | + |
| 89 | +You can specify an option as an "optgroup" header by passing in a boolean true value to the `is-group` attribute: |
| 90 | + |
| 91 | +```html |
| 92 | +<x-custom-select-option is-group>Group Name</x-custom-select-option> |
| 93 | +``` |
| 94 | + |
| 95 | +## Filtering |
| 96 | + |
| 97 | +You may provide search functionality on a custom select by setting `filterable` on the component to `true`. |
| 98 | + |
| 99 | +```html |
| 100 | +<x-custom-select :options="$options" filterable /> |
| 101 | +``` |
| 102 | + |
| 103 | +This will provide basic search functionality, which will hide any non-matching options as the user types. |
| 104 | + |
| 105 | +## Server-Side Filtering |
| 106 | + |
| 107 | +If you use Livewire, you can easily add server-side filtering of options via a custom `wire:filter` attribute on the component. |
| 108 | + |
| 109 | +```html |
| 110 | +<x-custom-select :options="$options" filterable wire:filter="selectSearch" /> |
| 111 | +``` |
| 112 | + |
| 113 | +Behind-the-scenes, the custom select component will convert that to a `wire:model` on the filter input in the select and bind it to |
| 114 | +your public property on your livewire component. From there, you can filter out your options based on the value of the filter. Modifiers |
| 115 | +such as `.lazy` or `.defer` are also supported on the `wire:filter` attribute. |
| 116 | + |
| 117 | +```html |
| 118 | +<x-custom-select :options="$options" filterable wire:filter.lazy="selectSearch" /> |
| 119 | +``` |
| 120 | + |
| 121 | +## Multiple Select |
| 122 | + |
| 123 | +You can easily make a select accept multiple selected options by using the `multiple` attribute. |
| 124 | + |
| 125 | +```html |
| 126 | +<x-custom-select :options="$options" multiple /> |
| 127 | +``` |
| 128 | + |
| 129 | +## Optional Selects |
| 130 | + |
| 131 | +For times that you want to allow users to clear the select option(s), you can mark a custom select as `optional`. This |
| 132 | +works for both single and multi-select modes, and provides a clear button next to the selected option text. |
| 133 | + |
| 134 | +```html |
| 135 | +<x-custom-select :options="$options" optional /> |
| 136 | +``` |
| 137 | + |
| 138 | +## Addons |
| 139 | + |
| 140 | +The custom select component supports leading addons, but since there are already elements appended to the end |
| 141 | +of the button trigger, trailing addons are not supported. For more information on addons, see [the input documentation](/docs/laravel-form-components/v1/components/input#addons). |
0 commit comments