svb

svb

Hi!

Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a newline to my input field (which is expected behaviour).

Is there a way to make submit work on pressing the Enter key without messing up the way the form is cleared after submitting?

I’m using below code to make the form work. This form works properly when the type of the input element is the default text type rather than a “textarea”.

    <div class="flex items-center py-2">
      <.form for={@form} phx-submit="save" phx-change="update" phx-target={@myself} >
        <.input type="textarea" field={@form[:content]} placeholder="Start typing..." autocomplete="off"/>
        <.button class="text-black" phx-disable-with="Submit">
          Submit
        </.button>
      </.form>
    </div>

Cheers,
Sil

Showing Posts 1 to 6

codeanpeace

codeanpeace

Welcome!

Here’s three distinct things to consider:

  1. listening for user interaction with a generic JS event listener on the textarea input e.g. on key down for the Enter keycode
  2. handling that event by triggering a phx-submit event on the form e.g. dispatching a “submit” event
  3. attaching the JS event listener/handler to the textarea input of a LiveView form e.g. LiveView client hooks via phx-hook

All together that might look something like:

<input type="textarea" ... phx-hook="TextArea" />
let Hooks = {}
Hooks.TextArea = {
  mounted() {
    this.el.addEventListener("keydown", e => {
      if (event.key == "Enter") {
        event.preventDefault();
        this.el.form.dispatchEvent(
          new Event("submit", {bubbles: true, cancelable: true})
        )
      }
    })
  }
}

let liveSocket = new LiveSocket("/live", Socket, {hooks: Hooks, ...})
theodore

theodore

Hey, I was just working on this today. very frustrating.
My form wasn’t clearing when a user presses enter. Seems related to: https://stackoverflow.com/questions/63649891/reset-form-input-field-after-submit-in-phoenix-liveview

This is my pure Elixir w/ a lil bit of Liveview.JS solution. One caveat, if the user presses “shift + enter”, the form will submit

def mount(socket) do
  {:ok,
   socket
   |> assign(:input_message_form, to_form(%{"message" => ""}))
   |> assign(:user_input_value, "")}
end

def handle_event("submit_message", %{"message" => message}, socket) do
  # Do something with the message
  {:noreply, socket |> assign(:user_input_value, "")}
end

def handle_event("user_input_change", %{"message" => changed_input_value}, socket) do
  {:noreply, socket |> assign(:user_input_value, changed_input_value)}
end

def render(assigns) do
  ~H"""
  <.form
    id="input-message-form"
    for={@input_message_form}
    phx-submit="submit_message"
    phx-target={@myself}>
    
    <.input
    field={@input_message_form[:message]}
    type="textarea"
    phx-keydown={JS.dispatch("submit", to: "#input-message-form")}
    phx-key="Enter"
    phx-change="user_input_change"
    phx-target={@myself}
    value={@user_input_value}
    />
    <button type="submit">Submit</button>
  </.form>
  """
end

svb

svb OP

Thanks for the quick reply!

Works like a charm. I think the way the submit event is triggered from this hooks is a neat solution :slight_smile:

I’ve added a check on the Shift key so that form will not submit on Shift+Enter and instead will add a newline to the textarea:

mounted() {
  this.el.addEventListener("keydown", e => {
    if (e.key == "Enter" && e.shiftKey == false) {
      e.preventDefault();
      this.el.form.dispatchEvent(
        new Event("submit", {bubbles: true, cancelable: true})
      )
    }
  })
}
svb

svb OP

Hi theodore,

I think you don’t need the value={@user_input_value} since you already bind field={@input_message_form[:message]}. If you get rid of the @user_input_value you can use the form itself to update the value. For proper clearing of the form it was necessary to update the form with the phx-change callback function (see How to clear a textbox after submit - #2 by andreaseriksson).

My LiveComponent looks like below, but this should also work for a LiveView:

  def update(assigns, socket) do
    {:ok,
     socket
     |> assign(assigns)
     |> assign_form}
  end

  defp assign_form(socket, content \\ nil) do
    assign(socket, :form, to_form(%{"content" => content}, as: "message"))
  end

  def handle_event("update", %{"message" => %{"content" => content}}, socket) do
    # This function seems to be required for clearing the form after submitting because Phoenix LiveView
    # needs to keep track of the items and can't clean properly otherwise (https://forum.elixirforum.com/t/how-to-clear-a-textbox-after-submit/47002/2)
    {:noreply,
     socket
     |> assign_form(content)}
  end

  def handle_event("save", %{"message" => message_params}, socket) do
    # We don't want to handle messages here. Send them to parent and let parent
    # deal with it.
    send self(), {:new_message, message_params}

    # Set empty form since we propagated the message to parent
    {:noreply,
     socket
     |> assign_form}
  end

  def render(assigns) do
    ~H"""
    <div>
      <.form id="message-form" for={@form} phx-submit="save" phx-change="update" phx-target={@myself}>
        <div class="flex-1 min-w-0">
          <.input
            field={@form[:content]}
            placeholder="Start typing..."
            autocomplete="off"
           />
        </div>
        <.button phx-disable-with="Submit">
          Submit
        </.button>
      </.form>
    </div>
    """
  end

Maybe try making it function properly first with a regular form and then switch to a textarea by using the code suggested by @codeanpeace?

theodore

theodore

Yea that’s what I thought too, but for some reason the field attribute doesn’t populate the value inside the input. I think I’ll also switch to hooks so I can easily have the shift + enter functionality.

axelclark

axelclark

I was running into a similar issue. I ended up pushing an event after creating a new message then clearing the field when I receive the event in the frontent.

in form_component.ex

    case Chats.create_message(message_params) do
      {:ok, _message} ->
        {:noreply,
         socket
         |> push_event("clear-textarea", %{id: "message_content"})
         |> push_patch(to: socket.assigns.patch)}

in app.js

window.addEventListener(`phx:clear-textarea`, (e) => {
  let el = document.getElementById(e.detail.id)
  el.value = ""
})
— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
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
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
mnkhod
So i have been using ash framework for a while and i love it. However currently the issue im having with ash framework is the error handl...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
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
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews