'Using arrow keys in a table but having it start from the selected table cell

I am trying to use arrow keys to navigate a table.
The below code works but the problem is that it will only navigate from the last place the arrow key was used. If I click on a cell somewhere else in the table, the arrow key starts from the last position that was moved with the keyboard, not the clicked cell. This is the code and I assume I need to change the start from the query selector to wherever the mouse last clicked/selected. Any ideas? Javascript only please, no jquery. Thank you

     function Mouse() { 

let start = document.querySelector('.first-element');

const changeStyle = (sibling) => {

  if (sibling !== null) {

    start.focus();

    sibling.focus();

    start = sibling;

  }

}

 

const checkKey = (event) => {

  event = event || window.event;

  const idx = start.cellIndex;

 

  if (event.keyCode === 38) {

    // up arrow

    const previousRow = start.parentElement.previousElementSibling;

    if (previousRow !== null) {

      const previousSibling = previousRow.cells[idx];

      changeStyle(previousSibling);

    }

  } else if (event.keyCode === 40) {

    // down arrow

    const nextRow = start.parentElement.nextElementSibling;

    if (nextRow !== null) {

      const nextSibling = nextRow.cells[idx];

      changeStyle(nextSibling);

    }

  } else if (event.keyCode === 37) {

    // left arrow

    const previousSibling = start.previousElementSibling;

    changeStyle(previousSibling);

  } else if (event.keyCode === 39) {

    // right arrow

    const nextsibling = start.nextElementSibling;

    changeStyle(nextsibling);

  }

}

document.onkeydown = checkKey;

}


Solution 1:[1]

I believe that it will help you. move key is [alt] + [shift] + [arrow keys].

const myTable = document.querySelector('#my-Table tbody')
    , nbRows  = myTable.rows.length
    , nbCells = myTable.rows[0].cells.length
    , movKey  = { ArrowUp    : p=>{ p.r = (--p.r +nbRows ) % nbRows  }
                , ArrowLeft  : p=>{ p.c = (--p.c +nbCells) % nbCells }
                , ArrowDown  : p=>{ p.r = ++p.r % nbRows  }
                , ArrowRight : p=>{ p.c = ++p.c % nbCells }
                }

// get On Focus event on Table elements
myTable
  .querySelectorAll('input, [contenteditable=true]')
  .forEach(elm=>{elm.onfocus=e=>
    {
    let sPos  = myTable.querySelector('.select')
      , tdPos = elm.parentNode

    if (sPos) sPos.classList.remove('select')

    tdPos.classList.add('select')
    }
  })


document.onkeydown=e=>
  {
  let sPos = myTable.querySelector('.select')
    , evt  = (e==null ? event:e)
    , pos  = { r: sPos?sPos.parentNode.rowIndex:-1
             , c: sPos?sPos.cellIndex:-1
             }

  if ( sPos                 // previous pos focus exist...
    && evt.altKey
    && evt.shiftKey         // addin shift to control
    && movKey[evt.code] )   // evt.ctrlKey... ?
    {
    let loop    = true
      , nxFocus = null
      , cell    = null
    do
      {
      movKey[evt.code](pos)
      cell    = myTable.rows[pos.r].cells[pos.c]                    // possible <td> for new focus...
      nxFocus = cell.querySelector('input, [contenteditable=true]') // get focussable element of <td>

      if ( nxFocus 
      && cell.style.display!=='none' 
      && cell.parentNode.style.display!=='none')
        {
        nxFocus.focus()
        loop = false
        }
      }
      while (loop)
    }
  }
#my-Table {
  border-collapse: collapse;
  font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
  font-size: 14px;
}
#my-Table td {
  min-width:20px;
  text-align: center;
  border: 1px solid grey;
  padding: 2px 5px;
  white-space: nowrap;
}
.select { background-color: aqua } /* just for the control, delete this line when commissioning the operation */
<table id="my-Table">
  <tbody>
    <tr>
      <td><input placeholder="r0, c0"></td>
      <td><div contenteditable="true">Content Editable 1 r0, c1</div></td>
      <td style="display: none;"><input placeholder="r0, c2"></td>
      <td><div contenteditable="true">Content Editable 2 r0, c3</div></td>
      <td><input placeholder="r0, c4"></td>
      <td>Not Editable</td>
    </tr>
    <tr style="display: none;">
      <td><input placeholder="r1, c1"></td><td><div contenteditable=" true">Content Editable 1</div></td>
      <td style="display: none;"><input value="Input 2"></td>
      <td><div contenteditable="true">Content Editable 2</div></td>
      <td><input value="Input 3"></td>
      <td>Not Editable</td>
    </tr>
    <tr>
      <td><input  placeholder="r2, c0"></td>
      <td><div contenteditable="true">Content Editable 1</div></td>
      <td style="display: none;"><input value="Input 2"></td>
      <td><div contenteditable="true">Content Editable 2</div></td>
      <td><input value="Input 3"></td>
      <td>Not Editable</td>
    </tr>
    <tr>
      <td><input value="Input 1"></td>
      <td><div contenteditable="true">Content Editable 1</div></td>
      <td style="display: none;"><input value="Input 2"></td>
      <td><div contenteditable="true">Content Editable 2</div></td>
      <td><input value="Input 3"></td>
      <td>Not Editable</td>
    </tr>
  </tbody>
</table>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Cory R