Skip to content

Instantly share code, notes, and snippets.

@odedw
Created August 27, 2017 14:32
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 odedw/82ed3e64fbcd4df2d298538bb438702e to your computer and use it in GitHub Desktop.
Save odedw/82ed3e64fbcd4df2d298538bb438702e to your computer and use it in GitHub Desktop.
Todo app in Elm
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.Keyed as Keyed
-- MODEL
type alias Model =
{ entries : List Entry
, uid : Int
, newTodoText : String
, visibility : Visibility
}
type alias Entry =
{ description : String
, completed : Bool
, id : Int
}
emptyModel : Model
emptyModel =
{ entries = []
, uid = 0
, newTodoText = ""
, visibility = All
}
newEntry : String -> Int -> Entry
newEntry desc id =
{ description = desc
, completed = False
, id = id
}
type Msg
= Add
| UpdateField String
| Toggle Int Bool
| SetVisibility Visibility
type Visibility
= All
| Completed
| Active
--UPDATE
update : Msg -> Model -> Model
update msg model =
case msg of
Add ->
{ model
| uid = model.uid + 1
, entries = model.entries ++ [ newEntry model.newTodoText model.uid ]
, newTodoText = ""
}
UpdateField text ->
{ model
| newTodoText = text
}
Toggle id isCompleted ->
let
updateEntry t =
if t.id == id then
{ t | completed = isCompleted }
else
t
in
{ model | entries = List.map updateEntry model.entries }
SetVisibility newVisibility ->
{ model | visibility = newVisibility }
--VIEW
view : Model -> Html Msg
view model =
let
entries =
case model.visibility of
All ->
model.entries
Active ->
List.filter (\todo -> not todo.completed) model.entries
Completed ->
List.filter (\todo -> todo.completed) model.entries
in
div []
[ input
[ placeholder "Description"
, value model.newTodoText
, onInput UpdateField
]
[]
, button [ onClick Add ] [ text "Add" ]
, fieldset [style [ ( "border", "none" ), ( "display", "inline-block")]]
[
label []
[ input [ type_ "radio", name "set-visibility", onClick (SetVisibility All), checked True] []
, text "All"
]
, label []
[ input [ type_ "radio", name "set-visibility", onClick (SetVisibility Active) ] []
, text "Active"
]
, label []
[ input [ type_ "radio", name "set-visibility", onClick (SetVisibility Completed) ] []
, text "Completed"
]
]
, Keyed.ul [] <|
List.map viewKeyedEntry entries
]
viewKeyedEntry : Entry -> ( String, Html Msg )
viewKeyedEntry todo =
( toString todo.id, viewEntry todo )
viewEntry : Entry -> Html Msg
viewEntry todo =
let
textDecoration =
if todo.completed then
"line-through"
else
"none"
in
li [style [ ( "list-style-type", "none" )]]
[ input [ type_ "checkbox", onClick (Toggle todo.id (not todo.completed)), checked todo.completed ] []
, span [style [ ( "text-decoration", textDecoration ) ]]
[ text todo.description ]
]
--PROGRAM
main : Program Never Model Msg
main =
Html.beginnerProgram
{ model = emptyModel
, view = view
, update = update
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment