Fringe81 Advent Calendar 2017の22日目です。
ElmでのonChange
イベントの捕捉の仕方を書いた日本語の記事を見つけられなかったので書きました。
以下が前提です。
- Elm 0.18
elm-lang/html/2.0.0/Html.Events
やりたいこと
プルダウンメニューの選択が変わった場合に何かやらせたい。
やりかた
まずonChange
関数を作る。
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events as Events exposing (on)
import Json.Decode as Json
onChange : (String -> msg) -> Attribute msg
onChange handler =
on "change" (Json.map handler Events.targetValue)
次に使い方
type Msg
= Change String
view : Model -> Html Msg
view model =
let
handler selectedValue =
Change selectedValue
in
div []
[ div [] [ text selectedText ]
select [ onChange handler ]
[ option [ value "a" ] [ text "a" ]
, option [ value "b" ] [ text "b" ]
, option [ value "c" ] [ text "c" ]
]
これでプルダウンメニューで変更が起きた時にChange
メッセージが発生して、selectedValue
には選択されたoption
のvalue
が入ってきます。
説明
ElmではHtmlイベントを捕捉して何かをやらすには Html.Events を使いますが、onChange
関数は定義されていません。
module Html.Events exposing
( onClick, onDoubleClick
, onMouseDown, onMouseUp
, onMouseEnter, onMouseLeave
, onMouseOver, onMouseOut
, onInput, onCheck, onSubmit
, onBlur, onFocus
, on, onWithOptions, Options, defaultOptions
, targetValue, targetChecked, keyCode
)
ではどうすれば良いかというとことで、Documentを見てみます。
on : String -> Decoder msg -> Attribute msg
Create a custom event listener. Normally this will not be necessary, but you have the power! Here is how onClick is defined for example:
on
関数を使うとcustom event listener
を作れるみたいですね。
DocumentにはonClick
を作る実装が書いてあります。
というかよーく見てみるとonClick
関数そのもの実装でした。
import Json.Decode as Json
onClick : msg -> Attribute msg
onClick message =
on "click" (Json.succeed message)
その後には引数の話が書いてある。
The first argument is the event name in the same format as with JavaScript's addEventListener function.
The second argument is a JSON decoder. Read more about these here. When an event occurs, the decoder tries to turn the event object into an Elm value. If successful, the value is routed to your update function. In the case of onClick we always just succeed with the given message.
第1引数は、JavaScriptのaddEventListener
を使う時の名前。
第2引数は、JSON decoder
。
なのでonChange
関数を作る場合には、
第1引数に"change"
、第2引数にmsg
に変換する関数を与えています。
ちなみにJSON decoder
については下記の素晴らしい記事がありました。
まとめ
on
関数はHTML.Events
に定義されていないイベントも扱える便利な関数ですね。
今回説明したソースの完全版はここにあります。
ところで、プルダウンメニューって複数選択も可能でしたよね。。。
安心して下さい!Elm Packageで見つけました!
これを使うもよし、実装を参考に作るものよし!