What causes phx-no-feedback to be automatically removed?


I have a complex form in which I have multiple budget components that are displayed using as follows:

<%= for budget <- inputs_for(f, :budgets) do %>
          <%= live_component @socket, SageWeb.NominalLive.BudgetComponent,
                id: "budget-#{input_value(budget, :year)}",
                parent_id: @id,
                budget: budget,
                company_id: @company_id,
                view: __MODULE__


One of the fields on the budget component can trigger an event:

<%= input @budget, :annual,
      phx_target: @myself,
      phx_keydown: "annual-budget-change",
      phx_debounce: "blur",

Note: The input tag is just a convenience helper that combines input and error tags.

In the budget component I have the following code (cut down for simplicity purposes).

def handle_event("annual-budget-change", params, socket) do
    params = %{"annual" => params["value"]}

    changeset = Budget.annual_changeset(socket.assigns.budget.source, params)

    case Ecto.Changeset.apply_action(changeset, :validate) do
      {:ok, _budget} ->
        {:noreply, socket}

      {:error, changeset} ->
        budget =
          |> Map.put(:source, changeset)
          |> Map.put(:errors, changeset.errors)
          |> Map.put(:params, params)

        {:noreply, assign(socket, :budget, budget)}

This all works reasonably well BUT errors are not being displayed. I’ve tracked it down to the fact that the phx-no-feedback class isn’t being removed as it would be for standard form processing. If I manually remove the class via Dev Tools I can see the error.

So a couple of questions if I may:

  • Am I not setting something correctly which would cause the error to display?
  • Is what I’m doing a bit mad/off the beaten path and shouldn’t be done?



I have seen this a few times and I’m afraid I can’t remember the fix exactly.

Possibly it depended on passing the changeset through form_for? Unclear if you’ve dropped that for the post or if you’re not using it.

thanks @soup. When the component is originally called it is passed through form_for just prior to being called. but the subsequent update doesn’t go via form_for. I did try passing the result of the changeset back to the parent form and merge with the original form changeset but couldn’t get that to work either. :-(.