简体   繁体   中英

Navigate Two HTML Table with input text using arrow key

On my previous post , I asked how to navigate a table cell using an arrow key. And now I'm trying to create another table that will behave the same with the first one.

How to achieve this?

Here is what I have so far:

 var active = 0; //$('#navigate td').each(function(idx){$(this).html(idx);}); rePosition(); $(document).keydown(function(e) { var inp = String.fromCharCode(event.keyCode); if (!(/[a-zA-Z0-9-_ ]/.test(inp) || event.keyCode == 96)){ reCalculate(e); rePosition(); // if key is an arrow key, don't type the user input. // if it is any other key (a, b, c, etc) // edit the text if (e.keyCode > 36 && e.keyCode < 41) { return false; } } }); $('td').click(function() { active = $(this).closest('table tbody').find('td').index(this); rePosition(); }); function reCalculate(e) { var rows = $('#navigate tbody tr').length; var columns = $('#navigate tbody tr:eq(0) td').length; var temp; if (e.keyCode == 37) { //move left or wrap temp = active; while (temp > 0) { temp = temp - 1; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } if (e.keyCode == 38) { // move up temp = active; while (temp - columns >= 0) { temp = temp - columns; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } if (e.keyCode == 39) { // move right or wrap temp = active; while (temp < (columns * rows) - 1) { temp = temp + 1; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } if (e.keyCode == 40) { // move down temp = active; while (temp + columns <= (rows * columns) - 1) { temp = temp + columns; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } } function rePosition() { console.log(active); $('.active').removeClass('active'); $('#navigate tbody tr td').eq(active).addClass('active'); $('#navigate tbody tr td').find('input').removeClass('textClass'); $('#navigate tbody tr td').eq(active).find('input').addClass('textClass'); $('#navigate tbody tr td').eq(active).find('input').select(); var input = $('#navigate tbody tr td').eq(active).find('input').focus(); scrollInView(); } function scrollInView() { var target = $('#navigate tbody tr td:eq(' + active + ')'); if (target.length) { var top = target.offset().top; $('html,body').stop().animate({ scrollTop: top - 100 }, 400); return false; } } 
 td.active{ border:2px solid #2c3e50; font-weight:bold; background-color:#ddd; } .textClass{ font-weight:bold; } input:focus { outline: none; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> <table border="1" id="navigate"> <thead> <th> CELL 1</th> <th> CELL 2</th> <th> CELL 3</th> <th> CELL 4</th> <th> CELL 5</th> </thead> <tbody> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> </tbody> </table> <br><br> <table border="1" id="table2"> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tbody> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> </tbody> </table> 

Please refer to this link for the sample demo.

DEMO HERE

After a bit sweating research, it gets to the proper solution. As we can't click inside the TDs of any other tables: we need to change the way of finding the index of td .

Currently it's as:

$(this).closest('table tbody').find('td').index(this);

This always returns the first table td indexes.

Below code helps finding exact index of TD where current focus is:

$('table td').index(this);

Though it looks a simple line.. little huge Research made it that small...

Working DEMO

Send Table id in $('td').click

$('td').click(function() {
    active = $(this).closest('table tbody').find('td').index(this);
    var tableid=$(this).closest('table').attr('id');
    console.log(tableid);
    rePosition(tableid);
});

And Change Function rePosition()

function rePosition(tableid) {
    console.log(active);
    $('.active').removeClass('active');
    $('#'+tableid+' tbody tr td').eq(active).addClass('active');
    $('#'+tableid+' tbody tr td').find('input').removeClass('textClass');
    $('#'+tableid+' tbody tr td').eq(active).find('input').addClass('textClass');
    $('#'+tableid+' tbody tr td').eq(active).find('input').select();
    var input = $('#'+tableid+' tbody tr td').eq(active).find('input').focus();
    scrollInView(tableid);
}

Live Demo Here

Snippet Example

 var active = 0; //$('#navigate td').each(function(idx){$(this).html(idx);}); rePosition(); $(document).keydown(function(e) { var inp = String.fromCharCode(event.keyCode); if (!(/[a-zA-Z0-9-_ ]/.test(inp) || event.keyCode == 96)){ reCalculate(e); rePosition(); // if key is an arrow key, don't type the user input. // if it is any other key (a, b, c, etc) // edit the text if (e.keyCode > 36 && e.keyCode < 41) { return false; } } }); $('td').click(function() { active = $(this).closest('table tbody').find('td').index(this); var tableid=$(this).closest('table').attr('id'); console.log(tableid); rePosition(tableid); }); function reCalculate(e) { var rows = $('#navigate tbody tr').length; var columns = $('#navigate tbody tr:eq(0) td').length; var temp; if (e.keyCode == 37) { //move left or wrap temp = active; while (temp > 0) { temp = temp - 1; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } if (e.keyCode == 38) { // move up temp = active; while (temp - columns >= 0) { temp = temp - columns; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } if (e.keyCode == 39) { // move right or wrap temp = active; while (temp < (columns * rows) - 1) { temp = temp + 1; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } if (e.keyCode == 40) { // move down temp = active; while (temp + columns <= (rows * columns) - 1) { temp = temp + columns; // only advance if there is an input field in the td if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) { active = temp; break; } } } } function rePosition(tableid) { console.log(active); $('.active').removeClass('active'); $('#'+tableid+' tbody tr td').eq(active).addClass('active'); $('#'+tableid+' tbody tr td').find('input').removeClass('textClass'); $('#'+tableid+' tbody tr td').eq(active).find('input').addClass('textClass'); $('#'+tableid+' tbody tr td').eq(active).find('input').select(); var input = $('#'+tableid+' tbody tr td').eq(active).find('input').focus(); scrollInView(tableid); } function scrollInView(tableid) { var target = $('#'+tableid+' tbody tr td:eq(' + active + ')'); if (target.length) { var top = target.offset().top; $('html,body').stop().animate({ scrollTop: top - 100 }, 400); return false; } } 
 td.active{ border:2px solid #2c3e50; font-weight:bold; background-color:#ddd; } .textClass{ font-weight:bold; } input:focus { outline: none; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <table border="1" id="navigate"> <thead> <th> CELL 1</th> <th> CELL 2</th> <th> CELL 3</th> <th> CELL 4</th> <th> CELL 5</th> </thead> <tbody> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> </tbody> </table> <br><br> <table border="1" id="table2"> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tbody> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> <tr> <td><input type="text" value="CELL 1" /></td> <td><input type="text" value="CELL 2" /></td> <td><input type="text" value="CELL 3" /></td> <td><input type="text" value="CELL 4" /></td> <td><input type="text" value="CELL 5" /></td> </tr> </tbody> </table> 

Try THIS DEMO

If two tables or more than that... use Class to identify all of them

I have written class="tblnavigate" to call in table cells in Javascript.

So, reposition function looks like:

function rePosition() {
    console.log(active);
    $('.active').removeClass('active');
    $('.tblnavigate tbody tr td').eq(active).addClass('active');
    $('.tblnavigate tbody tr td').find('input').removeClass('textClass');
    $('.tblnavigate tbody tr td').eq(active).find('input').addClass('textClass');
    $('.tblnavigate tbody tr td').eq(active).find('input').select();
    var input = $('.tblnavigate tbody tr td').eq(active).find('input').focus();
    scrollInView();
}

UPDATE:

The backspace must behave as it's functionality so, exclude it in keydown function as,

if ((!(/[a-zA-Z0-9-_ ]/.test(inp) || e.keyCode == 96)) && e.keyCode != 8){ ... }

UPDATED DEMO

Replace your function with below code and check:

function reCalculate(e) {
    var rows = $('#navigate tbody tr').length;
    var columns = $('#navigate tbody tr:eq(0) td').length;
    var temp;

    if (e.keyCode == 37) { //move left or wrap
        temp = active;
        while (temp > 0) {
            temp = temp - 1;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 38) { // move up
        temp = active;
        while (temp - columns >= 0) {
            temp = temp - columns;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 39) { // move right or wrap
        temp = active;
        while (temp < (columns * rows) - 1) {
            temp = temp + 1;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
    if (e.keyCode == 40) { // move down
        temp = active;
        while (temp + columns <= (rows * columns) - 1) {
            temp = temp + columns;
            // only advance if there is an input field in the td
            if ($('#navigate tbody tr td').eq(temp).find('input').length != 0) {
                active = temp;
                break;
            }
        }
    }
}

function rePosition() {
    console.log(active);
    $('.active').removeClass('active');
    $('#navigate tbody tr td').eq(active).addClass('active');
    $('#navigate tbody tr td').find('input').removeClass('textClass');
    $('#navigate tbody tr td').eq(active).find('input').addClass('textClass');
    $('#navigate tbody tr td').eq(active).find('input').select();
    var input = $('#navigate tbody tr td').eq(active).find('input').focus();
    scrollInView();
}

function scrollInView() {
    var target = $('#navigate tbody tr td:eq(' + active + ')');
    if (target.length) {
        var top = target.offset().top;

        $('html,body').stop().animate({
            scrollTop: top - 100
        }, 400);
        return false;
    }
}

Check Updated Demo: Click Here

我在最近的项目中使用了它,并且效果很好: https//gist.github.com/krcourville/7309218

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM