How to set Focus on Input using Tab Key Press in Next Table Cell

7.2k Views Asked by At

Following are scenarios I m implementing using JQuery in HTML

  • When a user double click on table cell it should a new input inside the Double Clicked Cell [Done]
  • When a user KeyPress [Tab] and it should move to next Cell [Done]

In Case of 2 Scenario, I need to trigger the dblclick() event on the next Cell which creates the Input Element Inside it, but it is not able to the Focus inside Input Element.

I have tried to debug that scenario not able to understand why it is happening.

I have created a button and written click function which trigger dblclick() , then focus was set inside the Input Element.

I m not able to understand when user click using the mouse / click() then why focus is set on the created input element but why same is not happening when I m triggering double click when from the code using dblclick()

Following are code For the Same:


//Global Variables
var TabEdit_sourceInput = null;
var TabEdit_currentTd = null;
var TabEdit_DOMtocheck = null;
var TabEdit_previousHour = null;
var gridRefreshFlag = false;

//Init Double Click Event on the Table TD
$('.custom-table-td').dblclick(function(event){
    var tableId = $(this).attr('id');
    var inputId = 'input-'+tableId;
    $(this).html('<input id="input-'+tableId+'" placeholder="Type Message" class="form-control" onkeydown="return initCheckKeypress();" tabindex="1"/>');
    
    //Focusing on Generated Event
    $('#'+inputId).focus();

    //Binding the Focus Out Event to
    $('#'+inputId).focusout(function(){
        debugger;
        $('.header').html($(this).val());
     });
     
});

//Click Event to trigger dblclick on td with id = 'tableData1'
$('.btn-trigger-dbclick').click(function(){
    $('#tableData1').dblclick();
});

//Function to check Tab is Press or not
function initCheckKeypress(evt) {
    "use strict";
    var e = event || evt; // for trans-browser compatibility
    var charCode = e.which || e.keyCode;
    if (charCode === 9) {
        gridRefreshFlag = true;
        TabEdit_sourceInput = $(e.target);
        TabEdit_currentTd = TabEdit_sourceInput.parent();
        TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
        movetoNextTD();
    }
}


//Code to Click on Next Cell
function movetoNextTD() {
    if (gridRefreshFlag && TabEdit_DOMtocheck !== null) {
        TabEdit_currentTd.html("");
        TabEdit_DOMtocheck.dblclick();
        resetmovetoNextVariable();
    }
}

//Reset Global Variable
function resetmovetoNextVariable(){
    TabEdit_sourceInput = null;
    TabEdit_currentTd = null;
    TabEdit_DOMtocheck = null;
    TabEdit_previousHour = null;
    gridRefreshFlag = false;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Focus Issue</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" >
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-lg-6">
                <div class="header"></div>
                <table class="table table-bordered">
                    <tbody>
                        <tr id="tableRow1">
                            <th id="tableHeader1" class="custom-table-th">TH 1</th>
                            <th id="tableHeader2" class="custom-table-th">TH 2</th>
                            <th id="tableHeader3" class="custom-table-th">TH 3</th>
                        </tr>
                        <tr id="tableRow2">
                            <td id="tableData1" class="custom-table-td"></td>
                            <td id="tableData2" class="custom-table-td"></td>
                            <td id="tableData3" class="custom-table-td"></td>
                        </tr>
                    </tbody>
                </table>
                <button class="btn btn-primary btn-trigger-dbclick">Trigger</button>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</body>
</html>

2

There are 2 best solutions below

6
fdomn-m On BEST ANSWER

What's happening is this:

  • double click - generates first input and sets focus, fine
  • user presses tab - the code that checks for tab kicks in before the system event handler and creates the 2nd input and sets focus - the system then continues with the default tab action and tabs off the 2nd input

The fix is to cancel the system default event after creating the 2nd input:

e.preventDefault();

Updated snippet:

//Global Variables
var TabEdit_sourceInput = null;
var TabEdit_currentTd = null;
var TabEdit_DOMtocheck = null;
var TabEdit_previousHour = null;
var gridRefreshFlag = false;

//Init Double Click Event on the Table TD
$('.custom-table-td').dblclick(function(event){
    var tableId = $(this).attr('id');
    var inputId = 'input-'+tableId;
    $(this).html('<input id="input-'+tableId+'" placeholder="Type Message" class="form-control" onkeydown="return initCheckKeypress();" tabindex="1"/>');
    
    //Focusing on Generated Event
    $('#'+inputId).focus();

    //Binding the Focus Out Event to
    $('#'+inputId).focusout(function(){
        debugger;
        $('.header').html($(this).val());
     });
     
});

//Click Event to trigger dblclick on td with id = 'tableData1'
$('.btn-trigger-dbclick').click(function(){
    $('#tableData1').dblclick();
});

//Function to check Tab is Press or not
function initCheckKeypress(evt) {
    "use strict";
    var e = event || evt; // for trans-browser compatibility
    var charCode = e.which || e.keyCode;
    if (charCode === 9) {
        gridRefreshFlag = true;
        TabEdit_sourceInput = $(e.target);
        TabEdit_currentTd = TabEdit_sourceInput.parent();
        TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
        movetoNextTD();
        e.preventDefault();
    }
}


//Code to Click on Next Cell
function movetoNextTD() {
    if (gridRefreshFlag && TabEdit_DOMtocheck !== null) {
        TabEdit_DOMtocheck.dblclick();
        TabEdit_currentTd.html("");
        resetmovetoNextVariable();
    }
}

//Reset Global Variable
function resetmovetoNextVariable(){
    TabEdit_sourceInput = null;
    TabEdit_currentTd = null;
    TabEdit_DOMtocheck = null;
    TabEdit_previousHour = null;
    gridRefreshFlag = false;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Focus Issue</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" >
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-lg-6">
                <div class="header"></div>
                <table class="table table-bordered">
                    <tbody>
                        <tr id="tableRow1">
                            <th id="tableHeader1" class="custom-table-th">TH 1</th>
                            <th id="tableHeader2" class="custom-table-th">TH 2</th>
                            <th id="tableHeader3" class="custom-table-th">TH 3</th>
                        </tr>
                        <tr id="tableRow2">
                            <td id="tableData1" class="custom-table-td"></td>
                            <td id="tableData2" class="custom-table-td"></td>
                            <td id="tableData3" class="custom-table-td"></td>
                        </tr>
                    </tbody>
                </table>
                <button class="btn btn-primary btn-trigger-dbclick">Trigger</button>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</body>
</html>

1
dilesh tanna On

Changing you initCheckKeyPress functions implementation would help. I fixed this by preventing the default behaviour of the triggered event by adding :

e.preventDefault();

This works because the default behaviour of the "tab" key press event is to focus on the next key item. This happens before the input is created (as rightly highlighted by freedomn-m). So preventing that would make this work.

Your final code would look like this:

Before

function initCheckKeypress(evt) {
"use strict";
var e = event || evt; // for trans-browser compatibility
var charCode = e.which || e.keyCode;
if (charCode === 9) {
    gridRefreshFlag = true;
    TabEdit_sourceInput = $(e.target);
    TabEdit_currentTd = TabEdit_sourceInput.parent();
    TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
    movetoNextTD();
}}

After:

function initCheckKeypress(evt) {
"use strict";
var e = event || evt; 
e.preventDefault();// for trans-browser compatibility
var charCode = e.which || e.keyCode;
if (charCode === 9) {
    gridRefreshFlag = true;
    TabEdit_sourceInput = $(e.target);
    TabEdit_currentTd = TabEdit_sourceInput.parent();
    TabEdit_DOMtocheck = TabEdit_currentTd.next('td');
    movetoNextTD();

}}