Select items from a menu list.
{ item : item, label : String }
The menu item that will be represented in the menu list.
The item
property is the type representation of the menu item that will be used in an Action.
The label
is the text representation that will be shown in the menu.
type Tool
= Screwdriver
| Hammer
| Drill
toolItems : MenuItem Tool
toolItems =
[ { item = Screwdriver, label = "Screwdriver" }
, { item = Hammer, label = "Hammer" }
, { item = Drill, label = "Drill" }
]
yourView model =
Html.map SelectMsg <|
view
(single Nothing
|> menuItems toolItems
|> state model.selectState
)
(selectIdentifier "SingleSelectExample")
Specific events happen in the Select that you can react to from your update.
Maybe you want to find out what country someone is from?
When they select a country from the menu, it will be reflected in the Select action.
import Select exposing ( Action(..) )
type Msg
= SelectMsg (Select.Msg Country)
-- your other Msg's
type Country
= Australia
| Japan
| Taiwan
-- other countries
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
SelectMsg selectMsg ->
let
(maybeAction, selectState, selectCmds) =
Select.update selectMsg model.selectState
selectedCountry : Maybe Country
selectedCountry =
case maybeAction of
Just (Select.Select someCountry) ->
Just someCountry
Nothing ->
Nothing
in
-- (model, cmd)
initState : State
Set up an initial state in your init function.
type Country
= Australia
| Japan
| Taiwan
type alias Model =
{ selectState : Select.State
, items : List (Select.MenuItem Country)
, selectedCountry : Maybe Country
}
init : Model
init =
{ selectState = Select.initState
, items =
[ { item = Australia, label = "Australia" }
, { item = Japan, label = "Japan" }
, { item = Taiwan, label = "Taiwan" }
]
, selectedCountry = Nothing
}
menuItems : List (MenuItem item) -> Config item -> Config item
The items that will appear in the menu list.
NOTE: When using the (multi) select, selected items will be reflected as a tags and visually removed from the menu list.
items =
[ { item = SomeValue, label = "Some label" } ]
yourView =
view
(Single Nothing |> menuItems items)
(selectIdentifier "1234")
placeholder : String -> Config item -> Config item
The text that will appear as an input placeholder.
yourView model =
Html.map SelectMsg <|
view
(single Nothing |> placeholder "some placeholder")
(selectIdentifier "1234")
selectIdentifier : String -> SelectId
The ID for the rendered Select input
NOTE: It is important that the ID's of all selects that exist on a page remain unique.
yourView model =
Html.map SelectMsg <|
view
(single Nothing)
(selectIdentifier "someUniqueId")
state : State -> Config item -> Config item
model : Model
model =
{ selectState = initState }
yourView : Model
yourView model =
Html.map SelectMsg <|
view
(single Nothing |> state model.selectState)
(selectIdentifier "1234")
update : Msg item -> State -> ( Maybe (Action item), State, Platform.Cmd.Cmd (Msg item) )
Add a branch in your update to handle the view Msg's.
yourUpdate msg model =
case msg of
SelectMsg selectMsg ->
update selectMsg model.selectState
view : Config item -> SelectId -> Html.Styled.Html (Msg item)
Render the select
yourView model =
Html.map SelectMsg <|
view
(single Nothing)
(selectIdentifier "SingleSelectExample")
searchable : Basics.Bool -> Config item -> Config item
Renders an input that let's you input text to search for menu items.
yourView model =
Html.map SelectMsg <|
view
(single Nothing |> searchable True)
(selectIdentifier "1234")
NOTE: This doesn't affect the Native single select variant.
setStyles : Styles.Config -> Config item -> Config item
Change some of the visual styles of the select.
Useful for styling the select using your color branding.
import Select.Styles as Styles
branding : Styles.Config
branding =
Styles.controlDefault
|> Styles.setControlBorderColor (Css.hex "#FFFFFF")
|> Styles.setControlBorderColorFocus (Css.hex "#0168B3")
|> Styles.setControlStyles Styles.default
yourView model =
Html.map SelectMsg <|
view
(single Nothing |> setStyles branding)
(selectIdentifier "1234")
single : Maybe (MenuItem item) -> Config item
Select a single item.
countries : List (MenuItem Country)
countries =
[ { item = Australia, label = "Australia" }
, { item = Taiwan, label = "Taiwan"
-- other countries
]
yourView =
Html.map SelectMsg <|
view
(single Nothing |> menuItems countries)
(selectIdentifier "1234")
clearable : Basics.Bool -> Config item -> Config item
Allows a single variant selected menu item to be cleared.
To handle a cleared item refer to the ClearedSingleSelect action.
yourView model =
Html.map SelectMsg <|
view
( single Nothing
|> clearable True
|> menuItems -- [ menu items ]
)
(selectIdentifier "SingleSelectExample")
multi : MultiSelectConfig -> List (MenuItem item) -> Config item
Select multiple items.
Selected items will render as tags and be visually removed from the menu list.
yourView model =
Html.map SelectMsg <|
view
(multi
(initMultiConfig
|> menuItems model.countries
)
model.selectedCountries
)
(selectIdentifier "1234")
truncateMultiTag : Basics.Float -> MultiSelectConfig -> MultiSelectConfig
Limit the width of a multi select tag.
Handy for when the selected item text is excessively long. Text that breaches the set width will display as an ellipses.
Width will be in px values.
yourView model =
Html.map SelectMsg <|
view
(multi
( initMultiConfig
|> truncateMultitag 30
)
model.selectedCountries
)
(selectIdentifier "1234")
multiTagColor : Css.Color -> MultiSelectConfig -> MultiSelectConfig
Set the color for the multi select tag.
yourView =
Html.map SelectMsg <|
view
(multi
( initMultiConfig
|> multiTagColor (Css.hex "#E1E2EA"
)
model.selectedCountries
)
(selectIdentifier "1234")
initMultiConfig : MultiSelectConfig
Starting value for the 'multi' variant.
yourView model =
Html.map SelectMsg <|
view
(multi initMultiConfig [])
(selectIdentifier "1234")
singleNative : Maybe (MenuItem item) -> Config item
Select a single item with a native html select element.
Useful for when you want to give a native select experience such as on touch devices.
countries : List (MenuItem Country)
countries =
[ { item = Australia, label = "Australia" }
, { item = Taiwan, label = "Taiwan"
-- other countries
]
yourView =
Html.map SelectMsg <|
view
(singleNative Nothing |> menuItems countries)
(selectIdentifier "1234")
Note
The only Action event that will be fired from the native single select is
the Select
Action. The other actions are not currently supported.
Some Config values will not currently take effect when using the single native variant i.e. loading, placeholder, clearable, labelledBy, disabled
disabled : Basics.Bool -> Config item -> Config item
Disables the select input so that it cannot be interacted with.
yourView model =
Html.map SelectMsg <|
view
(single Nothing |> disabled True)
(selectIdentifier "SingleSelectExample")
labelledBy : String -> Config item -> Config item
The element ID of the label for the select.
It is best practice to render the select with a label.
yourView model =
label
[ id "selectLabelId" ]
[ text "Select your country"
, Html.map SelectMsg <|
view
(single Nothing |> labelledBy "selectLabelId")
(selectIdentifier "SingleSelectExample")
]
ariaDescribedBy : String -> Config item -> Config item
The ID of element that describes the select.
yourView model =
label
[ id "selectLabelId" ]
[ text "Select your country"
, Html.map SelectMsg <|
view
(single Nothing
|> labelledBy "selectLabelId"
|> ariaDescribedBy "selectDescriptionId"
)
(selectIdentifier "SingleSelectExample")
, div [ id "selectDescriptionId" ] [ text "This text describes the select" ]
]
loading : Basics.Bool -> Config item -> Config item
Displays an animated loading icon to visually represent that menu items are being loaded.
This would be useful if you are loading menu options asynchronously, like from a server.
yourView model =
Html.map SelectMsg <|
view
(single Nothing |> loading True)
(selectIdentifier "SingleSelectExample")
jsOptimize : Basics.Bool -> State -> State
Opt in to a Javascript optimization.
Read the Advanced section of the README for a good explanation on why you might like to opt in.
model : Model model =
{ selectState = initState |> jsOptimize True }
Install the Javascript package:
npm
npm install @confidenceman02/elm-select
Import script
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Viewer</title>
<script src="/node_modules/@confidenceman02/elm-select/dist/dynamic.min.js"></script>
</head>
<body>
<main></main>
<script src="index.js"></script>
</body>
</html>
Alternatively you can import the script wherever you are initialising your program.
import { Elm } from "./src/Main";
import "@confidenceman02/elm-select"
Elm.Main.init({node, flags})