フォーム


サンプルコードをダウンロードするかオンラインエディタで試してください。


ここでは基本的なフォームを作成します。名前、パスワード、パスワード(確認用)のフィールドを持ったフォームです。また簡単な入力の検証(2つのパスワードが一致しているか)も行います。 この検証機能を選んだのに深い意味はなく、単に追加するのが単純だからです。

今回のコードは少し長いですが、各コードがどう動くかの説明の前に、やはりコードに目を通しておくことは価値があることだと思います。

import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)



-- MAIN


main =
  Browser.sandbox { init = init, update = update, view = view }



-- MODEL


type alias Model =
  { name : String
  , password : String
  , passwordAgain : String
  }


init : Model
init =
  Model "" "" ""



-- UPDATE


type Msg
  = Name String
  | Password String
  | PasswordAgain String


update : Msg -> Model -> Model
update msg model =
  case msg of
    Name name ->
      { model | name = name }

    Password password ->
      { model | password = password }

    PasswordAgain password ->
      { model | passwordAgain = password }



-- VIEW


view : Model -> Html Msg
view model =
  div []
    [ viewInput "text" "Name" model.name Name
    , viewInput "password" "Password" model.password Password
    , viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
    , viewValidation model
    ]


viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
  input [ type_ t, placeholder p, value v, onInput toMsg ] []


viewValidation : Model -> Html msg
viewValidation model =
  if model.password == model.passwordAgain then
    div [ style "color" "green" ] [ text "OK" ]
  else
    div [ style "color" "red" ] [ text "Passwords do not match!" ]

フィールドが複数ある点を除けば、テキストフィールドで紹介したコードによく似ています。どこがどうなっているのか、一つずつ見ていきましょう!

いつものように、モデルを考えることからはじめます。 3つのテキストフィールドが作られることが分かっているので、このようにします。

type alias Model =
  { name : String
  , password : String
  , passwordAgain : String
  }

とってもいいですね。ちゃんと書けているように見えます。これらのフィールドはそれぞれ別々に変更されるはずですから、今回のメッセージはこれら3つのフィールドの変更という処理を説明するようなものになるはずです。

type Msg
  = Name String
  | Password String
  | PasswordAgain String

このコードを見ると updateの処理がとても機械的なことがわかります。対応するテキストフィールドを更新するだけです。

update : Msg -> Model -> Model
update msg model =
  case msg of
    Name name ->
      { model | name = name }

    Password password ->
      { model | password = password }

    PasswordAgain password ->
      { model | passwordAgain = password }

ですが、 view ではすこし気の利いたことをしています。

view : Model -> Html Msg
view model =
  div []
    [ viewInput "text" "Name" model.name Name
    , viewInput "password" "Password" model.password Password
    , viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
    , viewValidation model
    ]

まず、4つの子ノードを持つ <div>を作ります。 ただし、elm/htmlの関数を直接使うのではなく、よりコードを簡潔にするために自分で定義したElmの関数を呼んでいます。以下のように定義した viewInput が最初に3つ並んでいますね。

viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
  input [ type_ t, placeholder p, value v, onInput toMsg ] []

viewInput "text" "Name" model.name Nameと書くことでノードを作れます。これは、HTMLで <input type="text" placeholder="Name" value="Bill"> と書くのと同じようなものです。このノードはユーザーの入力時に、 Name "Billy" のようなメッセージを update に送ります。

4つ目のノードはもっと面白いです。 viewValidation の呼び出しです。

viewValidation : Model -> Html msg
viewValidation model =
  if model.password == model.passwordAgain then
    div [ style "color" "green" ] [ text "OK" ]
  else
    -- 訳注: "Passwords do not match!" は "パスワードが一致しません!" の意味です。
    div [ style "color" "red" ] [ text "Passwords do not match!" ]

この関数はまず、二つのパスワードを比較します。一致すると、緑色の文字で入力に問題がないことを示すメッセージを表示します。一方、一致しない場合は赤色の文字でエラーを修正するために役立つメッセージを表示します。

こうした補助関数をみると、HTMLのシンタックスをそのまま用いるのではなく、現状のように通常のElmコードでHTMLを表現できるHTMLライブラリの利点がわかります。すべてのコードをベタ書きでviewに書くことももちろんできますが、Elmにおいて補助関数をつくって部品をくくりだすことはいたって普通のことですので、view関数のコードだろうが補助関数を使えば良いんです。理解するのが難しくなってきた?そしたらこのあたりの説明も、全部ここにベタ書きするんじゃなくて「補助関数」として別の節に分けて書いたほうが良いのかもしれないですね!

練習問題: viewValidationを分割する利点は、簡単に機能を追加できることです。もし、これを読みながらコードいじっているなら(なるべくそうしましょう!)次の機能を追加してみてください。

  • パスワードが8文字より長いか確認する。
  • パスワードが大文字、小文字、数字を含むか確認する。
  • 年齢のフィールドを追加して、入力値が数字かどうかを確認する。
  • 提出ボタンを追加する。ボタンが押された 、エラーがあれば表示する。

上記を試す際は、 String モジュールに含まれる補助関数を必ず使用しましょう! また、サーバーとの通信を行う前にまだ学ぶことがあります。試すのはHTTPのパートまで読んでからにしましょう。適切に順を追って説明していくので、かなり簡単になるはずです。

Note: 入力の検証を行うための汎用的なライブラリを作っても、苦労の割には大した結果を得られないでしょう。そんなライブラリを作らなくても、こうしたチェックはElmの通常の関数を使うだけで実現できる場合がほとんどだと思います。いくつかの引数をとって、BoolMaybe を返せばいいのです。例えば、2つの文字列が等しいかどうかをチェックするのに、あえてライブラリを使う必要なんてあるんでしょうか? 我々が知る限りでは、特別に何か追加でライブラリを使わなくても、実現したい特定の状況に合わせた具体的なロジックを書くことが最もシンプルなコードにつながります。なので、より複雑な方法が必要だと判断する前に、必ずまずこの最も単純なやり方を試してみてください!

results matching ""

    No results matching ""