CRUD

Code Example

module Components.Examples.Crud.Main exposing (main)

import Browser
import Html exposing (Html, button, div, input, text)
import Html.Attributes exposing (disabled, name, style, type_, value)
import Html.Events exposing (onClick, onInput)


type alias Model =
    { nextId : Int
    , todos : List Todo
    , newTodo : Maybe String
    }


type alias Todo =
    { id : Int
    , title : String
    , completed : Bool
    }


init : Model
init =
    { nextId = 1
    , todos = []
    , newTodo = Nothing
    }


type Msg
    = InputTodo String
    | AddTodo
    | ToggleTodo Int
    | RemoveTodo Int


update : Msg -> Model -> Model
update msg model =
    case msg of
        InputTodo text ->
            { model
                | newTodo =
                    case String.length text of
                        0 ->
                            Nothing

                        _ ->
                            Just text
            }

        AddTodo ->
            case model.newTodo of
                Nothing ->
                    model

                Just text ->
                    { model
                        | todos = Todo model.nextId text False :: model.todos
                        , nextId = model.nextId + 1
                        , newTodo = Nothing
                    }

        ToggleTodo id ->
            { model
                | todos =
                    List.map
                        (\todo ->
                            if todo.id == id then
                                todo

                            else
                                { todo | completed = not todo.completed }
                        )
                        model.todos
            }

        RemoveTodo id ->
            { model
                | todos =
                    List.filter
                        (\todo -> todo.id /= id)
                        model.todos
            }


view : Model -> Html Msg
view model =
    div [ style "width" "300px", style "margin" "auto" ]
        [ input
            [ value
                (Maybe.withDefault "" model.newTodo)
            , onInput InputTodo
            ]
            []
        , button
            [ disabled (model.newTodo == Nothing), onClick AddTodo ]
            [ text "Add Todo" ]
        , div [ style "padding-top" "20px" ]
            (List.map
                (\todo ->
                    div
                        [ style "display" "flex"
                        , style "justify-content" "space-between"
                        , style "padding" "5px 0"
                        ]
                        [ input
                            [ type_ "checkbox"
                            , name (String.fromInt todo.id)
                            , onClick (ToggleTodo todo.id)
                            ]
                            []
                        , text todo.title
                        , button [ onClick (RemoveTodo todo.id) ] [ text "X" ]
                        ]
                )
                model.todos
            )
        ]


main : Program () Model Msg
main =
    Browser.sandbox { init = init, update = update, view = view }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
Last Updated: 12/4/2021, 10:34:59 PM