DavidVII
Phoenix LiveView has odd behavior with select tags
I have a form with a select tag which ties to the template_id. If a template_id is selected, I want to update the view to show some additional content. This content changes based on the template_id that was selected.
Now, because the phx-change event is fired whenever a change happens at the form level, the code that is in charge of assigning a template to the socket based on that template_id is run every time a change happens on the form.
This means that after a form is submitted and there is a validation error, the template_id is set to a specific ID. If I then change the select to an option with a nil value, the select tag stays on the option with the template_id from the original request.
Here’s my select_tag:
<%= select f, :template_id,
[{"Custom", nil}] ++ Enum.map(@templates, &{&1.name, &1.id}),
value: (if @current_template, do: @current_template.id, else: nil)
%>
Here’s a quick gif of the issue. Notice what happens after the validation error message pops up. I attempt to choose “custom” and while the template gets set, the select tag does not update:
The select tag seems to work fine before submitting the form, but once I submit the form, the changeset changes in a way that keeps the select tag from knowing which option to choose on my change event.
I tried replacing the value option from the select tag and setting the selected option instead and it makes matters worse somehow:
Am I doing something wrong with the select tag? The only way I’ve been able to get this to work the way I expect is by updating the changeset every time the form is changed (because the phx-change event doesn’t support binding to specific inputs), but I don’t want to update the changeset every time there is a change, this results in running validations before I want to.
Any help with this would be greatly appreciated. Thanks! ![]()
First Post!
al2o3cr
I’m not sure if it’s relevant, but there’s specific handling in the implementation of select for when value is nil:
My reading of this code is that when @current_template in your code above is nil, then the value from :template_id will be used instead.
If the validations are inexpensive (validate_required etc) then running them early is harmless - form_for ignores errors on the changeset if there’s no action set.








