Update functions getting called twice with one click event

I am trying to implement a simple dropdown using elm-ui. I am following this medium article https://medium.com/nerd-for-tech/elm-elm-ui-and-the-building-of-a-dropdown-part-i-8aff2ed079b2 .

The UI consist of one text input element. The dropdown options are rendered by Element.Column and using the Element.below attribute to the input element. There are 3 msg NoAction/ClickedSelectFood/ClickedDropdownFood. When user click on input element ClickSelectFood is triggered. When user clicks on one of the dropdown element ClickedDropdownFood is triggered.

Update function:
> update : Msg → Model → Model

update msg model =
    case msg of
        NoAction ->
            model
        ClickedSelectFood ->
            let
               a = Debug.log "Inside ClickedSelectFood" msg
            in
            { model | status = SelectFood }
        ClickedDropdownFood ->
            let
                a = Debug.log "Inside ClickedDropdownFood" msg
            in
            { model | status =  Normal}

Problem is whenever one of the elements of the dropdown is clicked: the update function is called twice. Once with ClickedDropdownFood msg and once with ClickedSelectFood message. But the view code is only called once. My understanding was that Elm always renders the UI with every update call.

I suspect the issue might be that I am using Element.below to render the dropdown options. Maybe two events are generated by the click.

Any ideas ?

Ellie link: https://ellie-app.com/dhy7yMfMr9Ba1

Usually the view is called once per animation frame. The update can be called many times within that cycle.

I think the onClick event is propagating up the DOM. You have 2 onClick event handlers in the code, perhaps you only need 1? Or perhaps you need to stop the inner one from propagating using the options available here: VirtualDom - virtual-dom 1.0.2

1 Like

Thanks for the response Rupert. Looks like elm-ui Events does not expose functionality to stop event propagation. Should I use use virtual-dom event handler ?

You could conditionally enable the click handler on the Dropdown.

([ Border.width 1
                , Border.dashed
                , E.padding 3
                ] ++ case model.status of
                    SelectFood ->
                        [E.below (E.column [](List.map viewFood foodList))]
                    Normal->
                        [Events.onClick ClickedSelectFood,   -- I moved the onClick to the non-selecting state only.
                        E.below E.none])

Something like this: https://ellie-app.com/dhDFVv6XSLha1 . I also wired up the event to select a fruit :slight_smile:

2 Likes

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