Skip to content

Commit

Permalink
add phx-feedback-for migration section
Browse files Browse the repository at this point in the history
  • Loading branch information
SteffenDE committed May 10, 2024
1 parent 217c7c7 commit c12687b
Showing 1 changed file with 71 additions and 12 deletions.
83 changes: 71 additions & 12 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,82 @@ let liveSocket = new LiveSocket("/live", Socket, {
})
```

To use the new `used_input?` approach with a previously generated `phx.gen.auth` system, you will also need to add `current_password` tracking to your user schema with the following two changes to your `user.ex`:
### Migrating from phx-feedback-for

While we provide [a shim for existing applications](https://gist.github.com/chrismccord/c4c60328c6ac5ec29e167bb115315d82) relying on phx-feedback-for,
you might want to migrate to the new approach.

The following guides you through the necessary changes assuming a project generated
with a recent (Phoenix 1.7), but pre LiveView 1.0 version of the phx generators.
For more general use cases, please also have a look at the documentation for [`used_input?/1`](https://hexdocs.pm/phoenix_live_view/1.0.0-rc.0/Phoenix.Component.html#used_input?/1).

First, ensure that you are using the latest versions of `:phoenix_ecto` and `:phoenix_html`. At the time of writing:

```elixir
schema "users" do
...
{:phoenix_ecto, "~> 4.5"},
{:phoenix_html, "~> 4.1"},
```

#### Core components

1. Adjust the core components to omit phx-feedback-for attribute and the phx-no-feedback classes.
This shows one example for the textarea input, but there are more cases that need to be adjusted accordingly:

```diff
def input(%{type: "textarea"} = assigns) do
~H"""
- <div phx-feedback-for={@name}>
+ <div>
<.label for={@id}><%%= @label %></.label>
<textarea
id={@id}
name={@name}
class={[
- "mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6",
- "min-h-[6rem] phx-no-feedback:border-zinc-300 phx-no-feedback:focus:border-zinc-400",
+ "mt-2 block w-full rounded-lg text-zinc-900 focus:ring-0 sm:text-sm sm:leading-6 min-h-[6rem]",
@errors == [] && "border-zinc-300 focus:border-zinc-400",
@errors != [] && "border-rose-400 focus:border-rose-400"
]}
```

2. Filter the errors in the initial function for `Phoenix.HTML.FormField`s:

```diff
def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
+ errors = if Phoenix.Component.used_input?(field), do: field.errors, else: []

assigns
|> assign(field: nil, id: assigns.id || field.id)
- |> assign(:errors, Enum.map(field.errors, &translate_error(&1)))
+ |> assign(:errors, Enum.map(errors, &translate_error(&1)))
|> assign_new(:name, fn -> if assigns.multiple, do: field.name <> "[]", else: field.name end)
|> assign_new(:value, fn -> field.value end)
|> input()
end
```

#### phx.gen.auth

The settings page generated by phx.gen.auth creates a form to change the user's email as well as the password.
Because of the way the current password is checked in previous variants of the code, the error message for an invalid
password is not visible when migrating to `used_input?`. To make this work, two changes need to be made to the
generated user module:

1. add a new virtual field `:current_password` to the schema:

```diff
field :hashed_password, :string, redact: true
+ field :current_password, :string, virtual: true, redact: true
end
```

def validate_current_password(changeset, password) do
+ changeset = cast(changeset, %{current_password: password}, [:current_password])
2. cast the `current_password` field in the `validate_current_password` function:

if valid_password?(changeset.data, password) do
changeset
else
add_error(changeset, :current_password, "is not valid")
end
end
```diff
def validate_current_password(changeset, password) do
+ changeset = cast(changeset, %{current_password: password}, [:current_password])
+
if valid_password?(changeset.data, password) do
```

## 1.0.0-rc.1
Expand Down

0 comments on commit c12687b

Please sign in to comment.