vaer-k
vaer-k

Reputation: 11743

How do you clear a textarea in a Phoenix LiveView form?

I have a Phoenix LiveView with a form that is not backed by a data layer, like so:

<%= f = form_for :post, "#", [phx_submit: :create_post %>
  <%= textarea f, :message, placeholder: "Say something:" %>
  <%= hidden_input f, :user_id, value: @current_user.account_id %>
  <%= submit "Post" %>
</form>

I can't back the form with a changeset because I am not using Ecto. After submitting the form, the submission is processed just fine, but the form textarea is not cleared. How can I clear inputs without resorting to Javascript?

If I can't do it without Javascript, how can I do it with Javascript, but without bypassing the LiveView phx-submit mechanisms?

Some additional troubleshooting information:

Here is my event handler:

def handle_event("create_post", %{"post" => post_params}, socket) do
  thread_id = socket.assigns.thread.id
  user_id = post_params["user_id"]
  posts = Forums.append_post!(thread_id, user_id, post_params)
  UdsWeb.Endpoint.broadcast_from(self(), build_topic(thread_id), "new_post", %{posts: posts})
  {:noreply, assign(socket, :posts, posts)}
end

I've tried several different approaches to fix the problem, mostly involving variations of data structures backing the form.

Upvotes: 4

Views: 2142

Answers (2)

Wojciech Bednarski
Wojciech Bednarski

Reputation: 6373

Even it behaves like a SPA it is not a SPA, so you still need to use the backend router and redirect it back to the index page. Your form is on the index page but the resource is not the post's index page, it is post/new.

So, you need to use push_redirect (not redirect):

|> push_redirect(to: UdsWeb.post_index_path(socket, :index))
def handle_event("create_post", %{"post" => post_params}, socket) do
  thread_id = socket.assigns.thread.id
  user_id = post_params["user_id"]
  posts = Forums.append_post!(thread_id, user_id, post_params)
  UdsWeb.Endpoint.broadcast_from(self(), build_topic(thread_id), "new_post", %{posts: posts})
  {:noreply,
   socket
   |> push_redirect(to: UdsWeb.post_index_path(socket, :index))}
end

Hex: https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#push_redirect/2

Upvotes: 1

Peter
Peter

Reputation: 1160

As Aleksei said in his comment: You have to pass a new Post struct from your controller to your view. For example like this:

def handle_event("create_post", post, socket) do
    # Here do what you want with the data from the "post" parameter

    {:noreply, assign(socket, :post, %Post{})}   
end

Upvotes: 2

Related Questions