Autocomplete contains the main logic to handle auto-complete. The state and logic of Autocomplete should reside within your model. Please refer to our examples to see how it all linked up.
To render the Autocomplete, please refer to Autocomplete.View
or Autocomplete.Styled
.
Opaque type of Autocomplete state
Internal.Msg a
Opaque type of Autocomplete internal msg
Internal.Choices a
Record to hold the query and choices for your fetcher function.
type alias Choices a =
{ query : String
, choices : List a
, ignoreList : List a
}
fetcher : Autocomplete.Choices String -> Task String (Autocomplete.Choices String)
fetcher lastChoices =
let
dogs =
[ "Hunter"
, "Polo"
, "Loki"
, "Angel"
, "Scout"
, "Lexi"
, "Zara"
, "Maya"
, "Baby"
, "Bud"
, "Ella"
, "Ace"
, "Kahlua"
, "Jake"
, "Apollo"
, "Sammy"
, "Puppy"
, "Gucci"
, "Mac"
, "Belle"
]
insensitiveStringContains : String -> String -> Bool
insensitiveStringContains a b =
String.contains (String.toLower a) (String.toLower b)
choiceList : List String
choiceList =
if String.length lastChoices.query == 0 then
[]
else
List.filter (insensitiveStringContains lastChoices.query) dogs
in
Task.succeed { lastChoices | choices = choiceList }
{ query : String
, choices : List a
, ignoreList : List a
, selectedIndex : Maybe Basics.Int
, status : ViewStatus
}
Record to expose common values of Autocomplete to be used for display
A useful union type for rendering the correct view for each state of Autocomplete
init : Choices a -> (Choices a -> Task String (Choices a)) -> Autocomplete a
Initialize the Autocomplete state with your fetcher function
init : ( Model, Cmd Msg )
init =
( { -- Initialize the Autocomplete state
autocompleteState = Autocomplete.init { query = "", choices = [], ignoreList = [] } fetcher
, selectedValue = Nothing
}
, Cmd.none
)
fetcher : Autocomplete.Choices String -> Task String (Autocomplete.Choices String)
fetcher lastChoices =
let
dogs =
[ "Hunter"
, "Polo"
, "Loki"
, "Angel"
, "Scout"
, "Lexi"
, "Zara"
, "Maya"
, "Baby"
, "Bud"
, "Ella"
, "Ace"
, "Kahlua"
, "Jake"
, "Apollo"
, "Sammy"
, "Puppy"
, "Gucci"
, "Mac"
, "Belle"
]
insensitiveStringContains : String -> String -> Bool
insensitiveStringContains a b =
String.contains (String.toLower a) (String.toLower b)
choiceList : List String
choiceList =
if String.length lastChoices.query == 0 then
[]
else
List.filter (insensitiveStringContains lastChoices.query) dogs
in
Task.succeed { lastChoices | choices = choiceList }
update : Msg a -> Autocomplete a -> ( Autocomplete a, Platform.Cmd.Cmd (Msg a) )
Updates the Autocomplete state
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
-- This is the main wire-up to pass Autocomplete Msg to Autocomplete state
OnAutocomplete autocompleteMsg ->
let
( newAutocompleteState, autoCompleteCmd ) =
Autocomplete.update autocompleteMsg model.autocompleteState
in
( { model | autocompleteState = newAutocompleteState }
, Cmd.map OnAutocomplete autoCompleteCmd
)
-- ...
reset : Choices a -> Autocomplete a -> Autocomplete a
Reset the Autocomplete State
There are many scenarios Autocomplete can handle using the reset
.
On selected value, display selectedValue but remove all choices:
Autocomplete.reset
{ query = Maybe.withDefault query selectedValue
, choices = []
, ignoreList = []
}
autocompleteState
On selected multiple values, ignore selected values but still display the choices:
Autocomplete.reset
{ query = ""
, choices = Autocomplete.choices autocompleteState
, ignoreList = selectedValueList
}
autocompleteState
selectedValue : Autocomplete a -> Maybe a
Returns the selectedValue
viewState : Autocomplete a -> ViewState a
Returns the ViewState of the Autocomplete to render the view. Remember to attach Autocomplete events to your view! See Autocomplete.View
query : Autocomplete a -> String
Returns the query of the Autocomplete
choices : Autocomplete a -> List a
Returns the current list of choices
selectedIndex : Autocomplete a -> Maybe Basics.Int
Returns the selected index of the Autocomplete
isSelected : Maybe Basics.Int -> Basics.Int -> Basics.Bool
Helper function to calculate if an index is selected
renderChoice : (Int -> List (Attribute Msg)) -> Maybe Int -> Int -> String -> Html Msg
renderChoice events selectedIndex index s =
Html.div
(if Autocomplete.isSelected selectedIndex index then
Html.Attributes.style "backgroundColor" "#EEE" :: events index
else
Html.Attributes.style "backgroundColor" "#FFF" :: events index
)
[ Html.text s ]