silverdr

silverdr

Let’s say there’s a typical form with phx-change="validate" on the form level and there are also some fields in the form, which have phx-change="autocomplete" on input level. The problem I experience is that form level change event is not triggered whenever input level one is.

What is the correct way of handling such situations?

Showing Posts 1 to 6

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Can you elaborate as to the purpose of these secondary phx-change settings? The form level one will trigger with every change on every input anyway.

silverdr

silverdr OP

Let’s try… The form-level change is used to validate the whole form and return errors if any. The input-level one is used to pass values for autocompleting a particular field. These are two different events for different purposes and on the input level I immediately know which field triggered the event as only its data is passed. All in all both are needed and only some (like 15% of all) fields need autocompletion while all of them need to pass validation. Therefore it looked natural to me to try triggering autocomplete only for those fields, which need it, while triggering validate on all changes. I could probably (?) use form-level for everything and parse-out changed field from the params somehow but I’d prefer to have those contexts separated unless there’s currently no way to make it work (why would that be?).

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

I think what you want is the "_target" value sent via phx-change to handle event. So if you set it at the form level, you can see which input changed via "_target" without any extra wiring.

silverdr

silverdr OP

Possibly, yes. And instead of validate and autocomplete as needed there’d have to be something combined like handle_change with extra block checking what to do with the event. I. e. whether it was triggered by input requiring autocompletion or not, extracting the value, etc. Doable, of course, even if seemingly far less elegant. Still - why can’t both levels work together? Is it by design for some reason(s)? Or because of some limitations somewhere? Or they actually can but I don’t know how to make them do?

codeanpeace

codeanpeace

The default generated validation callback just runs a params map through the resource changeset based off the resource struct in the socket assigns. This means it should handle a subset of fields just as well as all the fields. So why not directly call the validate callback from the autocomplete callback?

def handle_event("autocomplete", %{"field" => value} = params, socket) do
  # add autocomplete logic and then add result(s) to socket and/or params
  # then call the `validate` callback with the updated socket and/or params
  handle_event("validate", %{"resource" => params}, socket)
end

These excerpts – and the comments especially – seem relevant from a quick skim through live_socket.js.

https://github.com/phoenixframework/phoenix_live_view/blob/555ccadab0da7104c58cdaa42dac4169ebcd44b7/assets/js/phoenix_live_view/live_socket.js#L830-L859

https://github.com/phoenixframework/phoenix_live_view/blob/555ccadab0da7104c58cdaa42dac4169ebcd44b7/assets/js/phoenix_live_view/live_socket.js#L697-L705

And based off of the LiveView docs on form events, it seems like what you’re seeing is expected behavior.

In general, it is preferred to handle input changes at the form level, where all form fields are passed to the LiveView’s callback given any single input change…
You may wish for an individual input to use its own change event or to target a different component. This can be accomplished by annotating the input itself with phx-change, for example:

<.form for={@form} phx-change="validate" phx-submit="save">
  ...
  <.input field={@form[:email]}  phx-change="email_changed" phx-target={@myself} />
</.form>

Then your LiveView or LiveComponent would handle the event:

def handle_event("email_changed", %{"user" => %{"email" => email}}, socket) do
  ...
end

Note: only the individual input is sent as params for an input marked with phx-change.

silverdr

silverdr OP

I thought of this too, but this way it would currently break the flow, because params contain only the one, specific input’s data rather than the full form. I’d need to rewrite the rather complex validation handler

I read those docs and it wasn’t clear to me that it is form-level EOR input-level. Now, rereading this again and looking for hints, there is one word that can suggest it to be the case: “own change event” w/o any qualifiers, although still…

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
psy-q
I’m trying to set up Emacs with elixir-ls via lsp-mode and credo via Flycheck. This should mostly be preconfigured as Flycheck picks up c...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews