Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to navigate textboxes in between different tables using arrow keys?

I have the following code, it is working that is navigating between the textboxes, but the issue is it is navigating only within one table, but am having different tables in my page. How to make it work?

$('input[type="text"],textarea').keyup(function(e){
    if(e.which==39 || e.which==13)
        $(this).closest('td').next().find('input[type="text"],textarea').focus();
    else if(e.which==37 || e.which==8)
        $(this).closest('td').prev().find('input[type="text"],textarea').focus();
    else if(e.which==40 || e.which==13)
        $(this).closest('tr').next().find('td:eq('+$(this).closest('td').index()+')').find('input[type="text"],textarea').focus();
    else if(e.which==38 || e.which==8)
        $(this).closest('tr').prev().find('td:eq('+$(this).closest('td').index()+')').find('input[type="text"],textarea').focus();
});




    <form>
   <table width="960" align="center" cellspacing="20" cellpadding="15" id="navigate"> 
            <thead>                 
                <th align="center"></th>
                <th align="center"></th>
                <th align="center"></th>
                <th align="center"></th>
            </thead>
            <tbody>
            <tr>
            <td colspan="4" style="font-size:15px;"><b>ADVERTISING:</b></th>
            </tr>
            <tr>
            <th></th>
                <th align="center">DOMESTIC($)</th>
                <th align="center">INTERNATIONAL($)</th>
                <th align="center">NOTES</th>
                </tr>
                <tr>
                    <td class="spending_table_title" title="<?php echo $this->data[14]->content; ?>"><span style="text-transform: uppercase;"><?php echo $this->data[13]->content; ?></span></td>
                    <td ><input type="text" value="" name="actual_marketing_dom_print" id="actual_marketing_dom_print"  size="30" style="height:20px; width:155px;" onChange="total_dom_advt();total_marketing_spending();format(this);"/> </td>
                    <td ><input type="text" value="" name="actual_marketing_intl_print" id="actual_marketing_intl_print"  size="30" style="height:20px; width:155px; " onChange="total_intl_advt();total_marketing_spending();format(this);"/></td>
                    <td ><textarea name="actual_marketing_print_notes"  id="actual_marketing_print_notes" style="height:32px; width:300px;" rows="3" cols="20"  class ="notes"> </textarea></td>
                </tr>


                </tbody>
                </table>
                </div>
                 <br>

         <br>         

         <div class="divgrid">

         <table width="960" align="center" cellspacing="20" cellpadding="15" id="navigate"> 
            <thead>
                <th style="width:60%;"></th>
                <th></th>
                <th></th>
            </thead>
            <tbody>
            <tr>
            <td colspan="3" style="font-size:15px;font-weight:bold;">TOTAL PRESS AND PUBLIC RELATIONS (DOMESTIC AND INTERNATIONAL COMBINED):</td>
            </tr>
            <tr>
            <th></th>
            <th align="center">$</th>
            <th align="center">NOTES</th>
            </tr>
                <tr>
                    <td  class="spending_table_title" title="<?php echo $this->data[31]->content; ?>"><span style="text-transform: uppercase;"><?php echo $this->data[30]->content; ?></span></td>

               <td ><input type="text" value="" name="actual_marketing_industry_relations" id="actual_marketing_industry_relations"  size="30" style="height:20px; width:155px; " onChange="total_press_public();total_marketing_spending();format(this);"/></td>
                    <td ><textarea name="actual_marketing_industry_relations_notes"  id="actual_marketing_industry_relations_notes" style="height:32px; width:300px;" rows="3" cols="20" class ="notes"> </textarea></td>
                </tr>


            </tbody>
         </table>
</form>

in my code am having two tables, after completing the textboxes in one table am not table to navigate to next table textboxes, i was not known how to do this

like image 743
user3165411 Avatar asked Jan 21 '14 12:01

user3165411


2 Answers

Interesting question, and hopefully you will find this helpful.

What I'm doing here is to check if there is an input above or below to go to with if (t.length == 0), and if not, move to the corresponding cell in the next or previous table instead.

$(document).ready(function () {
    $('input[type="text"],textarea').keyup(function (e) {
        if (e.which == 39) {
            $(this).closest('td').next().find('input[type="text"],textarea').focus();
        } else if (e.which == 37) {
            $(this).closest('td').prev().find('input[type="text"],textarea').focus();
        } else if (e.which == 40) {
            var t = $(this).closest('tr').next().find('td:eq(' + $(this).closest('td').index() + ')').find('input[type="text"],textarea');
            if (t.length == 0) {
                t = $(document).find('table:eq(' + ($('table').index($(this).closest('table')) + 1) + ')').find('tbody tr td').parent().first().find('td:eq(' + $(this).closest('td').index() + ')').find('input[type="text"]:not([readonly]),textarea');
            }
            t.focus();
        } else if (e.which == 38) {
            var t = $(this).closest('tr').prev().find('td:eq(' + $(this).closest('td').index() + ')').find('input[type="text"],textarea');
            if (t.length == 0) {
                t = $(document).find('table:eq(' + ($('table').index($(this).closest('table')) - 1) + ')').find('tbody tr td').parent().last().find('td:eq(' + $(this).closest('td').index() + ')').find('input[type="text"]:not([readonly]),textarea');
            }
            t.focus();
        }
    });
});

http://jsfiddle.net/zxTfb/5/

Please note that right now, this only works on multiple tables on top of each other, not side by side. If you need them side by side, you could copy what I did for keys 40 and 38 and modify it to work for 39 and 37 as well.

Hope it helps.

Further explanation

Let's break down this line of code and look at inner workings:

t = $(document).find('table:eq(' + ($('table').index($(this).closest('table')) - 1) + ')').find('tbody tr td').parent().last().find('td:eq(' + $(this).closest('td').index() + ')').find('input[type="text"]:not([readonly]),textarea');

First we find the table above the one we are currently in. This is done with the selector :eq() which selects an element, table in this case, by it's index. We select the table with our current tables index -1 to get the table above.

$(document).find('table:eq(' + ($('table').index($(this).closest('table')) - 1) + ')')

Now that we have the table above our current position, we find the last <tr> element that does contain a <td>, by first looking for all <td>, then move up to it's parent <tr> with .parent() and finally select the last one (bottom row) with .last().

.find('tbody tr td').parent().last()

Now we know which <tr> to look in, so we move ahead and look for the specific <td> by index, so that we end up in the right column, corresponding to the one we are currently in. This is similar to when we found the <table> by index at the top.

.find('td:eq(' + $(this).closest('td').index() + ')')

Finally, we now have our correct <td> element and now all that remains is to find our <input> or <textarea> that isn't readonly. We do this simply by selecting them like so

.find('input[type="text"]:not([readonly]),textarea');

And now we know where to move in the table above. Since we set t to this new element, all that remains is to move the focus there with t.focus().

And there you have it!

like image 180
Magnus Engdal Avatar answered Oct 04 '22 15:10

Magnus Engdal


How about this?

Use a global counter to assign IDs to your inputs. Then, since you know what ID triggered the event, you just add or subtract from that ID to get the new ID you should go to. Here's some code:

<html>
<head>
<script src="jquery.js"></script>
<script>
$(document).ready(function() {
  console.log("hej");
  $('input[type="text"],textarea').keyup(function(e){
    if(e.which==39 || e.which==13) {
        var thisId = parseInt(this.id);
        $("#" + (thisId + 1)).focus();
    } else if(e.which==37 || e.which==8) {
        var thisId = parseInt(this.id);
        $("#" + (thisId - 1)).focus();
    } else if(e.which==40 || e.which==13) {
        var thisId = parseInt(this.id);
        $("#" + (thisId + 4)).focus();
    } else if(e.which==38 || e.which==8) {
        var thisId = parseInt(this.id);
        $("#" + (thisId - 4)).focus();
    }
  });
});
</script>
</head>
<body>

 <form>
<table>

 <tr>
  <td><input type="text" id="1" name="5"></td>
  <td><input type="text" id="2" name="6"></td>
  <td><input type="text" id="3" name="7"></td>
  <td><input type="text" id="4" name="8"></td>


 </tr>

  <tr>
  <td><input type="text" id="5" name="5"></td>
  <td><input type="text" id="6" name="6"></td>
  <td><input type="text" id="7" name="7"></td>
  <td><input type="text" id="8" name="8"></td>


 </tr>
 <tr>
  <td><input type="text" id="9" name="5"></td>
  <td><input type="text" id="10" name="6"></td>
  <td><input type="text" id="11" name="7"></td>
  <td><input type="text" id="12" name="8"></td>


 </tr>

</table>

<table>
 <tr>
  <td><input type="text" id="13" name="5"></td>
  <td><input type="text" id="14" name="6"></td>
  <td><input type="text" id="15" name="7"></td>
  <td><input type="text" id="16" name="8"></td>


 </tr>

 <tr>
  <td><input type="text" id="17" name="5"></td>
  <td><input type="text" id="18" name="6"></td>
  <td><input type="text" id="19" name="7"></td>
  <td><input type="text" id="20" name="8"></td>


 </tr>

 <tr>
  <td><input type="text" id="21" name="5"></td>
  <td><input type="text" id="22" name="6"></td>
  <td><input type="text" id="23" name="7"></td>
  <td><input type="text" id="24" name="8"></td>


 </tr>

</table>

</form>
</body>
</html>
like image 27
Jake Avatar answered Oct 04 '22 13:10

Jake