Kurren123 / k-dropdown-container / DropdownContainer

A dropdown container in elm which can keep open when the user clicks inside (if you so choose).

Stuff to do with your model


type Visibility
    = Open
    | Closed

Whether the dropdown is visible


type State

The dropdown's internal state. This should be somewhere in your model, along with a value indicating the dropdown's Visibility

type alias Model =
type alias Model =
    { dropdownState : Dropdown.State
    , dropdownVisbility : Dropdown.Visibility
    }

initialState : State

Use this in the init of your app

initialModel : Model
initialModel =
    { dropdownState = Dropdown.initialState
    , dropdownVisbility = Dropdown.Closed
    }

Stuff to do with your update

dropDownCurrentlyClicked : State -> Basics.Bool

True if the user has pressed mousedown in the dropdown but not yet released the mouse. This is useful when the dropdownBlur event has been triggered and you need to decide whether you want to close the dropdown.

update : Msg -> Model -> Model
update msg model =
    case msg of
        DropdownBlur ->
            if Dropdown.dropDownCurrentlyClicked model.dropdownState then
                model

            else
                { model | dropdownVisbility = Dropdown.Closed }

Stuff to do with your view


type alias Config msg =
{ setState : State -> msg
, dropdownBlur : msg
, tabIndex : Basics.Int 
}

The config for the dropdown. setState should be a message which updates the dropdowns state. dropdownBlur is a message that is fired whenever the dropdown or it's trigger loses focus. NOTE: dropdownBlur can occur when the user clicks into a child element of the dropdown, so when handling this message use the dropDownCurrentlyClicked function to decide whether to close the dropdown on blur.

A tab index must be given for the dropdown, otherwise it cannot recieve focus.

attributes : State -> Config msg -> Visibility -> List (Html.Attribute msg)

These go on the dropdown container itself, such as a div. You'll need to style the dropdown yourself. The function accepts a dropdown state, a config and whether it should be visible or not (which can come from your model)

dropdownView : Model -> Html Msg
dropdownView model =
    div
        ([ style "width" "150px"
        , style "height" "200px"
        , style "border" "1px solid black"
        ]
            ++ Dropdown.attributes model.dropdownState dropDownConfig model.dropdownVisbility
        )
        [ button [] [ text "Click here" ] ]

triggerAttributes : Config msg -> List (Html.Attribute msg)

Put these on your dropdown trigger: anything which causes a dropdown to open, like a button or input text box. Remember to also set an event on the trigger to actually open the dropdown.

dropdownButton : Html Msg
dropdownButton =
    button
        ([ onClick OpenDropdown ] ++ Dropdown.triggerAttributes dropDownConfig)
        [ text "Open dropdown" ]