A dropdown component for Elm-UI.
In order to provide built-in keyboard navigation, and option filtering, it is
necessary for the Dropdown to manage it's own internal state. Therefore any
Dropdowns you require need to be stored on your Model, with events being
handled in your update function.
There are a few gotchas to watch out for with functions that operate on the
internal state of the Dropdown. Because of the effect they have on the internal
state, using them in your view code will have no effect. They should
therefore be used when you init the Dropdown, or in your update
function where model changes can be captured.
The affected functions are, id, filterType, setSelected, removeSelected, [removeOption](#removeOption] & openOnMouseEnter, along with all the functions for setting the menu options. Each function or section has a warning documenting this restriction where it is applicable.
All other functions can be used safely within view code.
Initialize a dropdown on your model.
import Dropdown
initialModel : Model
initialModel =
{ myDropdown = Dropdown.init }Provide an ID for the dropdown.
This will become the element id in the DOM, and is required in order for
keyboard navigation to work - it should therefore be unique.
import Dropdown
initialModel : Model
initialModel =
{ myDropdown =
Dropdown.init
|> Dropdown.id "my-drodown"
}Warning
The id needs to be stored on the dropdown model, and so should be set
when you init the dropdown, or in your update function where the
changes to the model can be captured.
If you set this in your view code it will have no effect and keyboard
navigation won't work.
The type of input the user uses to access the dropdown.
The default is Button.
Warning
Options need to be stored on the dropdown model, and so should be set
when you init the dropdown, or in your update function where the
changes to the model can be captured.
If you set these in your view code they will have no effect and so no menu
will appear.
This is the easiest way to set the options for custom types.
Simply provide a function that takes an option and returns the String to
be used for the label in the menu.
import Dropdown exposing (Dropdown)
type alias Model =
{ nameDropdown : Dropdown Person
, ageDropdown : Dropdown Person
}
initialModel : Model
initialModel =
{ nameDropdown =
Dropdown.init
|> Dropdown.optionsBy .name people
, ageDropdown =
Dropdown.init
|> Dropdown.optionsBy (.age >> String.fromInt) people
}
type alias Person =
{ name : String
, age : Int
}
people : List Person
people =
[ { name = "John Doe", age = 99 }
, { name = "Jane Doe", age = 98 }
]The options to set for your dropdown.
The first element in the list of tuples is always a String, and is used for
the option's label in the menu that is displayed to the user.
import Dropdown exposing (Dropdown)
type alias Model =
{ customTypeDropdown : Dropdown CustomType }
initialModel : Model
initialModel =
{ customTypeDropdown =
Dropdown.init
|> Dropdown.options customTypeOptions
}
type CustomType
= A
| B
customTypeOptions : List ( String, CustomType )
customTypeOptions =
[ ( "A", A )
, ( "B", B )
]The options to set for your dropdown if they are all Strings.
import Dropdown exposing (Dropdown)
type alias Model =
{ stringDropdown : Dropdown String }
initialModel : Model
initialModel =
{ stringDropdown =
Dropdown.init
|> Dropdown.stringOptions
[ "A"
, "B"
, "C"
]
}The options to set for your dropdown if they are all Ints.
import Dropdown exposing (Dropdown)
type alias Model =
{ stringDropdown : Dropdown Int }
initialModel : Model
initialModel =
{ stringDropdown =
Dropdown.init
|> Dropdown.intOptions
[ 1
, 2
, 3
]
}The options to set for your dropdown if they are all Floats.
import Dropdown exposing (Dropdown)
type alias Model =
{ stringDropdown : Dropdown Float }
initialModel : Model
initialModel =
{ stringDropdown =
Dropdown.init
|> Dropdown.floatOptions
[ 0.1
, 0.2
, 0.3
]
}Provide the label element for the InputType.
Hide the label.
The text element for the Button if nothing is selected.
The default is "-- Select --".
Provide the Placeholder for the text field if TextField is the InputType.
The default is Nothing.
The position of the label or the dropdown menu in relation to the InputType.
The max height for the dropdown, the default is 150.
(Vertical scrolling kicks in automatically.)
The Attributes to set on the InputType.
The Attributes to set on each option.
The Attributes to set on an option when hovered over with the mouse, or navigated to with the keyboard.
The Attributes to set on an option when it has been selected by a user.
Filtering is currently case insensitive.
The type of filter to apply when TextField is used as the InputType.
NoFilter: No filter will be applied.StartsWith: Filter the list of options down to only those whose label
starts with the entered text.Contains: Filter the list of options down to only those whose label
contains the entered text.StartsWithThenContains: Filter the list of options down to only those
whose label starts with the entered text or contains the entered text. The
list of options will be sorted with StartsWith taking priority over
Contains, with duplicates removed.The default is NoFilter.
Set the FiterType.
import Dropdown exposing (FilterType(..))
initialModel : Model
initialModel =
{ dropdown =
Dropdown.init
|> Dropdown.filterType StartsWith
}Warning
The FilterType needs to be stored on the dropdown model, and so should be set
when you init the dropdown, or in your update function where the
changes to the model can be captured.
If you set this in your view code it will have no effect, and filtering won't
work.
Set the selected option - it must exist in the list of options originally provided.
Warning
This function changes the internal state, and so needs to be used where the
state change can be captured. This is likely to be your update function.
If you use this in your view code it will have no effect.
Remove the selected option of one dropdown from the list of options of another dropdown.
This is useful if you have two dropdowns that show the same list of options, but each selection must be unique, therefore you don't want to show the selected option again.
For example, selecting a home team and away team from the same list of teams. In this case, once the home team has been selected, you may wish to remove that option from the list of away teams.
awayTeamDropdown =
Dropdown.removeSelected homeTeamDropdown awayTeamDropdownWarning
This function changes the internal state, and so needs to be used where the
state change can be captured. This is likely to be your update function.
If you use this in your view code it will have no effect.
Remove an option from the internal list.
Warning
This function changes the internal state, and so needs to be used where the
state change can be captured. This is likely to be your update function.
If you use this in your view code it will have no effect.
Set the selected label - it must exist in the list of options originally provided.
Warning
This function changes the internal state, and so needs to be used where the
state change can be captured. This is likely to be your update function.
If you use this in your view code it will have no effect.
Choose whether the menu opens when the mouse enters.
If this is set to True the menu will also close automatically when the mouse
leaves.
The default is True.
Warning
This function changes the internal state, and so needs to be used where the
state change can be captured. This is likely to be your update function.
If you use this in your view code it will have no effect.
Determine if an option has been selected by the user.
If a Just is returned, it consists of the following:
Int: The index of the selected option.String: The label of the selected option.option: The option value itself.Maybe retrieve the selected option.
Maybe retrieve the label for the selected option.
List all the option information. The tuples returned represent:
optionoptionoption itselfList all the options.
List all the labels for each option.
Pattern match on this type in your update function to determine the event
that occured.
Selected (Int, String, option)
Int is the index of the option in the menuString is the label of the option displayed in the menuoption is the option.TextChanged String
String is the text entered by the user.import Dropdown exposing (OutMsg(..))
type Msg
= DropdownMsg Dropdown.Msg
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
DropdownMsg subMsg ->
let
( dropdown, cmd, outMsg ) =
Dropdown.update subMsg model.dropdown
in
case outMsg of
Selected ( index, label, option ) ->
( { model | dropdown = dropdown }
, Cmd.map DropdownMsg cmd
)
TextChanged text ->
( { model | dropdown = dropdown }
, Cmd.map DropdownMsg cmd
)
...
An opaque type representing the internal model.
Use this to define the
optiontype on your model.