Using Ctrl+Enter to submit a Text Area with LiveView

Image by Annie Ruygt

In this post, we’ll explore how to use hooks and a few lines of JavaScript to trigger form submission simply by hitting Ctrl+Enter keys within a text area. Fly.io is a great place to run your Phoenix LiveView applications! Check out how to get started!

Problem

You have a text area for sending long messages. Users should be able to submit without moving their hands from the keyboard. Pressing Enter only creates a new empty line instead of sending the message:

Solution

You can define a Hook that listens for the keydown event and checks if a specific key —or key combination— is pressed. This hook can then be used to trigger an event on a DOM element, like a form.

For this example, in your app.js file, define a hook that automatically triggers the submit event for the form when you press Ctrl+Enter:

Hooks.CtrlEnterSubmit = {
  mounted() {
    this.el.addEventListener("keydown", (e) => {
      if (e.ctrlKey && e.key === 'Enter') {
        this.el.form.dispatchEvent(
          new Event('submit', {bubbles: true, cancelable: true}));
      }
    })
  }
}

By setting the bubbles option to true, you are allowing the event to propagate through the DOM tree until it reaches the window listener. This enables LiveView to recognize the submit event. Additionally, by using the cancelable option, you prevent Firefox from submitting the form via HTTP.

You have the option to choose a different key combination. For example, you can submit the form by simply pressing Enter, while still having the option to create a new line by using Shift+Enter:

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

Now, render the text area input, and add the phx-hook option:

<.input 
  field={@form[:message]} 
  type="textarea" 
  placeholder= "New message" 
  phx-hook="CtrlEnterSubmit" 
/>

It works!

Discussion

With hooks, the possibilities are endless. You can listen for different key combinations to trigger form events —such as submitting a form with phx-submit or capturing changes with phx-change—, but that’s not all! You can also use different listeners like focusout, input, or keyup to trigger those events. It’s an exciting world of possibilities, isn’t it?

Fly.io ❤️ Elixir

Fly.io is a great way to run your Phoenix LiveView app close to your users. It’s really easy to get started. You can be running in minutes.

Deploy a Phoenix app today!