Created
August 27, 2017 14:32
-
-
Save odedw/82ed3e64fbcd4df2d298538bb438702e to your computer and use it in GitHub Desktop.
Todo app in Elm
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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