Paul Taylor
Paul Taylor

Reputation: 13190

Configure Up/Down arrow to move up/down a row in html table

I have an html table, pressing TAB moves to next element in row and SHIFT-TAB goes back one element, this is fine hence I dont want to modify tabindex attribute to change this.

But I would also like the user to be able to traverse the table up and down using the arrows keys, how do I implement this.

Im using Html5 with a little bit of Javascript and CSS

<table class="edittable">
<tr>
  <th class="tableheading verysmallinputfield" style="position:relative">
      <label>
          #
      </label>
  </th>
  <th class="tableheading smallinputfield" style="position:relative">
      <label>
          Disc No
      </label>
  </th>
  <th class="tableheading smallinputfield" style="position:relative">
      <label>
          Disc Total
      </label>
  </th>
  <th class="tableheading largeinputfield" style="position:relative">
      <label>
          Disc Subtitle
      </label>
  </th>
</tr>
<tr>
  <td class="tableheading">
      1
  </td>
  <td>
      <input name="1DISC_NO" value="01" style="width:100%" type="number" min="1" max="999">
  </td>
  <td>
      <input name="1DISC_TOTAL" value="01" style="width:100%" type="number" min="1" max="999">
  </td>
  <td>
      <input name="1DISC_SUBTITLE" value="" style="width:100%" type="text">
  </td>
</tr>
<tr>
  <td class="tableheading">
      2
  </td>
  <td>
      <input name="2DISC_NO" value="01" style="width:100%" type="number" min="1" max="999">
  </td>
  <td>
      <input name="2DISC_TOTAL" value="01" style="width:100%" type="number" min="1" max="999">
  </td>
  <td>
      <input name="2DISC_SUBTITLE" value="" style="width:100%" type="text">
  </td>
</tr>
</table>

Update

I am getting key press detected, but having problem with activeElement. The element is defined but when I try to get tagname or parent its always undefined, dont understand why.

<script>
            document.onkeydown = function (e) {
    switch (e.key) {
        case 'ArrowUp':
            var el = document.activeElement;
            alert($(el)); 
            alert($(el).tagName); 
            alert($(el).closest('td').innerHtml); 
            break;
        case 'ArrowDown':
            var el = document.activeElement;
            alert($(el).closest('td').innerHtml); 
            break;
    }
};
        </script>

Upvotes: 0

Views: 3895

Answers (2)

Yash Mochi
Yash Mochi

Reputation: 967

Solution, where I've tried to keep JS simple?

document.onkeydown =
  function updownintable(e) {
    var el = document.activeElement;
    var rowNo = el.parentNode.parentNode.rowIndex;
    var columnNo = el.parentNode.cellIndex;
    var bodyElement = document.getElementById(tableElementId).children[0];

    switch (e.key) {
      case 'ArrowUp':
        rowNo--;
        break;
      case 'ArrowDown':
        rowNo++;
        break;
      case 'ArrowLeft':
        columnNo--;
        break;
      case 'ArrowRight':
        columnNo++;
        break;
    }
    bodyElement.children[rowNo].children[columnNo].children[0].focus();
};

Where tableElementId = id of html table.

Upvotes: 0

Paul Taylor
Paul Taylor

Reputation: 13190

I now have it working

Html:

   <table class="edittable" id="menu_disctable">
      <tr>
        <th class="tableheading verysmallinputfield" style="position:relative">
          <label>
                                            #
                                        </label>
        </th>
        <th class="tableheading smallinputfield" style="position:relative">
          <label>
                                            Disc No
                                        </label>
        </th>
        <th class="tableheading smallinputfield" style="position:relative">
          <label>
                                            Disc Total
                                        </label>
        </th>
        <th class="tableheading largeinputfield" style="position:relative">
          <label>
                                            Disc Subtitle
                                        </label>
        </th>
      </tr>
      <tr id="menu_disc1">
        <td class="tableheading">
          1
        </td>
        <td>
          <input name="1_DISC_NO" id="1_DISC_NO" value="01" style="width:100%" type="number" min="1" max="999">
        </td>
        <td>
          <input name="1_DISC_TOTAL" id="1_DISC_TOTAL" value="01" style="width:100%" type="number" min="1" max="999">
        </td>
        <td>
          <input name="1_DISC_SUBTITLE" id="1_DISC_SUBTITLE" value="" style="width:100%" type="text">
        </td>
      </tr>
      <tr id="menu_disc2">
        <td class="tableheading">
          2
        </td>
        <td>
          <input name="2_DISC_NO" id="2_DISC_NO" value="01" style="width:100%" type="number" min="1" max="999">
        </td>
        <td>
          <input name="2_DISC_TOTAL" id="2_DISC_TOTAL" value="01" style="width:100%" type="number" min="1" max="999">
        </td>
        <td>
          <input name="2_DISC_SUBTITLE" id="2_DISC_SUBTITLE" value="" style="width:100%" type="text">
        </td>
      </tr>
    </table>

Javascript

document.onkeydown =
  function updownintable(e) {
    switch (e.key) {
      case 'ArrowUp':
        var el = document.activeElement;
        var rowNo = el.id.substring(0, el.id.indexOf("_"));
        var fieldId = el.id.substring(el.id.indexOf("_"));
        if (rowNo > 1) {
          rowNo--;
          var newId = rowNo + fieldId;
          var newEl = document.getElementById(newId);
          if (newEl != null) {
            newEl.focus();
          }
        }
        break;
      case 'ArrowDown':
        var el = document.activeElement;
        var rowNo = el.id.substring(0, el.id.indexOf("_"));
        var fieldId = el.id.substring(el.id.indexOf("_"));
        rowNo++
        var newId = rowNo + fieldId;
        var newEl = document.getElementById(newId);
        if (newEl != null) {
          newEl.focus();
        }
        break;
    }
  };

https://jsfiddle.net/paultaylor/480Ln4y6/1/

Upvotes: 1

Related Questions