How to update form input_value after handle_event?


LiveView beginner here… I have a handle_event function which based on some params, returns a value which I would like to set as value in a form input_field.

So, I have a button outside the form, and when that button is clicked, it runs handle_event("update_input) function which then returns some value, let’s say “ABC”. I would like to update form input_field value with the value from handle_event function, in this case “ABC”.

How do I do that?

<.input field={@form[:name]} type="text" label="Name" value="" phx-change="update_input" />

def handle_event("update_input", _params, socket) do
    input_value = get_value(params)

      |> assign(input_data: value)

Can you give a little more complete example of what you’re looking for? The one you provided is not super clear as you are saying there is a button outside the form that runs "update_input" event yet your example has that event trigger on a text input. Is it a button outside the form that is updating a field inside the form?

If that is the case, you can manually update a form field by getting its changeset through the :source key. So if you had this button outside the form:

<button type="button" value="ABC" phx-click="update_input">Click me </button>

and this inside the form:

<.input field={@form[:name]} type="text" label="Name" />

the update_event handler could look like:

def handle_event("update_input", %{"value" => value}, socket) do
   changeset = socket.assigns.form.source.changeset
   changeset = Ecto.Changeset.change(changeset, %{name: value})
   form = to_form(changeset)

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

You could also use LiveView’s update function:

def handle_event("update_input", %{"value" => value}, socket) do
  socket =
    update(socket, :form, fn %{source: changeset} ->
       |> Ecto.Changeset.change(%{name: value})
       |> to_form()

  {:noreply, socket}

EDIT: Fixed a glaring syntax error

Sorry for not making it clear enough… my code is wrong and doesn’t work…

So, I have a page which has a button and a form. Button is not a submit button, instead, when a user clicks it, handle_event("update_input) is triggered and random name for a user is created. Now, I would like to set that generated name as a value for input_field in the form which is bellow. This generated name is a default, and user can change it if they want before submitting it, that’s why I’m not using changeset here. I hope this makes sense.

EDIT: Tried your code and it works. I got it all wrong how this should work, it’s clear now, thanks a lot.

1 Like

Ok great! :slight_smile:

To take it a bit further, if you need validations to run immediately you should use your custom changeset function you use for updating instead of Ecto.Changeset.change directly.

EDIT: Oops, I read your response super quickly and missed the part where you are generating a random name. In that case using Ecto.Changeset.change is fine since you have complete control over the change!

1 Like