按列的垂直顺序设置tabindex

时间:2016-07-25 19:19:25

标签: javascript jquery html

我为输入类型文本分配了tabindex,并且没有禁用/隐藏。以下是我尝试过的,它的确有效。但是,索引的顺序在表中水平分配。我需要列顺式而不是水平的tabindex顺序。任何建议如何实现?我希望订单如下    这个Q是对此enter key to follow the tabindex (in scenario where enter key is changed to behave as tab)的跟进。

   col1 col2 col3
    1      3    7
    2      4    8
           5    9 
           6   10  

(":input:not([disabled]):not(:hidden)").not($(":submit")).not($(":reset")).each(function (i) { $(this).attr('tabindex', i + 1); })

4 个答案:

答案 0 :(得分:3)

此示例将帮助您根据列设置tabindex



function fixVerticalTabindex(selector) {
  if (typeof selector == 'undefined') {
    selector = '.reset-tabindex';
  }
  var tabindex = 1;
  $(selector).each(function(i, tbl) {
    $(tbl).find('tr').first().find('td').each(function(clmn, el) {
      $(tbl).find('tr td:nth-child(' + (clmn + 1) + ') input').each(function(j, input) {
        $(input).attr('placeholder', tabindex);
        $(input).attr('tabindex', tabindex++);
      });
    });
  });
}
$(function() {
  $('#btn-fix').click(function() {
    fixVerticalTabindex('.reset-tabindex');
  });
});

table {
  border: 1px solid red;
}

input {
  border: 1px solid black;
  width: 75px;
  height: 65px;
  font-size: 25px;
  text-align: center;
}

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

<table class="reset-tabindex">
  <tr>
    <td><input /></td>
    <td>no input</td>
    <td>no input</td>
  </tr>
  <tr>
    <td>no input</td>
    <td><input /></td>
    <td><input /></td>
  </tr>
  <tr>
    <td><input /></td>
    <td>no input</td>
    <td><input /></td>
  </tr>
</table>
<br /><br />
<table class="reset-tabindex">
  <tr>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
  </tr>
  <tr>
    <td>no input</td>
    <td>no input</td>
    <td>no input</td>
    <td>no input</td>
    <td><input /></td>
  </tr>
  <tr>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
  </tr>
  <tr>
    <td>no input</td>
    <td>no input</td>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
  </tr>
  <tr>
    <td>no input</td>
    <td>no input</td>
    <td><input /></td>
    <td><input /></td>
    <td><input /></td>
  </tr>
</table>
<br /><br />
<button id="btn-fix">Click to fix vertical tabindex</button>
&#13;
&#13;
&#13;

该功能将&#34;修复&#34;它上面的每个表都是自己的(不会在不同表的列之间混合)。

  

我没有检查colspan / rowspan表的功能,但我的猜测是正常工作。

$(input).attr('placeholder', tabindex);仅用于预览和调试,您可以在生产时删除。

答案 1 :(得分:2)

基于this solution的箭头键,我修改了代码以使用回车键和带有指定列式模式的Tab键。

我不认为为这种情况指定tabindex属性是最好的主意。您必须在列数或行数的每次更改时重新计算它们。此外,它还会改变页面上可聚焦元素的流量(表格首先是其周围)。

&#13;
&#13;
/*!
* based on formNavigation https://github.com/omichelsen/FormNavigation
*/
(function ($) {
  $.fn.formNavigation = function () {
    $(this).each(function () {
      // Events triggered on keyup
      $(this).find('input').on('keyup', function(e) {
        switch (e.which) {
          // arrow right
          case 39:
            $(this).closest('td').next().find('input').focus();
            break;

          // arrow left
          case 37:
            $(this).closest('td').prev().find('input').focus();
            break;

          // arrow bottom
          case 40:
            $(this).closest('tr').next().children().eq($(this).closest('td').index()).find('input').focus();
            break;

          // arrow top
          case 38:
            $(this).closest('tr').prev().children().eq($(this).closest('td').index()).find('input').focus();
            break;

          // enter
          case 13:
            if ($(this).closest('td').next().find('input').length>0) {
              // when there is another column on right
              $(this).closest('td').next().find('input').focus();
            } else {
              // when last column reached
              $(this).closest('tr').next().children().eq(1).find('input').focus();
            }
            break;
        }
      });
      
      // Events triggered on keydown (repeatable when holding the key)
      $(this).find('input').on('keydown', function(e) {
        // Vertical navigation using tab as OP wanted
        if (e.which === 9 && !e.shiftKey) {
          // navigate forward
          if ($(this).closest('tr').next().find('input').length>0) {
            // when there is another row below
            e.preventDefault();
            $(this).closest('tr').next().children().eq($(this).closest('td').index()).find('input').focus();
          } else if ($(this).closest('tbody').find('tr:first').children().eq($(this).closest('td').index()+1).find('input').length>0) {
            // when last row reached
            e.preventDefault();
            $(this).closest('tbody').find('tr:first').children().eq($(this).closest('td').index()+1).find('input').focus();
          }
        } else if (e.which === 9 && e.shiftKey) {
          // navigate backward
          if ($(this).closest('tr').prev().find('input').length>0) {
            // when there is another row above
            e.preventDefault();
            $(this).closest('tr').prev().children().eq($(this).closest('td').index()).find('input').focus();
          } else if ($(this).closest('tbody').find('tr:last').children().eq($(this).closest('td').index()-1).find('input').length>0) {
            // when first row reached
            e.preventDefault();
            $(this).closest('tbody').find('tr:last').children().eq($(this).closest('td').index()-1).find('input').focus();
          }
        }
      });
    });
  };
})(jQuery);

// usage
$('.gridexample').formNavigation();
&#13;
/* For demonstration only */
.gridexample {
  font-size: 1.1em;
}
.gridexample th {
  padding: .15em .5em;
}
.gridexample td {
  padding: .1em;
  width: 5em;
}
.gridexample input[type="text"] {
  width: 100%;
  line-height: 2;
  box-sizing: border-box;
}
&#13;
<p>
  Sample <a href="#">links</a> around the table (to simulate <a href="#">focus</a> outside the table).
</p>

<table class="gridexample">
  <thead>
    <tr>
      <th></th>
      <th>A</th>
      <th>B</th>
      <th>C</th>
      <th>D</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>1</th>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
    </tr>
    <tr>
      <th>2</th>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
    </tr>
    <tr>
      <th>3</th>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
    </tr>
    <tr>
      <th>4</th>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
      <td><input type="text"></td>
    </tr>
  </tbody>
</table>

<p>
  Sample <a href="#">links</a> around the table (to simulate <a href="#">focus</a> outside the table).
</p>

<!-- jQuery needed for this solution -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

来自@ Merlyn Morgan-Graham解决方案How can I use jQuery to reassign the tab-order from horizontal to vertical in a table? 和@dekel解决方案在这里,我想出了以下答案。哪个适用于大多数情况。 enter key to follow the tabindex (in scenario where enter key is changed to behave as tab)

function assignTabIndex() {
    // Define variables 
    var maxRowCount = 0;        
    // Loop through all rows and find the children (td) length
    // Get the maxRowCount
    $('table tbody tr').each(function() {
        maxRowCount = Math.max(maxRowCount, $(this).children('td').length);        
    });

    // Define and start the cell count at 1
    var cellCounter = 1;
    // Loop through the table, column first instead of row first
    for (var columnIndex = 0; columnIndex < maxRowCount; ++columnIndex) {
        // Loop through all the rows for the current column
        $('form table tr').each(function() {
            // ...but only look at cells matching the current column
            var cellForCurrentColumn = $(this)
                .children('td')
                .eq(columnIndex)
                .find('input[type =text]:not([disabled])');
            // Some rows could be bigger than others,
            // so cellForCurrentColumn might not exist for shorter rows
            if (cellForCurrentColumn != null) {
                // Set the tab index and then increment the counter
                cellForCurrentColumn.attr('tabindex', cellCounter++);
            }
        });
    }
};
// Enter key to follow tab index

   function EnterKeyAsTabKey() {
    $(document).ready(function() {
        assignTabIndex(); //call the assignTabIndex function

        // Will only run once the page Document Object Model (DOM) is ready for JavaScript code 
        // Create a jQuery object containing the html element 'input', and not disabled
        // Create a .not() method to exclude buttons for keypress event
        $(":input:not([disabled])").not($(":button")).keypress(function(evt) {
            // If the keypress event code is 13 (Enter)
            if (event.which === 13 && this.type !== 'submit' || 'reset') {
                evt.preventDefault();
                // Get the attribute type and if the type is not submit
                itype = $(this).prop('type');
                // Get the current Tabindex
                currentTabindex = $(this).attr('tabindex');
                // alert(currentTabindex); // alert to check the value a variable has. Good for trouble shoot
                if (currentTabindex) {
                    nextInput = $('input[tabindex^="' + (parseInt(currentTabindex) + 1) + '"]');
                    // console.log(this, nextInput); // to print next input in console. Good for trouble shoot
                    if (nextInput.length) {
                        nextInput.focus();
                    } else
                        return false;

                }

            }
        });
    })
};

答案 3 :(得分:0)

这是解决方案,如果您的所有输入都在同一级别的 div 中(假设每个都在 Bootstrap col-md-* 中):

let columns_number=4; // static for me, but you can send/get it via data-columns="4" as form attribute

$('form').find('input, select, textarea').each(function(){
    $(this).attr('tabindex', $(this).attr('type')==='submit' ? 999 : $(this).closest('div').index()%columns_number+1);
});

JSFiddle:https://jsfiddle.net/x5oh7edf/