Skip to content

Instantly share code, notes, and snippets.

@ir4y
Last active December 9, 2015 16:17
Show Gist options
  • Select an option

  • Save ir4y/8390899b14cb4e312f37 to your computer and use it in GitHub Desktop.

Select an option

Save ir4y/8390899b14cb4e312f37 to your computer and use it in GitHub Desktop.
module Hello where
import Graphics.Element exposing (Element, show)
import Task exposing (Task, andThen)
import Html exposing (..)
import Html.Attributes exposing (style, value)
import Html.Events exposing (onClick, on, targetValue)
import Json.Decode as Json
import Focus exposing (..)
-- Data structure
type alias EditForm =
{ name : String
, externalId : String
, selected: Bool
}
type alias Store =
{ editForm: EditForm
, itemList: List Item
}
type alias Item = EditForm
-- Cursor stuff
type alias Cursor a b =
{ mailbox : Signal.Mailbox a
, state : a
, lens : Focus a b
}
(>=>) : Cursor a b -> Focus b c -> Cursor a c
(>=>) c1 f1 = { c1 | lens = (c1.lens => f1) }
setC : Cursor a b -> b -> Cursor a b
setC c1 v = { c1 | state = update c1.lens (\_ -> v) c1.state}
getC : Cursor a b -> b
getC c1 = get c1.lens c1.state
-- Lenses
idL = create identity (\f r -> f r)
nameL = create .name (\f r -> { r | name = f r.name })
externalIdL = create .externalId (\f r -> { r | externalId = f r.externalId })
selectedL = create .selected (\f r -> { r | selected = f r.selected })
editFormL = create .editForm (\f r -> { r | editForm = f r.editForm })
itemListL = create .itemList (\f r -> { r | itemList = f r.itemList })
-- Helpers
create_C : Store -> Cursor Store Store
create_C state = { mailbox = contentMailbox
, state = state
, lens = idL
}
applyTo : Cursor a b -> b -> Signal.Message
applyTo cursor value = Signal.message cursor.mailbox.address (setC cursor value).state
onMyClick act = on "click" Json.value act
myInput : Cursor a String-> Html
myInput cursor = input [ value (getC cursor)
, on "input" targetValue (applyTo cursor)
] []
-- Main
initialState = { itemList = []
, editForm = { name = ""
, externalId = ""
, selected = False
}
}
contentMailbox : Signal.Mailbox Store
contentMailbox =
Signal.mailbox initialState
main =
Signal.map (create_C >> view) contentMailbox.signal
-- Views
appendItem : Cursor Store Store -> Signal.Message
appendItem cursor = applyTo (cursor >=> itemListL)
((getC (cursor >=> itemListL)) ++ [(getC (cursor >=> editFormL))])
view : Cursor Store Store -> Html
view cursor = div []
[ editFormView (cursor >=> editFormL)
, p []
[button [onMyClick (\_ -> appendItem cursor)] [text "+"]]
, itemListView (cursor >=> itemListL)
]
editFormView : Cursor Store EditForm -> Html
editFormView cursor = div []
[ p []
[ label [] [text "Name"]
, myInput (cursor >=> nameL)
]
, p []
[ label [] [text "External Id"]
, myInput (cursor >=> externalIdL)
]
]
itemListView : Cursor Store (List Item) -> Html
itemListView cursor = table []
[tbody []
(List.indexedMap itemView (getC cursor))
]
itemView : Int -> Item -> Html
itemView index item = tr []
[td [] [label [] [text item.name]]
,td [] [label [] [text item.externalId]]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment