LoginSignup
33
3

More than 5 years have passed since last update.

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

Posted at

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

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

参考

33
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
3