I have a condition to save a new record of a ‘name’ field, to be automatically saved after user click away from the text_input (unfocus/blur), without the save button.
I have successfully used phx-change along with phx-debounce to save the unique name and minimum length of 3 characters. However, after saving, it does not redirect to the show page.How to achieve the redirection without phx-submit like this?
Thank you.
issuing a push_redirect(socket, to: ...)
from the phx-change event should be enough. Do you have a redirect in place? If so, are you seeing any server or js console errors? Can you provide your LV source?
1 Like
Wow, thank you for the response @chrismccord.
This is my LiveView file
defmodule PortalWeb.SignLiveNew.Form do
use Phoenix.LiveView
require IEx
alias Portal.Fleet
alias Portal.Fleet.Sign
alias PortalWeb.LiveSignView
alias PortalWeb.Router.Helpers, as: Routes
def render(assigns), do: LiveSignView.render("form.html", assigns)
def mount(session, socket) do
{:ok,
assign(socket,
changeset: Fleet.change_sign(%Sign{}),
)}
end
def handle_event("verify_submit", %{"sign" => params}, socket) do
IO.inspect(params)
changeset = Fleet.change_sign(%Sign{})
case Fleet.create_sign(params) do
{:ok, _sign} ->
{:stop,
socket
|> put_flash(:info, "Sign created successfully.")
|> redirect(to: Routes.sign_path(socket, :index))
}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, changeset: changeset)}
end
{:noreply, assign(socket, params: params)}
end
end
This is the template.
<%= f = form_for @changeset, "#", [phx_change: :verify_submit] %>
<%= text_input f, :name, placeholder: "Name", "phx-debounce": "blur" %>
<%= error_tag f, :name %>
</form>
So far there is no error shown on the iex or js console, even if the input is not correct. However, it is not saving when the input is incorrect.
Your handle_event
returns the socket unchanged. Remember that elixir is immutable, so your case statement executes, but the socket
is not changed because you return the old one afterwards. Update your handle_event to:
def handle_event("verify_submit", %{"sign" => params}, socket) do
IO.inspect(params)
changeset = Fleet.change_sign(%Sign{})
case Fleet.create_sign(params) do
{:ok, _sign} ->
{:noreply,
socket
|> put_flash(:info, "Sign created successfully.")
|> redirect(to: Routes.sign_path(socket, :index))}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, changeset: changeset, params: params)}
end
end
8 Likes
This is working perfectly. Thank you @chrismccord