スポンサーリンク

Elm0.19でlocalStorage利用のTODOアプリ(2)elm/timeでMonthの表示

2019年5月6日

ElmでTodoアプリを作りたいシリーズの第1回では、flagsを用いて、elmアプリ初期化時にindex.html(JavaScript)からmain.js(src/Main.elmをコンパイルしたもの)にデータを送りました。

今回は、前回の続きで、
https://superhahnah.com/elm-flags/ の後半を写経しながら、以下の2つを行いたいと思います。

以下の2つを行いたいと思います。

  • フラグflagsでindex.html(JavaScript)からElm(正確には、src/Main.elm)に、時刻を含む複数のデータを送る
  • src/Main.elmにおいて、flagsで時刻を含む複数データを受け取り、時刻を年月日時分秒で表示する(elm/timeパッケージの使用方法)

スポンサーリンク

Elmで月を表示するためには自分で関数を定義しないといけない

最初、elm/timeパッケージの公式を見てもMonthのみ表示することができず非常に困りました。

月はTime.Monthとしてカスタムタイプで定義されているため、Int型のHourやMinuteのように、VIEWで表示するときにString.fromIntを用いて表示することができません。かなり面倒ですが、月を表示するための関数を自分で作らないといけません。しかし、以下にありましたの!感謝!

https://github.com/ababup1192/elm-firebase-chat/blob/master/src/Main.elm

開発環境

Windows 10 Pro
Chrome
VisualStudioCode 1.32.3
git version 2.20.1.windows.1
nvm 1.1.7
node 10.2.0
npm 6.4.1
elm 0.19.0-bugfix6
elm-format 0.8.1
VisualStudioCodeの拡張機能でelmをインストールして、settings.jsonに以下のようにelmを設定。
(『Alt + Shift + F』と『Ctrl + S』を使用。)

    "[elm]": {
        "editor.formatOnSave": true
    },

前回までのソースコード

https://github.com/adash333/elm-bulma-flag

こちらのコードを編集していきます。

index.html(JavaScript)からflagsを介して複数データを送る

Javascriptの Date.now()メソッドは、1 January 1970 00:00:00 UTC(世界協定時 – 1970年1月1日 0時0分0秒)からの経過時間をミリ秒で返します。

この数値を、datetimeという名前をつけて、Elm側に送り、表示したいと思います。

変更前

<script>
  var app = Elm.Main.init({
    node: document.getElementById('elm'),
    flags: 4
  });
</script>

変更後

<script>
  var app = Elm.Main.init({
    node: document.getElementById('elm'),
    flags: {greeting: "Hello Again, World!", times: 8, datetime: Date.now() }
  });
</script>

elm/timeパッケージのインストール

VisualStudioCodeでCtrl+@でターミナル画面を開き、以下を入力して、elm/time パッケージをインストールします。

何か聞かれたらEnterを押します。

elm install elm/time

参考:
https://package.elm-lang.org/packages/elm/time/1.0.0/

https://package.elm-lang.org/packages/elm-lang/core/latest/Date

MODELを編集

今回はflagsを介して、index.html(Javascript)から、greeting, times, datetimeの3個を受け取りますので、src/Main.elmのMODELを以下のように変更します。

また、初期値としてinitもflagsを介して受け取った値を入力します。

src/Main.elm

(変更前)

(変更後)

UPDATEの編集

UPDATEは特に変更はありません。

VIEWの編集(1)

先に、greetings を timesの回数分だけ繰り返すように変更します

section [ class "section" ]
  [ div [ class "container" ]
    [ ul [ class "list is-hoverable" ]
      (List.repeat model.times (li [ class "list-item" ] [ text model.greeting ]))
    ]
  ]

(変更前)

(変更後)

これで、Elmアプリ上で、index.html(JavaScript)で指定したgreetingsの文字列を、times回数繰り返して表示することができました。

VIEWの編集(2)

さて、 index.html(JavaScript)で指定した 日付(をUNIX TIMEに変換した数値)を、Elmでmodel.timeとして受け取ったものを、表示します。

elm/time パッケージを用いるので、importします。

後で用いるのですが、特に、exposingの中のMonth(..)が大事です。

import Time exposing (Month(..), millisToPosix, toDay, toHour, toMinute, toMonth, toSecond, toYear, utc)

次に、VIEWの上の方に、時刻を表示するコードを書きます。Monthだけはややこしいので、あとで定義する関数” omissionMonth ”を使用して、とりあえず書いておきます。

h1 [ class "title" ]
  [ text
    ("Initialized at "
      ++ String.fromInt (toYear utc (millisToPosix model.datetime))
      ++ " "
      ++ (toMonth utc (millisToPosix model.datetime)
              |> omissionMonth
          )
      ++ " "
      ++ String.fromInt (toDay utc (millisToPosix model.datetime))
      ++ " "
      ++ String.fromInt
          (toHour utc (millisToPosix model.datetime))
      ++ ":"
      ++ String.fromInt (toMinute utc (millisToPosix model.datetime))
      ++ ":"
      ++ String.fromInt (toSecond utc (millisToPosix model.datetime))
      ++ " UTC"
    )
  ]

(変更前)

(変更後)

突然ですが、ここで、『パイプ演算子 pipe operator』を使用しています。(使用しない方が見やすかったかもしれませんが、、、)

(toMonth utc (millisToPosix model.datetime)
   |> omissionMonth
)

上記のコードは、以下と同じです。

omissionMonth (toMonth utc (millisToPosix model.datetime))

参考: 関数の型
https://guide.elm-lang.jp/appendix/function_types.html

参考2:(|>) : a -> (a -> b) -> b

https://package.elm-lang.org/packages/elm/core/latest/Basics#(|%3E)

MonthをVIEWで表示できるようにomissionMonth関数を定義する

以下のサイトのomissionMonth関数をコピペします。
(いつか、toDate関数もコピペさせていただきたいと思っていますが、、、)

https://qiita.com/ababup1192/items/803bd2e66461c70bf7e7

VIEWの最後に、omissionMonth関数を定義する以下のコードをコピペします。

omissionMonth : Time.Month -> String
omissionMonth month =
    case month of
        Jan ->
            "Jan"

        Feb ->
            "Feb"

        Mar ->
            "Mar"

        Apr ->
            "Apr"

        May ->
            "May"

        Jun ->
            "Jun"

        Jul ->
            "Jul"

        Aug ->
            "Aug"

        Sep ->
            "Sep"

        Oct ->
            "Oct"

        Nov ->
            "Nov"

        Dec ->
            "Dec"

src/Main.elmをコンパイルしてmain.jsを作成

VisualStudioCodeでCtrl+@でターミナル画面を開き、以下を入力します。

elm make src/Main.elm --output=main.js

その後、index.htmlをChromeで開くと、以下のような画面になります。

参考3:  日付を 日本風の時間フォーマットに する場合のソースコード

https://github.com/ababup1192/elm-firebase-chat/commit/75b3bfa945a86f54fa0c926eb087d051b7a79a8e

ソースコードとDEMOサイト

ソースコード:https://github.com/adash333/elm-bulma-flag2

DEMOサイト: https://adash333.github.io/elm-bulma-flag2/

参考にした本

以下の本のP172-P178を参考にしました。

bulma,Elm

Posted by twosquirrel