elm / virtual-dom

The foundation of HTML and SVG in Elm.
https://package.elm-lang.org/packages/elm/virtual-dom/latest
BSD 3-Clause "New" or "Revised" License
209 stars 80 forks source link

Html.select selected value is reset in Firefox #134

Closed MethodGrab closed 6 years ago

MethodGrab commented 6 years ago

Elm: 0.19 Browser: Firefox v61.0.2 x64 (Windows 10 & Ubuntu 16.04)

Elm 0.19 seems to have a problem with select inputs in Firefox. I have a tick subscription that updates the current time every second. When I try to select a value from an Html.select element in Firefox, as soon as the tick fires, it resets the selected value back to the value specified by Html.Attributes.selected instead of leaving it where my cursor is.

I'm not sure if this issue is related to elm/html or elm/virtual-dom.

To reproduce:

  1. Open https://ellie-app.com/3cysgr6wX2Sa1 https://ellie-app.com/3cFs4FWXhQxa1 in Firefox
  2. Open the select dropdown
  3. Move the cursor over another value other than the initially selected value (4)
  4. Observe that when the tick fires, it resets the selected option back to what it was before.

SSCCE

module Main exposing (main)

import Browser
import Html as H exposing (Html)
import Html.Attributes as HA
import Html.Events as HE
import Html.Lazy as HL
import Time exposing (Posix)

main : Program () Model Msg
main =
    Browser.element
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

type alias Model =
    { time1 : Maybe Posix
    }

init : a -> ( Model, Cmd msg )
init flags =
    ( { time1 = Nothing
      }
    , Cmd.none
    )

subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.batch
        [ --
          Time.every 1000 Tick1
        ]

type Msg
    = Tick1 Posix

update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    case msg of
        Tick1 time1 ->
            ( { model | time1 = Just time1 }, Cmd.none )

selectView : List String -> String -> Html msg
selectView options selected =
    H.select []
        (options |> List.map (optionView selected))

optionView selected option =
    H.option
        [ HA.value option
        , HA.selected (option == selected)
        ]
        [ H.text option ]

view : Model -> Html Msg
view model =
    selectView [ "1", "2", "3", "4", "5" ] "4"
harrysarson commented 6 years ago

Here is a reduced SSCCE:

module Main exposing (main)

import Browser
import Html as H exposing (Html)
import Html.Attributes as HA
import Time exposing (Posix)

main : Program () Model Msg
main =
    Browser.element
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

type alias Model = ()

type Msg = Tick

init : a -> ( Model, Cmd msg )
init flags =
    ( (), Cmd.none )

subscriptions : Model -> Sub Msg
subscriptions model =
    Time.every 1000 (always Tick)

update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    ( (), Cmd.none )

optionView selected option =
    H.option
        [ HA.selected (option == selected)
        , HA.value option -- remove this line to fix
        ]
        [ H.text option ]

view : Model -> Html Msg
view model =
    H.select []
        ([ "1", "2", "3", "4", "5" ] 
            |> List.map (optionView "4")
        )

Note: removing the line I marked -- remove this line to fix prevents the selected option reverting.