Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

on UI.valueChange not triggered until ESC pressed #171

Open
jerbaroo opened this issue Mar 19, 2017 · 3 comments
Open

on UI.valueChange not triggered until ESC pressed #171

jerbaroo opened this issue Mar 19, 2017 · 3 comments

Comments

@jerbaroo
Copy link
Contributor

Here is the code for the problem described below.

main :: IO ()
main = do
  startGUI defaultConfig setup

setup :: Window -> UI ()
setup window = do
  (event, handler) <- liftIO $ newEvent
  behavior         <- stepper "No file selected." event
  text             <- UI.div # sink UI.text behavior
  input            <- UI.input # set UI.type_ "file"
  -- input            <- UI.button # set UI.text "file"
  getBody window #+ map element [text, input]
  on UI.valueChange input $ const $ do
    liftIO $ handler "File selected."

Problem

  • Initially the text of the div is "No file selected.".
  • Click the input and select a file.
  • Observe the text of the div not change.
  • Press the ESC key.
  • Observe the text of the div change to "File selected.". (Chrome only)
  • Use a button instead of input, by using the commented line, and the problem is the same.

Reproduce

  • git clone https://github.com/barischj/threepenny-slow-valuechange
  • cd threepenny-slow-valuechange
  • stack setup && stack build && stack exec threepenny-slow-frp-exe
  • Open browser to localhost:8023 and follow problem steps.

System

  • OS X 10.11.6
  • Chrome 56.0.2924.87

Additional notes:

  • On Firefox 51.0.1 and Safari 10.0.3 the text of the div won't update even after pressing ESC.
@jerbaroo
Copy link
Contributor Author

jerbaroo commented Mar 19, 2017

Fix

A fix for this was not to use UI.valueChange which uses the DOM keydown event, but instead use a new event function which uses the DOM change event:

...
  on change input $ const $ do
    liftIO $ handler "File selected."

-- |change event.
change :: Element -> Event ()
change = void . domEvent "change"

The documentation for the DOM change event is very similar to that of UI.valueChange:

UI.valueChange:

Event that occurs when the user changes the value of the input element.

change:

The change event is fired for <input>, <select>, and <textarea> elements when a change to the element's value is committed by the user.

@HeinrichApfelmus
Copy link
Owner

The main reason why I used the keypress event was that this makes sure that the user is the one who did the change. (This is relevant for a smooth FRP experience.) The documentation you mention indicates that the change event ensures the same thing, and I'm inclined to use it in the implementation of valueChange.

However: Do browser really follow this specification, or do they also emit a change event when the contents of the DOM element was changed programmatically, e.g. with input.val('foo') (in jQuery notation)? The latter would be undesirable.

@jwaldmann
Copy link

jwaldmann commented Nov 12, 2017

I ran into this (or similar) problem when I wanted to use sliders (input type = range) as input.

https://gitlab.imn.htwk-leipzig.de/waldmann/matrix-game/blob/master/src/Main.hs#L101

@maweki solved it with onDomEvent "input". This is currently is not exported?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants