Catalyst

Elm 笔记(3):表单

官方例子三: Forms 学习

概念

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 }
  • 接收每个类型的消息并修改Record

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
    ]
  • 这里没像前面一样使用普通的input,而使用了函数,方便统一建立和修改。
viewInput : String -> String -> String -> (String -> msg) -> Html msg
viewInput t p v toMsg =
  input [ type_ t, placeholder p, value v, onInput toMsg ] []
  • viewInput函数,输入 input 类型,占位符,绑定的值和响应函数生成文本框。
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!" ]
  • viewValidation验证输入的函数。

练习

最后完成文档后留的作业:

  1. 验证:密码必须长于 8 位。
  2. 验证:密码必须含有大写、小写字母和数字。

(竟然绕了个大圈子去看elm/parser……其实根本用不到)

module Form exposing (main)

import Browser
import Html exposing (Html, div, input, text)
import Html.Attributes exposing (placeholder, style, type_, value)
import Html.Events exposing (onInput)



-- MAIN


main : Program () Model Msg
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 =
    -- elm 使用 /= 表示 !=
    if model.password /= model.passwordAgain then
        div [ style "color" "red" ] [ text "密码不匹配" ]

    else if String.length model.password < 8 then
        div [ style "color" "red" ] [ text "密码必须长于8位" ]

    else if String.length (String.filter Char.isDigit model.password) == 0 || String.length (String.filter Char.isUpper model.password) == 0 || String.length (String.filter Char.isLower model.password) == 0 then
        div [ style "color" "red" ] [ text "密码必须含有大写、小写字母和数字。" ]

    else
        div [ style "color" "green" ] [ text "通过" ]