Posted at
Fringe81Day 22

ElmでプルダウンメニューのonChangeイベント

More than 1 year has passed since last update.

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には選択されたoptionvalueが入ってきます。


説明

ElmではHtmlイベントを捕捉して何かをやらすには Html.Events を使いますが、onChange関数は定義されていません。


Events.elm

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で見つけました!

これを使うもよし、実装を参考に作るものよし!


参考