# How to update an HTML element when the model changes

**URL:** https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150
**Category:** Learn
**Created:** [August 12, 2019, 9:17pm UTC](https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150 "2019-08-12T21:17:36Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![fluffymufti](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/fluffymufti/32/2439_2.png) [@fluffymufti](https://discourse.elm-lang.org/u/fluffymufti)
#### Post date: [August 12, 2019, 9:17pm UTC](https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150/1 "2019-08-12T21:17:36Z")

</div>

I’m very much an elm beginner and have come across this problem of trying to change the state of an HTML radio button when the model changes.

I include a stripped down copy of the code which illustrates the problem I’m having.

The page displays a list of indexes, each index in the list has a radio button. The ‘+’ button adds a new index to the list.

 ![Untitled](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/2X/f/fbdff3adec73923d1d36bd2c87496a976f6cace0.png)

- **A** Initial state, a single, unselected radio box.

- **B** Select the radio box next to ‘0’

- **C** Click the ‘+’ button to add a new , index ‘1’

The previous index ‘0’ remains selected. I’d like to change this behaviour so that the most recently created index, in this case 1’, becomes selected.

```elm
module Main exposing (main)

import Browser
import Html exposing (..)
import Html.Attributes exposing (name, style, type_, value)
import Html.Events exposing (onClick, onInput)

type Msg
    = EntryAdded
    | EntrySelected String

type alias Entry =
    { index : Int }

type alias Model =
    { selected : Maybe Int
    , entries : List Entry
    }

main =
    Browser.element
        { init = init
        , view = view
        , update = update
        , subscriptions = \_ -> Sub.none
        }

init : () -> ( Model, Cmd Msg )
init _ =
    ( Model Nothing [Entry 0]
    , Cmd.none
    )

view : Model -> Html Msg
view model =
    div []
        [ul [ style "list-style-type" "none"]
            (List.map
                (\entry ->
                    div
                        []
                        [li []
                            [ text (String.fromInt entry.index)
                            , input
                                [ type_ "radio"
                                , name "entrySelector"
                                , value <| String.fromInt entry.index
                                , onInput EntrySelected
                                ]
                                []
                            ]
                        ]
                )
                model.entries
            )
        , button [onClick EntryAdded] [text "+"]
        ]

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        EntryAdded ->
            let
                last_item =
                    List.length model.entries
            in
            ( { model
                | entries = List.append model.entries [Entry last_item]
                , selected = Just last_item
              }
            , Cmd.none
            )

        EntrySelected index ->
            ( { model | selected = String.toInt index }
            , Cmd.none
            )

```

---

<div class="post-metadata">

### Author: ![joelq](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joelq/32/445_2.png) [@joelq](https://discourse.elm-lang.org/u/joelq)
#### Post date: [August 12, 2019, 9:28pm UTC](https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150/2 "2019-08-12T21:28:36Z")

</div>

You can programatically select a radio by setting the HTML `checked` attribute on it. In Elm, you can use the [`Html.Attributes.checked`](https://package.elm-lang.org/packages/elm/html/latest/Html-Attributes#checked) function.

I modified your code by adding the following line on the radio input:

```elm
checked <| Just entry.index == model.selected

```

Now the checked status of each radio will depend on whether or not its index is the same as `model.selected. Here’s an executable example: [https://ellie-app.com/6mLnKqRmB3na1](https://ellie-app.com/6mLnKqRmB3na1)

---

<div class="post-metadata">

### Author: ![fluffymufti](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/fluffymufti/32/2439_2.png) [@fluffymufti](https://discourse.elm-lang.org/u/fluffymufti)
#### Post date: [August 12, 2019, 9:43pm UTC](https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150/3 "2019-08-12T21:43:32Z")

</div>

Many thanks for the prompt reply. That’s exactly what I was looking for.

Michael.

---

<div class="post-metadata">

### Author: ![brian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/brian/32/2180_2.png) [@brian](https://discourse.elm-lang.org/u/brian)
#### Post date: [August 13, 2019, 2:56pm UTC](https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150/4 "2019-08-13T14:56:18Z")

</div>

> [@fluffymufti](#):
>
> ```elm
> type alias Model =
> { selected : Maybe Int
> , entries : List Entry
> }
> 
> ```

an additional wrinkle here is that this data structure is going to get out of sync pretty easily. What if you have: `{ selected = Just 10, entries = [] }`? There may be a better way to model this, depending on your requirements. Why is there a maybe there? If it’s because the list may be empty, but you always want an item to be selected, then a zipper might be a good fit. There are a few good packages for this!

---

<div class="post-metadata">

### Author: ![fluffymufti](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/fluffymufti/32/2439_2.png) [@fluffymufti](https://discourse.elm-lang.org/u/fluffymufti)
#### Post date: [August 13, 2019, 8:58pm UTC](https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150/5 "2019-08-13T20:58:25Z")

</div>

Brian - thanks for the feedback

The list of `entries` (or `rows` in the application code) are rows in a table. New rows can be appended to the table and existing rows can be deleted. In order to delete a row, it must be selected by the user, so `selected` can either point to a row in the table or nothing, hence the use use of `Maybe`

The application code proper can delete a selected row but, on deletion entries in the list are re-indexed.

```elm
deleteSelectedEntry : Model -> Model
deleteSelectedEntry model =
    case model.selected of
        Nothing ->
            model

        Just index ->
            { model
                | rows =
                    List.take index model.rows
                        ++ List.drop (index + 1) model.rows
                        |> reIndex index

                , selected = Nothing
            }

reIndex : Int -> List Entry -> List Entry
reIndex from_idx rows =
    let
        -- no change here
        upper =
            List.take from_idx rows

        -- change indexes in this portion
        lower =
            List.drop from_idx rows

        indexes =
            List.range from_idx <| from_idx + List.length lower
    in
    upper ++ List.map2 (\i entry -> Entry.changeIndex i entry) indexes lower

```

`List.map2` works like a zip function. I’ll have a look at the packages with zip functionality.

As I say, I’m very new to elm and all feedback is very useful.

Michael

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [August 23, 2019, 9:05pm UTC](https://discourse.elm-lang.org/t/how-to-update-an-html-element-when-the-model-changes/4150/6 "2019-08-23T21:05:04Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
