Keep input value on focus when item is programatically selected

This commit is contained in:
Tom Nunn 2023-03-31 11:31:09 +01:00
parent 5dd545f911
commit ece80633d6
7 changed files with 25 additions and 8 deletions

View File

@ -110,6 +110,16 @@ exampleProgramTest =
>> Query.has [ Selector.attribute (Html.Attributes.value "🇦🇶 Antarctica") ]
)
|> ProgramTest.expectModel (.countrySelect >> Select.toValue >> Expect.equal (Countries.fromCode "AQ"))
, Test.test "Programatically selecting an item and the focusing the input keeps the selected item input value" <|
\() ->
programTest (Countries.fromCode "AQ")
|> focusInput
|> ProgramTest.expectView
(Query.find
[ Selector.id (Select.toInputElementId countrySelect)
]
>> Query.has [ Selector.attribute (Html.Attributes.value "🇦🇶 Antarctica") ]
)
]

View File

@ -9,6 +9,7 @@ module Internal.Model exposing
, isLoading
, isOpen
, isRequestFailed
, onInputChange
, openMenu
, requiresNewFilteredOptions
, selectOption
@ -296,6 +297,11 @@ setSelected a (Model model) =
setInputValue : String -> Model a -> Model a
setInputValue v (Model model) =
Model { model | inputValue = v }
onInputChange : String -> Model a -> Model a
onInputChange v (Model model) =
Model
{ model
| inputValue = v

View File

@ -7,7 +7,7 @@ import Internal.Option exposing (Option)
type Msg a
= InputChanged String (List (Option a))
| OptionClicked (Option a)
| InputFocused (Maybe ( List a, List (Option a) ))
| InputFocused String (Maybe ( List a, List (Option a) ))
| GotNewFilteredOptions ( List a, List (Option a) )
| InputClicked
| InputLostFocus

View File

@ -28,7 +28,7 @@ update_ { request, requestMinInputLength, debounceRequest, onFocus, onLoseFocus,
case msg of
InputChanged val filteredOptions ->
( model
|> Model.setInputValue val
|> Model.onInputChange val
|> Model.highlightIndex
(if String.isEmpty val then
Nothing
@ -74,7 +74,7 @@ update_ { request, requestMinInputLength, debounceRequest, onFocus, onLoseFocus,
, Effect.none
)
InputFocused maybeOptions ->
InputFocused inputValue maybeOptions ->
(case maybeOptions of
Just ( items, options ) ->
Model.setItems items model
@ -83,6 +83,7 @@ update_ { request, requestMinInputLength, debounceRequest, onFocus, onLoseFocus,
Nothing ->
model
)
|> Model.setInputValue inputValue
|> onFocusMenu tagger (request /= Nothing)
|> withEffect (\_ -> Effect.emitJust onFocus)

View File

@ -36,7 +36,7 @@ hijackKey menuOpen tagger key =
onInput : (Msg a -> msg) -> (a -> String) -> Model a -> ViewConfigInternal a attribute view -> String -> msg
onInput onChange itemToString model viewConfig v =
InputChanged v
(Model.setInputValue v model
(Model.onInputChange v model
|> Model.toFilteredOptions False viewConfig.minInputLength itemToString viewConfig.filter
)
|> onChange
@ -46,10 +46,10 @@ onFocus : (Msg a -> msg) -> (a -> String) -> Model a -> ViewConfigInternal a att
onFocus onChange itemToString model viewConfig filteredOptions =
Html.Events.on "focus" <|
if Model.requiresNewFilteredOptions model then
Decode.lazy (\_ -> Decode.succeed (onChange <| InputFocused (Just <| optionsUpdate itemToString model viewConfig filteredOptions)))
Decode.lazy (\_ -> Decode.succeed (onChange <| InputFocused (Model.toInputText itemToString model) (Just <| optionsUpdate itemToString model viewConfig filteredOptions)))
else
InputFocused Nothing
InputFocused (Model.toInputText itemToString model) Nothing
|> onChange
|> Decode.succeed

View File

@ -142,7 +142,7 @@ setSelected =
-}
setInputValue : String -> Select a -> Select a
setInputValue =
Model.setInputValue
Model.onInputChange
{-| Close the menu

View File

@ -142,7 +142,7 @@ setSelected =
-}
setInputValue : String -> Select a -> Select a
setInputValue =
Model.setInputValue
Model.onInputChange
{-| Close the menu