Preventing input triggering phx-change

Hi there,

I have a form with phx-change event.
There’s one input which should not trigger phx-change. How can I achieve that?

I think you can add “phx-update=“ignore” to the element you want to keep from changing. See DOM patching & temporary assigns — Phoenix LiveView v0.17.11

Since you want to change a specific input, one way you could do that would be to have an ignore validation event handler. For example…

...
def render(assigns) do
  ~H"""
    <.form let={f} for={@changeset} phx-submit="save" phx-change="validate">

      # specific input to ignore
      <.text_input form={f} field={:ignore_field} phx-debounce={"blur"} phx-change="validate-ignore" />
    </.form>
  """

def handle_event("validate-ignore", _params, socket) do
  {:noreply, socket}
end

def handle_event("validate", %{"form" => form_params}, socket) do
 # your normal validation handling
end
...

Just fyi, this example is using a text_input form component but it works the same as standard Phoenix form HTML. Also, there is an update coming for Phoenix LiveView 0.18 regarding the let syntax. Here’s the docs.

1 Like

I’ve tried this already. validate event get’s called.
Here’s the snippet of my code.

<.form
    let={f}
    for={@changeset}
    id="analysis-form"
    phx-submit="analyse"
    phx-change="validate"
    as="analysis">

  <input class="border-none focus:ring-0 outline-none pl-1 flex-auto"
      phx-focus="open-suggestions"
      phx-click-away="close-suggestions"
      phx-keydown="handle_key"
      name={"#{@id}-search"}
      data-target={@myself}
      phx-target={@myself}
      phx-change="ignore"
      phx-hook="Search"
      id={"#{@id}-search"}
    />
</.form>

Well, without seeing more of your code, you have a lot of events going on that input: phx-keydown is going to trigger its own event separated from your phx-change event and possibly your hook may be doing similar as well.

Edit: to clarify, I think you need to tie all of your events to same “validate-ignore” handler. Or in your example, phx-change="ignore".

Perhaps I have misunderstood the problem, but I think what @f0rest8 might be suggesting is that you drop the change validation from your form setup and apply it separately to your fields.

That’s assuming you don’t want it passed back to your validation handle_event.

e.g.:

<.form let={f} phx-submit="submit" for={@changeset}>
  <%= text_input f, :search, phx_change: "validate" %>
  <%= text_input :other_field, :foo %>`
</.form>

Edit: just realised (as I can’t test it right now), but I think if the non-validating-field is part of the changeset, if other fields do get validated the returned changeset will have a blank entry for the non-validating-field resulting in the entry dissapearing from your form.

You may need to generate your own text_input (i.e. an atom instead of the form).

1 Like