I built an inline form for updating one field today and I wanted to toggle between displaying the field and editing the field by simply clicking on it. So, I’ve built this little thing which toggles between the form and a <p>
-element when the user clicks on it:
alias Phoenix.LiveView.JS
def render(assigns) do
~H"""
<p
id={"name-#{@element.id}"}
# The group element means that the edit icon is shown
# when a user hovers over the group.
class="group hover:cursor-pointer flex items-center space-x-2"
phx-click={toggle_name_divs(@element.id)}
>
<span><%= @element.name %></span>
<.icon name="hero-pencil-solid" class="h-4 w-4 hidden group-hover:block" />
</p>
<form
id={"form-#{@element.id}"}
phx-submit="update_name"
phx-target={@myself}
class="hidden items-center space-x-2"
>
<input
type="text"
name="name"
value={@element.name}
autocomplete="off"
/>
<.button phx-click={toggle_name_divs(@element.id)}>
<.icon name="hero-check" />
</.button>
</form>
"""
end
def toggle_name_divs(element_id) do
JS.toggle(to: "#name-#{element_id}", display: "flex")
|> JS.toggle(to: "#form-#{element_id}", display: "flex")
end
def handle_event("update_name", %{"name" => name}, socket) do
# Update and assign your element here
end
So, if a user hovers over the name display, an pencil icon shows. If the user clicks on the group, it disappears and the form appears. If the user saves the form, the form disappears and the name display appears again, but it also sends an “update_name”-event to the server. Hope it helps!