phoenixframework / phoenix_live_view

Rich, real-time user experiences with server-rendered HTML
https://hex.pm/packages/phoenix_live_view
MIT License
6.18k stars 931 forks source link

Form elements rendered in a LiveComponent do not display errors correctly #1834

Closed iwarshak closed 2 years ago

iwarshak commented 2 years ago

Environment

Actual behavior

I have a form where I can edit a post and add comments to it. If my comments form fields are in the heex template, errors show up correctly. If I have the comments fields in a functional component it also displays errors correctly. If I extract the comments form fields to a stateful LiveComponent, they do NOT render correctly.

In this contrived example, the form has a 'add comment' button which adds a comment to the post's changeset. It also pushes an event to a dummy input on the form, and that event triggers a DOM event to force the form to validate (as described here) The reason to do this is in the real application I have a validation which displays an error unless there is at least 1 comment, and forcing this validation to occur will clear that particular error once you add at least 1 comment to the post.

Here you can see what I am talking about. I have the comments field rendered twice, one being inline and the other in a LiveComponent. After submitting the form, I'd expect the 'can't be blank' error to show up under the comment field, but it does not in the LiveComponent version. It is actually there, but it has the phx-no-feedback class applied. When you submit a form, the phx-no-feedback classes should get removed, but they are not in this case. I added some debug logs to the liveview js, and it feels like this new field is not getting properly tracked/updated by morphdom.

Side note: if I do not add an action to the changeset when I do my dummy validation here - everything seems to work.

^^ Edit: This was a red herring. If I don't add an action to the changeset, the error tag is not actually rendered until after I submit the form. This leads me even more to believe it has to do with the javascript losing track of this component.

https://user-images.githubusercontent.com/471/149639081-db71b316-cf5e-44c0-8cf1-3848e1313fe7.mov

Here is a repo where you can see this happen: https://github.com/iwarshak/phx-liveview-no-feedback-bug

Open up: http://localhost:4090/posts/1/edit

chrismccord commented 2 years ago

Thanks for the detailed report and reproduction! This was super help to figure out what was going on. In this case, your "preflight" validate was causing the following submit to produce no diff within the live component, since the comment did not change. Because no diff was produced, no errors were shown following submit. Updated the client to always show form errors for previous inputs following a submit regardless of what the server sends back (or not). Thanks!