neurodynamic

neurodynamic

I have a form that I want to be automatically submitted when a user presses “Enter” inside of its textarea field, but I want shift+enter to add a newline. So I setup a hook for this that includes this listener function:

function listener(event) {
  if (event.key == "Enter" && !event.shiftKey && !event.repeat) {
    event.preventDefault()
    this.pushEventTo(this.el, "textarea-submit")
  }
}

and I have some handle_event branches that look like this:

  def handle_event("textarea-submit", params, socket) do
    save_comment(socket, socket.assigns.action, socket.assigns.form.params)
  end

  def handle_event("save", %{"comment" => comment_params}, socket) do
    save_comment(socket, socket.assigns.action, comment_params)
  end

They work exactly how you’d expect except that if the comment is saved via the “save” event getting triggered, the textarea gets cleared like you’d expect. If it is saved via the “textarea-submit” event, the comment saves just fine, but the textarea retains the value that was there before submission.

Any ideas why this might be happening? I don’t think it’s anything in the handle_event code because the “textarea-submit” branch works fine if I change the form element’s code to phx-submit="textarea-submit". It seems to be something about the fact that it’s triggered from the JavaScript side.

The textarea field code looks like this:

          <.input
            field={@form[:content]}
            id={new_comment_content_field_id(@post)}
            type="textarea"
            phx-hook="EnterSubmit"
            />

Showing Posts 1 to 7

neurodynamic

neurodynamic OP

Update: it works fine if I change this

function listener(event) {
  if (event.key == "Enter" && !event.shiftKey && !event.repeat) {
    event.preventDefault()
    this.pushEventTo(this.el, "textarea-submit")
  }
}

to this

function listener(event) {
  if (event.key == "Enter" && !event.shiftKey && !event.repeat) {
    event.preventDefault()
    const newEvent = new MouseEvent("click")
    event.target.form.querySelector("button").dispatchEvent(newEvent)
  }
}

so it really does seem to be something with pushEventTo specifically.

codeanpeace

codeanpeace

That’s expected behavior as LiveView intentionally refrains from overwriting focused inputs.

JavaScript client specifics

The JavaScript client is always the source of truth for current input values. For any given input with focus, LiveView will never overwrite the input’s current value, even if it deviates from the server’s rendered updates.

source: Form bindings — Phoenix LiveView v1.2.5

03juan

03juan

Have you considered the form’s usability for mobile users, where there is no shift-enter?

Overriding enter as new line seems counterintuitive to the generally expected UX of textareas and would probably cause friction and frustration for most users.

neurodynamic

neurodynamic OP

That’s a good point; I think I’ll change it to control/command + enter. There’s also a button to do it for places where the shortcuts aren’t an option.

03juan

03juan

Also I was looking into the original question of programmatically submitting a form and found that there are two form submit functions, submit() and requestSubmit(). I wasn’t aware of the second one, which forces the browser to run client-side validations, vs. plain submit which just submits without validation. Not sure how this plays with LiveView, but something to be aware of?

So in your hook you can probably capture and prevent default on ctrl/cmd-enter and just call this.el.form.requestSubmit() without needing to create and dispatch a custom event, or push_event back to the server.

neurodynamic

neurodynamic OP

Ooh, thank you for this! requestSubmit does seem to play very nicely and it feels much less awkward than the click-event simulation I was doing before.

sbaildon

sbaildon

One caveat for requestSubmit() is that it’s only supported on Safari >= 16, which, as of this post, is less than a year old. Still, browser coverage is pretty good at 89.75%

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
matt-savvy
Anyone here using Honeybadger? My Honeybadger account is being overwhelmed with noise from some bots. Seeing a lot of Bandit.HTTPError...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New

Other Trending Topics Top

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
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews