Control HTML Focus from Rails Server
Summary
An easy way to control the focus of DOM-elements from RailsLesson
Sometimes, it is important to control exactly which DOM-element is focused after a user interaction. For a project of mine, I implemented keyboard controls and wanted to keep the focus on a given node after moving it down or up, triggering a HTTP request to Rails to render the reordered elements (in a Turbo Frame), that was morphed from a Turbo Stream Action. Initially I was trying to listen for some event trigger after the form submission or the morphing was done, but couldn't get the job done. Then I remembered custom Turbo Stream Actions and made this work in a breeze.
In your Javascript, define a custom action like this
import "@hotwired/turbo-rails"
Turbo.StreamActions.focus = function () {
const target = this.getAttribute("target")
const focusElement = document.querySelector(target)
if (focusElement) focusElement.focus()
}
Then, in your response that you send back from the server, include your Custom Stream Action, e.g.
<turbo-stream action="focus" target='[data-uuid="<%= @workitem.uuid %>"]'></turbo-stream>
In the example above, I'm targeting a unique node with the HTML attribute data-uuid="<something>"
, but the Stream Action is very versatile and can be used for other situations as well.