How can I reset a select control?

I have a select widget that validates the change on the backend and I cannot figure out how reset the select to the previous value.

So, when the select changes, I take the value from the message, check it on the backend and the backend can return the same value or error out. If the value is valid, I set it, if not… I leave the model the same.

In this Ellie example I do nothing on selection and I expect the selected value to reset back to “The Bar” after selecting “The Foo”.

What am I missing? How can I reset the selection back to “The Bar”?

You should be able to set the value property of the select directly (Html.Attributes.property "value" (Json.Encode.string selectedValue)). The selected attribute of option seems to be only for setting the initially-selected option.

4 Likes

Thank you! This worked wonderfully!

1 Like

Not sure if this thread is the place for it but I ran into this issue as well as some related ones which I thought I’d share for posterity.

A select value is a property but an option value is an attribute

Getting these mixed leads to odd behavior like incorrect default values, text disappearing, and disabled options not showing

select [ Html.Attributes.property "value" (Encode.string "my-value") ]
    [ option [ Html.Attributes.attribute "value" "my-value" ] []
    ]

Explicitly use Html.Attributes.attribute to set an option’s value instead of Html.Attributes.value
https://ellie-app.com/9qkCLMDC6r6a1

In this example in Chrome, both select options are disabled but only the first option using Html.Attributes.attribute appears so. The other one using Html.Attributes.value seems like a selectable option. Clicking re-render makes the second option’s text disappear.

Screen Shot 2020-07-13 at 4.05.47 PM

In Firefox, the second option appears initially but disappears on re-rendering.

Screen Shot 2020-07-13 at 4.07.31 PM

Both the select’s value and the option’s selected are required to keep the render consistent with your model.

Here the select’s value is set but the initial render is wrong because no option has selected. Click the NoOp button to re-render and see the correct value. Reload and the wrong value is back. Same happens with navigation away from and back to the page.
https://ellie-app.com/9qkMcTdGtK4a1

You can easily set them to opposing values. Here, the initial render says three but the model is two and the select defaults to one. Re-rendering button shows the correct two.
https://ellie-app.com/9qkMPwBRJ4Ja1

Setting both keeps the correct value consistently.
https://ellie-app.com/9qkNtG7Zz6Ga1

Example of odd value behavior: If you have an intermediate set of options (eg while loading) with selected True and Html.Attributes.value, it will supersede a later selected option.

In this example, both value and selected are correctly set, but a “loading…” option is briefly shown that uses Html.Attributes.value. This supersedes the later options and the incorrect initial value of “Option One” is shown. Click the NoOp button to re-render and show the correct “Select one”. Or edit the code to remove the selected True from the loading option and it will work as expected.

https://ellie-app.com/9qkZdWFqbLYa1

This version where Html.Attributes.value is replaced with Html.Attributes.attribute "value" works as expected
https://ellie-app.com/9qkYXxGhdNZa1

4 Likes

I think this is incorrect. While it’s true that an element attribute sets the initial property of the dom, in elm selected is implemented as a property:

selected : Bool -> Attribute msg
selected =
  boolProperty "selected"
...
boolProperty : String -> Bool -> Attribute msg
boolProperty key bool =
  Elm.Kernel.VirtualDom.property key (Json.bool bool)

So it can actually be used to set the select value. But, as mentioned in the other reply, it’s necessary to keep the model in sync with the dom; otherwise when the user changes the selection, the select value property and the option selected property are changed, but the elm model is oblivious of the change.

Back to the original problem, I don’t understand why you want to prevent the change in the select; it seems like bad UX. For me, you either disable the options that you know can’t be selected or after the backend check you revert the change with an appropriate ui message.

Here is an ellie example that simulates a backend call and then reverts the selected value. I’m sure it will be trivial to the OP, but the point is that the value can be changed with the selected attribute, and it looks more like the elm way to me.

2 Likes

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