elm

elmでwebアプリ作成 6 〜 施設一覧ページ

作りたいものは、商業ビル、観光スポット、コンサートホール、動物園、水族館、公共施設、体育館、遊園地等の施設情報をまとめるサイトです。
行く際の注意点、開館時間、トイレの有無・場所、ゴミ箱の有無・場所、食事できる店の有無・場所、ATMの有無・場所、閉館情報、などを投稿してシェアできるようにしたいです(トイレの場所とATMの場所は意外と重要)。

だいたい以下のような機能があるでしょう(ページと機能がごっちゃになってますが)。

  • ホーム画面
  • 検索窓
  • 施設一覧
  • おすすめ施設
  • 個別施設ページ
  • コメント欄
  • 行ってきました!(いいね!ボタンみたいなやつ?)

まずは、施設一覧ページを作ります。

施設データについて改めて確認します(elmでwebアプリ作成 1 〜 モックDB)。

以下のフィールドを持つjsonです。

  • id: string
  • name: string
  • opening: [string]
  • address: string
  • postcode: string
  • web_site: string
  • description: string

まずはこのデータをモデルとして定義しましょう。モデルには、この後これ以外のデータも追加する予定なので、施設リストデータはレコードの1フィールとしておきます。こうしておけば後で他のフィールドの追加が簡単にできます(以下の3,4行目)。

idについては型エイリアスFacilityIdを定義しておきます。こうするとこのidを受け取る関数の型を見ればある程度その機能を推定できそうです。他のフィールドについても型エイリアスを作っても良いのですが、やりすぎると今度は関数の汎用性が失われていくので今回はidだけにしておきます(11,12行目)。

openingは["9:00","20:00"]のように、常に開館時間と閉館時間の2要素の文字列のリストなので、elmではタプルとして(String,String)と定義します(17行目)。

src/Models.elm

module Models exposing (..)

type alias Model =
    { facilities: List Facility }

initialModel : Model
initialModel =
    { facilities = [ Facility "1" "施設" ("9:00", "21:00") "○○市○○区1-2-3" "000-0000" "https://nothing.no" "デフォルト施設" ]
    }

type alias FacilityId =
    String

type alias Facility =
    { id: FacilityId
    , name: String
    , opening: (String, String)
    , address: String
    , postcode: String
    , web_site: String
    , description: String
    }

では、このモデルを使用するようにModelsのインポートにinitialModelを追加し、initを修正します。

src/Main.elm

module Main exposing (..)

import Html exposing (program)
import Models exposing (Model, initialModel) -- ※変更箇所
import Msgs exposing (Msg)
import Update exposing (update)
import View exposing (view)


init : (Model, Cmd Msg)
init =
    ( initialModel, Cmd.none ) -- ※変更箇所

subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.none

main : Program Never Model Msg
main =
    program
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

新たにファイルを作って施設一覧をリスト表示する関数を作成します。少し複雑になってきていますが、単にページのタイトル(nav)と、テーブル作成の関数(list)、テーブルの1行を作成する関数(facilityRow)を定義しているだけです。テーブルの行数(施設数)は変わる可能性があるので、一行作成する関数を作っておいて、それを施設リスト(facilities)にマップしています(以下36行目)。

src/Facilities/List.elm

module Facilities.List exposing (..)

import Html exposing (..)
import Models exposing (Facility)
import Msgs exposing (Msg)



view : List Facility -> Html Msg
view facilities =
    div []
        [ nav
        , list facilities
        ]

nav : Html Msg
nav =
    div []
        [ div [] [ text "施設一覧" ] ]

list : List Facility -> Html Msg
list facilities =
    div []
        [ table []
            [ thead []
                [ tr []
                    [ th [] [ text "Id" ]
                    , th [] [ text "Name" ]
                    , th [] [ text "Opening" ]
                    , th [] [ text "Address" ]
                    , th [] [ text "Postal code" ]
                    , th [] [ text "URL" ]
                    , th [] [ text "description" ]
                    ]
                ]
            , tbody [] (List.map facilityRow facilities)
            ]
        ]

facilityRow : Facility -> Html Msg
facilityRow facility =
    let
        (open, close) = facility.opening
    in
        tr []
            [ td [] [ text facility.id ]
            , td [] [ text facility.name ]
            , td [] [ text (open ++ " - " ++ close) ]
            , td [] [ text facility.address ]
            , td [] [ text facility.postcode ]
            , td [] [ text facility.web_site ]
            , td [] [ text facility.description ]
            ]

src/View.elm

src/Facilities/View.elmのビューを呼び出すように変更します。

module View exposing (..)

import Facilities.List
import Html exposing (Html, div)
import Models exposing (Model)
import Msgs exposing (Msg)

view : Model -> Html Msg
view model =
    div []
        [ page model ]

page : Model -> Html Msg
page model =
    Facilities.List.view model.facilities

では再びyarn startして表示を確認して見ましょう。

cssを何も入れていないのでとても味気ないページが表示されました。誰か私にデザインセンスをください。

次は、jsonサーバーの簡易DBからデータを取ってきて一覧のところに表示できるようにしていきます。
elmでwebアプリ作成 7 〜 webAPIで取ってきたデータを表示

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です