Skip to content

Instantly share code, notes, and snippets.

@pdamoc pdamoc/App.elm
Last active Jul 4, 2019

Embed
What would you like to do?
Demo on how to split code across multiple pages.
module Main exposing (..)
import Html exposing (Html, div, hr, text)
import Html.App as App
import Navigation
-- APP IMPORTS
import FirstPage
import SecondPage
import Router exposing (..)
import Widgets exposing (..)
-- WIRING
main : Program Never
main =
Navigation.program (Navigation.makeParser hashParser)
{ init = init
, view = view
, update = update
, urlUpdate = urlUpdate
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ page : Page
, first : FirstPage.Model
, second : SecondPage.Model
}
init : Result String Page -> ( Model, Cmd Msg )
init result =
urlUpdate result (Model Home FirstPage.init SecondPage.init)
-- UPDATE
type Msg
= FirstPage FirstPage.Msg
| SecondPage SecondPage.Msg
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
FirstPage fMsg ->
{ model | first = FirstPage.update fMsg model.first }
! []
SecondPage sMsg ->
{ model | second = SecondPage.update sMsg model.second }
! []
{-| The URL is turned into a result. If the URL is valid, we just update our
model to the new count. If it is not a valid URL, we modify the URL to make
sense.
-}
urlUpdate : Result String Page -> Model -> ( Model, Cmd Msg )
urlUpdate result model =
case Debug.log "result" result of
Err _ ->
( model, Navigation.modifyUrl (toHash model.page) )
Ok Home ->
{ model
| page = Home
}
! []
Ok (First id) ->
{ model
| page = First id
, first = FirstPage.urlUpdate id model.first
}
! []
Ok (Second str) ->
{ model
| page = Second str
, second = SecondPage.urlUpdate str model.second
}
! []
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
div []
[ div [ centerStyle "row" ]
[ viewLink Home "Home"
, viewLink (First 42) "FirstPage"
, viewLink (Second "Hello World") "Second Page"
]
, hr [] []
, (viewPage model)
]
viewPage : Model -> Html Msg
viewPage model =
case model.page of
Home ->
div [ centerStyle "column" ]
[ words 60 "Welcome!"
, text "Play with the links above. "
]
First id ->
div [ centerStyle "column" ]
[ App.map FirstPage (FirstPage.view model.first) ]
Second str ->
div [ centerStyle "column" ]
[ App.map SecondPage (SecondPage.view model.second) ]
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "4.0.1 <= v < 5.0.0",
"elm-lang/html": "1.0.0 <= v < 2.0.0",
"elm-lang/navigation": "1.0.0 <= v < 2.0.0",
"evancz/url-parser": "1.0.0 <= v < 2.0.0"
},
"elm-version": "0.17.1 <= v < 0.18.0"
}
module FirstPage exposing (..)
import Html exposing (..)
import Widgets exposing (..)
import Router exposing (..)
-- MODEL
type alias Model =
{ value : Int }
init : Model
init =
Model 0
-- UPDATE
type Msg
= Update Int
update : Msg -> Model -> Model
update msg model =
case msg of
Update id ->
{ model | value = id }
urlUpdate : Int -> Model -> Model
urlUpdate id model =
update (Update id) model
-- VIEW
view : Model -> Html Msg
view model =
div []
[ p [] [ text "This is the First Page" ]
, p [] [ text ("The value of the int is: " ++ (toString model.value)) ]
, viewLink Home "Get Back Home"
]
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
module Router exposing (..)
import String
import UrlParser exposing (Parser, (</>), format, int, oneOf, s, string)
import Navigation
-- URL PARSERS - check out evancz/url-parser for fancier URL parsing
toHash : Page -> String
toHash page =
case page of
Home ->
"#home"
First id ->
"#first/" ++ toString id
Second str ->
"#second/" ++ str
hashParser : Navigation.Location -> Result String Page
hashParser location =
UrlParser.parse identity pageParser (String.dropLeft 1 location.hash)
type Page
= Home
| First Int
| Second String
pageParser : Parser (Page -> a) a
pageParser =
oneOf
[ format Home (s "home")
, format First (s "first" </> int)
, format Second (s "second" </> string)
]
module SecondPage exposing (..)
import Html exposing (..)
-- MODEL
type alias Model =
{ value : String }
init : Model
init =
Model ""
-- UPDATE
type Msg
= Update String
update : Msg -> Model -> Model
update msg model =
case msg of
Update str ->
{ model | value = str }
urlUpdate : String -> Model -> Model
urlUpdate str model =
update (Update str) model
-- VIEW
view : Model -> Html Msg
view model =
div []
[ p [] [ text "This is the Second Page" ]
, p [] [ text ("The value of the string is: " ++ model.value) ]
]
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
module Widgets exposing (..)
import Html exposing (Html, Attribute, a, div, hr, input, span, text)
import Html.Attributes exposing (..)
import Router exposing (..)
viewLink : Page -> String -> Html msg
viewLink page description =
a [ style [ ( "padding", "0 20px" ) ], href (toHash page) ] [ text description ]
words : Int -> String -> Html msg
words size message =
span [ style [ ( "font-size", toString size ++ "px" ) ] ] [ text message ]
centerStyle : String -> Attribute msg
centerStyle direction =
style
[ ( "display", "flex" )
, ( "flex-direction", direction )
, ( "align-items", "center" )
, ( "justify-content", "center" )
, ( "padding", "20px 0" )
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.