Handling the Enter and arrow keys using Javascript
Tags: javascript, programming, tutorial, html
Published: 2022-10-11 11:56:23

I had a task assigned to handle a "_enter_" key in my internship. 
Actually, I am not quite familiar with the frontend development. But here is my effort to solve the task and learn new thing.

So, the task was, to generate the table where the cells of the table are editable. And whenever the 'enter' button is pressed, the next cell has to be selected.

At first, it seemed easy, and I started to code. I knew this task was related to the event. But, as I was solving it, I needed to google lot. And, after many errors, and solving those errors, I have finally solve the task.

Here's how the solution looks.

First created a html file named '_index.html_'

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Index</title>
</head>
<body>
    <h1 style="text-align:center">Demo of handling Enter and arrow keys</h1>
    <br>
    <div>
        <table id="dataTable">
            <tbody id="tableBody">

            </tbody>
        </table>
    </div>
    
</body>
</html>
```

Here I have created a table inside the div tag. I have decided to create a table dynamically.

Now, create a table dynamically.

```
function createTable(rows, columns) {
    for (let i=0; i<rows; i++) {
        let row = document.createElement('tr');
        
        for (let j=0; j<columns; j++) {
            let cell = document.createElement('td');

            cell.setAttribute('contenteditable', 'true') //makes cell editable
            cell.setAttribute('onkeyup','handleEvent(event)')  // calls postAnswer() function on keyup

            cell.innerHTML = `${i}${j}`;
            row.appendChild(cell);
        }
        document.getElementById('tableBody').appendChild(row);
    }

}
```
here, the rows and columns are the parameter i.e. the table can be generated of any rows and columns.

Now let's make the table look good using bootstrap. I used bootstrap cdn here.

```
 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
    
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js" integrity="sha384-IDwe1+LCz02ROU9k972gdyvl+AESN10+x7tBKgc9I5HFtuNz0wWnPclzo6p9vxnk" crossorigin="anonymous"></script>

```
use the bootstrap cdn inside the <_head_> tag.


Add bootstrap class in the <_table_> tag.

```
<table class="table table-striped table-bordered" id="dataTable">
            <tbody id="tableBody">

            </tbody>
        </table>
```
Now the table seems little good.


Now let's handle the _Enter and arrow keys pressed_. Here the main task is when a enter is pressed the next cell to the right has to be selected. 

```
function handleEvent(event) {
    // handles events for "enter"/ "up"/ "down"/ "left"/ "right" arrow keys
    
    if (event.which == 13) {
        //prevents the default action of the event from happening
        event.preventDefault();

        if (event.target.nextSibling != null) {
            // go to next cell
            event.target.nextSibling.focus()
        }
        else {
            // go to next row's first cell
            event.target.parentElement.nextSibling.firstChild.focus()
        }
    }
}
```
This handles the enter key pressed and selects the right cell.
But I wanted to handle the arrow keys as well so it will give good user experience. 

```
if (event.which == 39) {
        // go to next cell
        event.target.nextSibling.focus()
    }

    if (event.which == 37) {
        // go to previous cell
        event.target.previousSibling.focus()
    }

    if (event.which == 38) {
        // go to previous row's same cell
        event.target.parentElement.previousSibling.childNodes[event.target.cellIndex].focus()
    }

    if (event.which == 40) {
        // go to next row's same cell
        event.target.parentElement.nextSibling.childNodes[event.target.cellIndex].focus()
    }
```
this worked for all the arrow keys and provides the good user experience.

So here's how the final code looks like.

index.html

```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Index</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
    <script src="table.js"></script>
    <script src="events.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.min.js" integrity="sha384-IDwe1+LCz02ROU9k972gdyvl+AESN10+x7tBKgc9I5HFtuNz0wWnPclzo6p9vxnk" crossorigin="anonymous"></script>

</head>
<body>
    <h1 style="text-align:center">Demo of handling Enter and arrow keys</h1>
    <br>
    <div>
        <table class="table table-striped table-bordered" id="dataTable">
            <tbody id="tableBody">

            </tbody>
        </table>
    </div>
    
    <script>
        createTable(10,10);
    </script>
    

</body>
</html>
```

table.js

```
function createTable(rows, columns) {
    for (let i=0; i<rows; i++) {
        let row = document.createElement('tr');
        
        for (let j=0; j<columns; j++) {
            let cell = document.createElement('td');

            cell.setAttribute('contenteditable', 'true') //makes cell editable
            cell.setAttribute('onkeyup','handleEvent(event)')  // calls postAnswer() function on keyup

            cell.innerHTML = `${i}${j}`;
            row.appendChild(cell);
        }
        document.getElementById('tableBody').appendChild(row);
    }

}
```

events.js

```
function handleEvent(event) {
    // handles events for "enter"/ "up"/ "down"/ "left"/ "right" arrow keys
    
    if (event.which == 13) {
        //prevents the default action of the event from happening
        event.preventDefault();

        if (event.target.nextSibling != null) {
            // go to next cell
            event.target.nextSibling.focus()
        }
        else {
            // go to next row's first cell
            event.target.parentElement.nextSibling.firstChild.focus()
        }
    }

    if (event.which == 39) {
        // go to next cell
        event.target.nextSibling.focus()
    }

    if (event.which == 37) {
        // go to previous cell
        event.target.previousSibling.focus()
    }

    if (event.which == 38) {
        // go to previous row's same cell
        event.target.parentElement.previousSibling.childNodes[event.target.cellIndex].focus()
    }

    if (event.which == 40) {
        // go to next row's same cell
        event.target.parentElement.nextSibling.childNodes[event.target.cellIndex].focus()
    }
}

```

And this is final result of the code.

{% embed https://youtu.be/nmMk2F3V0XY %}


It was fun solving this task and I learned little about the events too. Hope it is helpful for others too.

_**Note**_ : I have made some improvement changes after writing this post.

link to github: [https://github.com/aakash-shakya/javascript-handling-arrow-keys-and-enter-key](https://github.com/aakash-shakya/javascript-handling-arrow-keys-and-enter-key)

demo link: [https://aakas.com.np/javascript-handling-arrow-keys-and-enter-key/](https://aakas.com.np/javascript-handling-arrow-keys-and-enter-key/)