Andrey Hihlovskiy

Professional blog on groovy, gradle, Java, Javascript and other stuff.

“focusable” behavior

Task: Suppose, you want to create web-page with few areas. Each area has multiple inputs. When focus “belongs” to a particular area, it is indicated with some CSS and area captures keyboard navigation.

Problem: how to manage focus transfer within the area (that means, between inputs of the area) and between areas – with as less code as possible?

Solution: include small script:

jQuery(function($) {
  $("body").on("click focusin", function(event) {
    var thisFocusable = $(event.target).closest(".focusable");
    $(".focusable.focused").not(thisFocusable).removeClass("focused").trigger("lostFocus.focusable");
    if(!thisFocusable.hasClass("focused"))
      thisFocusable.addClass("focused").focus().trigger("gotFocus.focusable");
  });
});

then add “focusable” class to areas:

<div id="div1" class="focusable"> ... </div>
<div id="div2" class="focusable"> ... </div>
<div id="div3" class="focusable"> ... </div>

then attach keyboard handlers:

$("body").on("keydown", "div1.focused", function(event) {
  // process keyboard events
});
$("body").on("keydown", "div2.focused", function(event) {
  // process keyboard events
});
</code>

Note the difference between “focusable” and “focused” classes. With “focusable” you mark areas of web-page that can be focused. “focused” class is automatically assigned to the currently focused area. There is always only one element having “focused” class.

Additional benefit: you get two new event types – “gotFocus.focusable” and “lostFocus.focusable”. Differently from “focusin” and “focusout”, these events are only triggered when focus is moved between the areas. Focusing within the same area does not trigger them.

See how all this works on this online example.

You can get complete source code from this github repository.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: