Skip to content

Instantly share code, notes, and snippets.

@clohr
Last active January 30, 2017 03:18
Show Gist options
  • Select an option

  • Save clohr/4cc84bdc72238742e2e6cd13c5bdafd4 to your computer and use it in GitHub Desktop.

Select an option

Save clohr/4cc84bdc72238742e2e6cd13c5bdafd4 to your computer and use it in GitHub Desktop.
Updating nested records within lists
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
import Array exposing (Array)
main =
program
{
init = init,
update = update,
view = view,
subscriptions = (always Sub.none)
}
-- INIT
type alias Model =
{ parents : List Parent
}
type alias Parent =
{ id : Int
, name : String
, role : ParentalRole
, spouse : Int
, children : List Child
}
type ParentalRole
= Father
| Mother
type alias Child =
{ id : Int
, name : String
}
initialModel : Model
initialModel =
Model
[ Parent 1 "Christian" Father 2 [Child 1 "Logan"]
, Parent 2 "Jenny" Mother 1 [Child 1 "Logan"]
]
init: (Model, Cmd Msg)
init =
(initialModel, Cmd.none)
-- UPDATE
type Msg
= UpdateParentName Int String
| UpdateChildName Int Int String
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
UpdateParentName id n ->
let
updatedParents =
Array.toList
<| Array.map (updateName id n)
<| Array.fromList model.parents
in
{model | parents = updatedParents} ! [Cmd.none]
UpdateChildName parentId childId childName ->
let
updatedParents =
Array.toList
<| Array.map (matchChild parentId childId childName)
<| Array.fromList model.parents
in
{model | parents = updatedParents} ! [Cmd.none]
updateName : Int -> String -> Parent -> Parent
updateName id name parent =
if (id == parent.id) then
{parent | name = name}
else
parent
matchChild : Int -> Int -> String -> Parent -> Parent
matchChild parentId childId childName parent =
if (parentId == parent.id) then
let
updatedChildren =
Array.toList
<| Array.map (updateChildName childId childName)
<| Array.fromList parent.children
in
{parent | children = updatedChildren}
else
parent
updateChildName : Int -> String -> Child -> Child
updateChildName childId childName child =
if (childId == child.id) then
{child | name = childName}
else
child
-- VIEW
view : Model -> Html Msg
view model =
div []
[ h1 [] [text "Parents"]
, ul [] (List.map displayParents model.parents)
, p [] []
, div [] [text <| toString model]
]
displayParents : Parent -> Html Msg
displayParents parent =
li []
[ input [value parent.name, onInput <| UpdateParentName parent.id] []
, ul [] (List.map (displayChildren parent.id) parent.children)
]
displayChildren : Int -> Child -> Html Msg
displayChildren parentId child =
li []
[ input [value child.name, onInput <| UpdateChildName parentId child.id] []
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment