Creating a Loop for Tabs on an HTML Form

When navigating through form input boxes using the tab key, it usually goes in order. However, I discovered that you can actually customize this order by using tabindex=x. Since I have 5 inputs on my form, I use tabindex 5 times to specify the order. But after those 5, the focus moves to other elements on the page. Is there a way to create a loop so that the tab key cycles only through those initial 5 items? Unfortunately, I can't use tabindex=0 because then I'd have to add it to hundreds of other items as well. So, my question is how can I establish a "tab loop" for these specific 5 items?

Answer №1

Tab looping cannot be set up declaratively. This functionality is meant to align with the standard tabbing behavior of the browser, which includes navigating through all tab-able elements on the page and in the browser interface.

If you wish to restrict tabbing from a specific group of elements, JavaScript will be necessary. It's important to understand why this limitation is being imposed, provide clear visual indicators that certain elements are focused over others, and consider users who rely on keyboard navigation without visuals.

If after careful consideration you decide to alter the tabbing sequence, one approach is to create hidden tabbable elements (though still displayed) positioned before and after your target form items. These elements will redirect focus back to the beginning or end of the form as needed.

preFormDummy.addEventListener('focus', function(e){
  lastFormItem.focus() }, true )

postFormDummy.addEventListener('focus', function(e){
  firstFormItem.focus() }, true )

Remember to initially disable these dummy elements and only enable them once the form is accessed, signalling a modal state. Disable them again once the form interaction is complete.

It is crucial to conduct user testing to gauge reactions to this adjusted tabbing behavior. Feedback will reveal if users find it helpful or unsettling due to unexpected changes in tab navigation.

Answer №2

After experimenting with jQueryUI, I discovered a simple method to accomplish this task. I established a .tabloop class and implemented the code snippet below.

If you're looking for the :tabbable selector, it's not inherent in jQuery but can be easily created using jQueryUI.

// Focus loop within an element with the tabloop class
$(function() {
  $(document).on('keydown', '.tabloop :tabbable:not([readonly])', function(e) {

    // Only consider Tab key (code 9)
    if (e.keyCode != 9)
      return;

    var loop = $(this).closest('.tabloop');

    // Obtain first and last tabbable elements
    var firstTabbable = loop.find(':tabbable:not([readonly])').first();
    var lastTabbable = loop.find(':tabbable:not([readonly])').last();

    // When leaving the first element with Shift + Tab, focus on the last one
    if (firstTabbable.is(e.target) && e.shiftKey == true) {
      e.preventDefault();
      lastTabbable.focus();
    }

    // When leaving the last element with Tab, focus on the first one
    if (lastTabbable.is(e.target) && e.shiftKey == false) {
      e.preventDefault();
      firstTabbable.focus();
    }
  });
});
.tabloop {
  border: 1px red solid;
  padding: 1ch;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<p>
  <label for="text1">Field 1:</label>
  <input type="text" id="text1">
</p>

<p>
  <label for="text2">Field 2:</label>
  <input type="text" id="text2">
</p>

<p>
  <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank">Link</a>
</p>

<p>
  <button type="button">Button</button>
</p>

<div class="tabloop">

  <p>
    <label for="text3">Field 3:</label>
    <input type="text" id="text3">
  </p>

  <p>
    <label for="text4">Field 4:</label>
    <input type="text" id="text4">
  </p>

  <p>
    <a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank">Link</a>
  </p>

  <p>
    <button type="button">Button</button>
  </p>
</div>

Answer №3

Following up on @NicolasBernier's JqueryUI solution, here is the modified code that successfully worked without using the ':tabbable' keyword.

// This section deals with the first tabbable element
$('containerOfInterest').find('firstTabbableElement(e.g. "a")').first().on('keydown', function (e) {

    // Handling shift and tab on the first element
    if (e.shiftKey == true && e.keyCode == 9) {
        console.log('Shift tab on first')
        e.preventDefault();
        
        $('containerOfInterest').find('lastTabbableElement(e.g. "button")').last().focus();
    }
});

// Handling tab on the last element: focusing back to the first one
$('containerOfInterest').find('lastTabbableElement(e.g. "button")').last().on('keydown', function (e) {

    // Leaving the last element with Tab : focus the first one
    if (e.shiftKey == false && e.keyCode == 9) {
        console.log('tab on last')
        e.preventDefault();

        $('containerOfInterest').find('firstTabbableElement(e.g. "a")').first().focus();
    }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Obtain the URL currently loaded in the browser, excluding any URLs retrieved using jQuery's $.get function

I am working with a controller named examples.php, which contains the following function: public function total_records_of_current_dataset(){ $url = base_url().uri_string(); $get_current_segment = $this->uri->segment(3); $count_all_rows ...

I am curious to understand the reasons behind the occurrence of this ID problem

When I format my code like this const title = document.getElementById("title"); function handleClick() { title.style.color = "red"; } title.addEventListener("click", handleClick); everything works fine. However, if I c ...

Retrieve the original state of a ReactJs button from the database

I am completely new to ReactJs and I have a question regarding how to set the initial state of a button component based on data from an SQL database. I am successfully retrieving the data using PHP and JSON, but I am struggling with setting the state corre ...

Learn how to retrieve data from the console and display it in HTML using Angular 4

Need help fetching data inside Angular4 HTML from ts variable. Currently only able to retrieve 2 data points outside the loop. Can anyone assist with pulling data inside Angular4? HTML: <tr *ngFor="let accept of accepts"> ...

Guidelines on centering an AJAX spinning animation within a parent div

Below is the basic structure of an HTML document for a webpage. <div class="grand-parent"> <div class="header">Heading</div> <div class="parent-div"> <div class="child-div-1"></div> ...

sending data from a servlet to ajax

Implementing a star-based voting system involves sending an ajax request to update the database through a servlet when a user casts their vote. This is the ajax code used: $.ajax({ type:'GET', contentType: "charset=utf- ...

Animating each individual element within the v-for loop in Vue.JS

Recently, I developed a basic to-do app using VueJS. Additionally, I integrated vue2-animate, which is a Vue.js 2.0 adaptation of Animate.css used for Vue's built-in transitions. The animation feature that adds an element functions correctly. However ...

Guide to removing selected value from a combobox in Angular

I am working on a simple HTML file that consists of one combobox and one clear button. I want the clear button to remove the selected value from the combobox when clicked. Below is my code: mat-card-content fxLayout="row wrap" fxLayoutAlign="left" fxLayou ...

Issues with Codeigniter's ajax pagination search functionality failing to display search results as

For my Ajax pagination, I referred to this site and made some modifications: Everything was working well until I encountered an issue with the pagination after performing a search. For example, when I conduct a search, the pagination links appear correct ...

The setter function for a boolean value in React's useState hook is malfunctioning

I encountered an issue while trying to update a state value using its setter from the useState hook. Surprisingly, the same setter worked perfectly in a different function where it set the value to true. To confirm that the function call was correct, I te ...

Dealing with JSON feed and function events problem with jQuery fullcalendar in Internet Explorer

Currently, I am utilizing jQuery fullcalendar in conjunction with Grails. Initially, I was utilizing events (in the form of a json feed) and observed that each time the user clicks on prev/next or changes views, the json feed URL is invoked. Considering t ...

Instructions for sending a server error response with php

When the user clicks on the delete button, my jQuery script sends a request to the server to delete the selected item. Now, I want my php script to return either a success or an error response. Is it possible to trigger the error callback if the item can ...

Guide to create a sliding menu transition from the viewport to the header

I am just starting to learn jQuery and I want to create a menu similar to the one on this website Specifically, I would like the menu to slide down from the viewport to the header, as shown in the template in the link. I have searched through the jQuery ...

The Price Filtering feature in the MERN Stack for Products is currently experiencing technical difficulties

Hey there! I am currently working on developing an Ecommerce Application using the MERN Stack with redux. I've encountered a problem while trying to send a price array argument in my fetching function. The error message states: XHR GET http://localhos ...

Steps for organizing a list based on the number of clicks

I've created an HTML list with images of political party logos. Each logo is a grid item that can be clicked on. I want to sort the list based on the number of clicks each logo receives, essentially ranking them by popularity. However, I'm not su ...

Utilizing the Model URL Parameter in VueJS

In the context of , my objective is to dynamically modify a range input element and reflect that change in the URL. // Incorporating URL update with range input manipulation var Hello = Vue.component('Hello', { template: ` <div> &l ...

Error: Authorization requires both data and salt arguments

As a novice in NodeJS, I attempted to create an authentication form using NodeJS + express. The issue I am facing is regarding password validation - specifically, when "confirmpassword" does not match "password", it should return nothing. Despite my effo ...

creating dynamic parameterized URLs in Laravel

For example: Here are a few names. - Mujib - Amjed - Anees When someone clicks on "Mujib," the URL should remain the same and only the parameter should change. When someone clicks on "Amjed," the URL parameter should change to . ...

data not being transferred successfully to the SQL input from forms

The data from this input form is not being properly transferred to the SQL database when using the sqlAddUser.php file available at pastebin.com/W9BH0D3s. The form includes the following fields: <form action="sqlAddUser.php" method="post"> <div c ...

Finding it difficult to grasp the concept of enabling CORS through an ajax request

I'm struggling to figure out how to enable CORS while using Ajax to send data to a remote server on a different domain. Despite researching extensively and reading numerous Stackoverflow threads, I can't seem to make sense of it all. I understand ...