Skip to content

Instantly share code, notes, and snippets.

@pdamoc
Created May 20, 2016 20:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pdamoc/a4944a973138234f681359d505c4bea8 to your computer and use it in GitHub Desktop.
Save pdamoc/a4944a973138234f681359d505c4bea8 to your computer and use it in GitHub Desktop.
Counters through JS
module Component exposing (..)
import Html exposing (..)
import Html.Attributes exposing (style)
import Html.Events exposing (onClick)
import Ports exposing (..)
-- MODEL
type alias Model =
{ id: ID
, value : Int }
init : ID -> (Model, Cmd Msg)
init id =
{ id = id
, value = 0 } ! []
-- UPDATE
type Msg = Increment | Decrement | UpdateValue Int | NoOp
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Increment -> model ! [toJS (model.id, "Increment")]
Decrement -> model ! [toJS (model.id, "Decrement") ]
UpdateValue val -> {model | value = model.value + val} ! []
NoOp -> model ! []
-- VIEW
view : Model -> Html Msg
view model =
div []
[ button [ onClick Decrement ] [ text "-" ]
, div [ countStyle ] [ text (toString model.value) ]
, button [ onClick Increment ] [ text "+" ]
]
countStyle : Attribute Msg
countStyle =
style
[ ("font-size", "20px")
, ("font-family", "monospace")
, ("display", "inline-block")
, ("width", "50px")
, ("text-align", "center")
]
-- WIRING
subscriptions : Model -> Sub Msg
subscriptions model =
fromJS (\(id, shift) -> if id == model.id then UpdateValue shift else NoOp)
{
"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.0 <= v < 5.0.0",
"elm-lang/html": "1.0.0 <= v < 2.0.0",
"evancz/elm-http": "3.0.1 <= v < 4.0.0"
},
"elm-version": "0.17.0 <= v < 0.18.0"
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Elm • Counter through JS </title>
<script type="text/javascript" src="elm.js"></script>
</head>
<body style="margin: 0px;">
</body>
<script type="text/javascript">
var app = Elm.Main.fullscreen();
app.ports.toJS.subscribe(function(idAndCmd) {
var id = idAndCmd[0]
var cmd = idAndCmd[1]
if (cmd == "Increment") {
app.ports.fromJS.send([id, 1]);
} else {
app.ports.fromJS.send([id, -1]);
}
});
</script>
</html>
import Html.App as App
import Html exposing (..)
import Component
-- MODEL
type alias Model =
{ top : Component.Model
, bottom : Component.Model
, snoop : String
}
init : ( Model, Cmd Msg )
init =
let
(top, tCmd) = Component.init 0
(bottom, bCmd) = Component.init 1
in
Model top bottom "" ! [Cmd.map Top tCmd, Cmd.map Bottom bCmd]
-- UPDATE
type Msg = Top Component.Msg | Bottom Component.Msg
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Top compMsg ->
let
(top, cmd) = Component.update compMsg model.top
in
{ model | top = top } ! [Cmd.map Top cmd]
Bottom compMsg ->
let
(bottom, cmd) = Component.update compMsg model.bottom
in
{ model | bottom = bottom } ! [Cmd.map Bottom cmd]
-- VIEW
view : Model -> Html Msg
view model =
div []
[ App.map Top (Component.view model.top)
, div [] [ App.map Bottom (Component.view model.bottom)]
, div [] [ text model.snoop ]
]
-- WIRING
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ Sub.map Top (Component.subscriptions model.top)
, Sub.map Bottom (Component.subscriptions model.bottom)
]
main : Program Never
main =
App.program
{ init = init
, update = update
, view = view
, subscriptions = subscriptions}
port module Ports exposing (toJS, fromJS, ID)
type alias ID = Int
port toJS : (ID, String) -> Cmd msg
port fromJS : ((ID, Int) -> msg) -> Sub msg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment