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?