I create rows dynamically using the event onfocus of d or w field. I got that correct,but the radio button- when i choose dm, d should be disabled and cm, w should be disabled. I am not sure how to do that. Please help me out
<table class="table table-bordered table-hover" id="tvtable">
<thead>
<tr>
<th width="10%" style="text-align: center;">Type</th>
<th width="20%" style="text-align: center;">A</th>
<th width="20%" style="text-align: center;">d</th>
<th width="20%" style="text-align: center;">w</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="radio" name="wd0" id="rd" value="dr" />Dm
<br/>
<input type="radio" name="wd0" id="rc" value="cr" />Cm</td>
<td>
<select id="m0" class="form-control"></select>
</td>
<td>
<input class="form-control c1 amt" type="number" id="w0" name="amt1" />
</td>
<td>
<input class="form-control c2 amt" type="number" id="d0" name="amt2" />
</td>
</tr>
</tbody>
</table>
$(document).ready(function ()
{
if ($('#rd').prop('checked'))
{
$(".c1").attr("disabled", "disabled");
}
else if($('#rc').prop('checked'))
{
$(".c2").attr("disabled", "disabled");
}
var counter = 0;
$(document).on("focus", ".amt", function (event)
{
counter++;
var list = '<tr><td><input type="radio" name="wd' + counter + '" id="rd" value="dr" />Dm<br/><input type="radio" name="wd' + counter + '" id="rc" value="cr" />Cm</td><td><select id="m' + counter +
'" class="form-control "></select></td><td><input class="form-control c1 amt" type="number" id="w' + counter + '" name="amount" /></td><td><input class="form-control c2 amt" type="number" id="d' + counter + '" name="amount" /></td></tr>';
$('#tvtable').append(list);
});
});
http://jsfiddle.net/A8G5v/
You did not include jQuery in JSfiddle plus syntax errors.
You are appending checkboxes dynamically, so the if()..else() won't work on document.ready.
Add a delegated change event.
$(document).on('change', ':radio', function () {
if ($(this).prop('checked') && $(this).val() == 'dr') {
$(this).parents('tr').find(".c1").attr("disabled", "disabled");
$(this).parents('tr').find(".c2").removeAttr("disabled");
} else{
$(this).parents('tr').find(".c2").attr("disabled", "disabled");
$(this).parents('tr').find(".c1").removeAttr("disabled");
}
});
Note : Your code is generating duplicate IDs which wont work for later append.
Updated Demo
Related
I have a function where my input type="number" data-id="weight" checks whether the user typed a divisible by 5 or not. It is perfectly working on my current row but when i add a new row/s, it is not working. Is there anything i missed? I provided my snippet below. Thank you everyone.
To try it. Please type on the weight column a number that is not divisible by 5, then you'll see the error. Add row and do the same, you will not see the error. My target is my function to work with added rows too.
$("#addrow").on('click', function() {
let rowIndex = $('.auto_num').length + 1;
let rowIndexx = $('.auto_num').length + 1;
var newRow = '<tr><td><input class="auto_num" type="text" name="entryCount" value="' + rowIndexx + '" /></td>"' +
'<td><input name="lightBand' + rowIndex + '" id="auto" value="" class="form" type="number" /></td>"' +
'<td><input data-id="weight" name="weight' + rowIndex + '" type="number" placeholder="not working divisible by 5" /></td>"' +
'<td><input id="wingBand" name="wingBand' + rowIndex + '" type="number" /></td>"' +
'<td><input type="button" class="removerow" id="removerow' + rowIndex + '" name="removerow' + rowIndex + '" value="Remove"/></td>';
$("#applicanttable > tbody > tr:last").after(newRow);
});
// divisible by only 5
const inputer = document.querySelectorAll('input[data-id="weight"]');
inputer.forEach(input => {
input.addEventListener('change', () => {
if (input.value % 5 !== 0) {
alert('not valid');
input.value = 5;
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" border="1" id="applicanttable">
<thead>
<tr>
</tr>
</thead>
<tbody>
<div class="row">
<tr>
<th>#</th>
<th>LB#</th>
<th>Weight#</th>
<th>Wingband #</th>
<th>Action</th>
</tr>
<tr id="row_0">
<td>
<input id="#" name="#" class="auto_num" type="text" value="1" readonly />
</td>
<td class="labelcell">
<input value="" class="hehe form-control" placeholder="" required id="auto" />
</td>
<td class="labelcell">
<input data-id="weight" name="weight1" type="number" placeholder="Working divisible by 5" />
<input data-id="weight" name="weight1" type="number" placeholder="Working divisible by 5" />
</td>
<td class="labelcell">
<input name="wingBand" class="hehe form-control" type="number" />
</td>
<td class="labelcell">
<input type="button" class="removerow" id="removerow0" name="removerow0" value="Remove">
</td>
</tr>
</div>
</tbody>
</div>
<tfoot>
<tr>
</tr>
<tr>
<button type="button" id="addrow" style="margin-bottom: 1%;">Add Row</button>
</tr>
</tfoot>
</table>
This is caused by the event handler for the change event not being fired for dynamically created objects.
When you create an the event handlers like this:
const inputer = document.querySelectorAll('input[data-id="weight"]');
inputer.forEach(input => {
input.addEventListener('change', () => {
...
}
});
The handler is only mapped for elements that exist when you first run the code. That means any subsequently created dynamic elements will not cause the event to fire.
Instead, use the following syntax to create the event which will catch dynamically created elements by using their selector (input[data-id="weight"]):
$(document).on('change', 'input[data-id="weight"]', function(e) {
if ($(this).val() % 5 !== 0) {
alert('not valid');
$(this).val(5);
}
});
I've removed the other code you had previously that tried to bind the event handler. You don't need to do it that way with jQuery.
Seen here in a working version of your snippet:
$("#addrow").on('click', function(){
let rowIndex = $('.auto_num').length+1;
let rowIndexx = $('.auto_num').length+1;
var newRow = '<tr><td><input class="auto_num" type="text" name="entryCount" value="'+rowIndexx+'" /></td>"' +
'<td><input name="lightBand'+rowIndex+'" id="auto" value="" class="form" type="number" /></td>"' +
'<td><input data-id="weight" name="weight'+rowIndex+'" type="number" placeholder="not working divisible by 5" /></td>"' +
'<td><input id="wingBand" name="wingBand'+rowIndex+'" type="number" /></td>"' +
'<td><input type="button" class="removerow" id="removerow'+rowIndex+'" name="removerow'+rowIndex+'" value="Remove"/></td>';
$("#applicanttable > tbody > tr:last").after(newRow);
});
// divisible by only 5
$(document).on('change', 'input[data-id="weight"]', function(e) {
if ($(this).val() % 5 !== 0) {
alert('not valid');
$(this).val(5);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" border="1" id="applicanttable">
<thead>
<tr>
</tr>
</thead>
<tbody>
<div class="row">
<tr>
<th>#</th>
<th>LB#</th>
<th>Weight#</th>
<th>Wingband #</th>
<th>Action</th>
</tr>
<tr id="row_0">
<td>
<input id="#" name="#" class="auto_num" type="text" value="1" readonly />
</td>
<td class="labelcell">
<input value="" class="hehe form-control" placeholder="" required id="auto"/>
</td>
<td class="labelcell">
<input data-id="weight" name="weight1" type="number" placeholder="Working divisible by 5" />
<input data-id="weight" name="weight1" type="number" placeholder="Working divisible by 5" />
</td>
<td class="labelcell">
<input name="wingBand" class="hehe form-control" type="number" />
</td>
<td class="labelcell">
<input type="button" class="removerow" id="removerow0" name="removerow0" value="Remove" >
</td>
</tr>
</div>
</tbody>
</div>
<tfoot>
<tr>
</tr>
<tr>
<button type="button" id="addrow" style="margin-bottom: 1%;">Add Row</button>
</tr>
</tfoot>
</table>
Add change event listener after adding the table row. Modified the above code as below:
$("#addrow").on('click', function(){
let rowIndex = $('.auto_num').length+1;
let rowIndexx = $('.auto_num').length+1;
var newRow = '<tr><td><input class="auto_num" type="text" name="entryCount" value="'+rowIndexx+'" /></td>"' +
'<td><input name="lightBand'+rowIndex+'" id="auto" value="" class="form" type="number" /></td>"' +
'<td><input data-id="weight" name="weight'+rowIndex+'" type="number" placeholder="not working divisible by 5" /></td>"' +
'<td><input id="wingBand" name="wingBand'+rowIndex+'" type="number" /></td>"' +
'<td><input type="button" class="removerow" id="removerow'+rowIndex+'" name="removerow'+rowIndex+'" value="Remove"/></td>';
$("#applicanttable > tbody > tr:last").after(newRow);
const list = document.querySelectorAll('input[data-id="weight"]');
const input = list[list.length - 1];
console.log(input)
input.addEventListener('change', inputValidation);
});
const inputValidation = (e) => {
if (e.target.value % 5 !== 0) {
alert('not valid');
e.target.value = 5;
}
}
// divisible by only 5
const inputer = document.querySelectorAll('input[data-id="weight"]');
inputer.forEach(input => {
input.addEventListener('change', inputValidation);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table class="table table-bordered" border="1" id="applicanttable">
<thead>
<tr>
</tr>
</thead>
<tbody>
<div class="row">
<tr>
<th>#</th>
<th>LB#</th>
<th>Weight#</th>
<th>Wingband #</th>
<th>Action</th>
</tr>
<tr id="row_0">
<td>
<input id="#" name="#" class="auto_num" type="text" value="1" readonly />
</td>
<td class="labelcell">
<input value="" class="hehe form-control" placeholder="" required id="auto"/>
</td>
<td class="labelcell">
<input data-id="weight" name="weight1" type="number" placeholder="Working divisible by 5" />
<input data-id="weight" name="weight1" type="number" placeholder="Working divisible by 5" />
</td>
<td class="labelcell">
<input name="wingBand" class="hehe form-control" type="number" />
</td>
<td class="labelcell">
<input type="button" class="removerow" id="removerow0" name="removerow0" value="Remove" >
</td>
</tr>
</div>
</tbody>
</div>
<tfoot>
<tr>
</tr>
<tr>
<button type="button" id="addrow" style="margin-bottom: 1%;">Add Row</button>
</tr>
</tfoot>
</table>
i want to get more input field by onfoucus event
function new_option() {
var tot_opt = parseInt($('#tot_opt').val());
$('#otp' + tot_opt).unbind('onfocus', "new_option");
tot_opt++;
$('#tot_opt').val(tot_opt);
var opt = "<br><input onfocus='new_option()' id='otp" + tot_opt + "' placeholder='Options" + tot_opt + "' type='text' name='options' class='form-control'>"
$('#new_opt').append(opt);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-bordered">
<tr>
<th colspan="2">Create Voter Pool</th>
</tr>
<tr>
<th>Question</th>
<th><textarea name="question" class="form-control">
</textarea></th>
</tr>
<tr>
<th>Options</th>
<td>
<input type="text" placeholder="Options1" id="opt1" class="form-control" name="options"><br>
<input type="text" onfocus="new_option()" id="opt2" placeholder="Options2" class="form-control" name="options">
<span id="new_opt"></span>
<input type="hidden" id="tot_opt" value="2">
</td>
</tr>
</table>
i want onfocus attribute only on last input and want to remove onfoucs attribute from remain
Before you add the new input you can remove the onfocus attribute form all the other inputs.
The below will query for inputs with the onfocus attribute and loop through each element removing the attribute. Then I append the last input with the onfocus attribute. This ensures only the last input will be able to add another input.
function new_option() {
var tot_opt = parseInt($('#tot_opt').val());
$('#otp' + tot_opt).unbind('onfocus', "new_option");
tot_opt++;
$('#tot_opt').val(tot_opt);
var opt = "<br><input onfocus='new_option()' id='otp" + tot_opt + "' placeholder='Options" + tot_opt + "' type='text' name='options' class='form-control'>"
// remove onfocus from all previous inputs (that have the onfocus attribute)
document.querySelectorAll("input[onfocus]").forEach(function(element, index) {
element.removeAttribute("onfocus");
});
$('#new_opt').append(opt);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-bordered">
<tr>
<th colspan="2">Create Voter Pool</th>
</tr>
<tr>
<th>Question</th>
<th><textarea name="question" class="form-control"></textarea></th>
</tr>
<tr>
<th>Options</th>
<td>
<input type="text" placeholder="Options1" id="opt1" class="form-control" name="options"> <br>
<input type="text" onfocus="new_option()" id="opt2" placeholder="Options2" class="form-control" name="options">
<span id="new_opt"></span>
<input type="hidden" id="tot_opt" value="2">
</td>
</tr>
</table>
I want to make simple real time calculator without page refresh with jquery.
I added dynamic table row with jquery and applied some method in the input fields but that is not working perfectly in newly added rows.
newly added rows are only working when I change something in the default rows.
Here is my html codes:
<button type="button" id="addBillingRow" class="btn btn-success btn-sm fa fa-plus fa-3x float-right">add</button>
<table class="table table-bordered" id="dynamic_field_shipping">
<thead>
<tr>
<th width="10%">Date</th>
<th width="20%">Purpose</th>
<th width="20%">Amount</th>
<th width="10%">Quantity</th>
<th width="30%">Total</th>
<th width="10%">#</th>
</tr>
</thead>
<tbody>
<tr class="ship_bill">
<td>
12/12/17
</td>
<td>
<input id="purpose" type="text" name="purpose" required>
</td>
<td>
<input id="amount" name="amount" type="text"
oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');" required>
</td>
<td>
<input id="quantity" name="quantity" required="required" type="number" min="0" value="0">
</td>
<td>
<strong><i><span class="multTotal">0.00</span></i></strong>
</td>
<td>
</td>
</tr>
</tbody>
</table>
<table class="table table-bordered">
<tbody>
<tr>
<td width="50%"><strong><i>Bill Amount:</i></strong></td>
<td><strong><i><span id="grandTotal">0.00</span></i></strong></td>
</tr>
</tbody>
</table>
Here is my jQuery codes:
var i=1;
$('#addBillingRow').click(function(){
i++;
$('#dynamic_field_shipping').append('<tr class="ship_bill" id="row'+i+'"><td></td><td><input id="purpose" type="text" name="purpose" required></td><td><input id="amount" name="amount" type="text" required></td><td><input id="quantity" name="quantity" required="required" type="number" min="0" value="0"></td><td><strong><i><span class="multTotal">0.00</span></i></strong></td><td>X</td></tr>');
});
$(document).on('click', '.btn_remove', function(e){
e.preventDefault();
var button_id = $(this).attr("id");
$('#row'+button_id+'').remove();
});
function multInputs() {
var mult = 0;
// for each row:
$("tr.ship_bill").each(function () {
// get the values from this row:
var $amount = $('#amount', this).val();
var $quantity = $('#quantity', this).val();
var $total = ($amount * 1) * ($quantity * 1)
$('.multTotal',this).text($total);
mult += $total;
});
$("#grandTotal").text(mult);
}
$(".ship_bill input").change(multInputs);
If you want you can check the live code here:
https://jsfiddle.net/wasid/3xkcLdss/1/
besides I also wanted to use this code in jquery append() for allowing only numbers in input fields. but could not use it either.
oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*)\./g, '$1');"
Try this
$("tbody").on('change', '.ship_bill input', multInputs);
I created a table where I can dynamically add multiple rows to it. There's a column to add cost. Now I want to
get total cost value of each row at the bottom of the table. How can I get this using JavaScript?
Here is my html code for dynamic table.
<table>
<thead>
<tr>
<th>No</th>
<th>Title</th>
<th cost</th>
</tr>
</thead>
<tbody id="body">
<tr>
<th>1</th>
<td>
<input type="text" id="title" name="title[]" />
</td>
<td>
<input type="text" id="cost" name="cost[]" />
</td>
</tr>
</tbody>
</table>
Javascript function:
$(function(){
$('.addrow').click(function(){
addrow();
});
function addrow()
{
var row =($('#body tr').length-0)+1;
var tr ='<tr>'+
'<th>'+row+'</th>'+
'<td><input type="text" id="title" name="title[]" ></td>'+
'<td><input type="text" id="cost" name="cost[]" /></td>'+
'</tr>';
$('#body').append(tr);
}
});
You should iterate the input tags that belong to the table and have an id starting with "cost".
Also, you can not add the row directly to the body, you want to add it after the last row already created.
Try out this (edit:) fiddle (old habits die hard) snippet .
$(document).ready(function(){
$('#addRow').click(function(){
addRow();
});
$('#totalRow').click(function(){
totalRow();
});
function addRow()
{
var rowId = $('#myTable tr').length;
$('#myTable > tbody:last-child').append(
'<tr><th>' + rowId + ' </th>' +
'<td><input type="text" id="title' + rowId + '" /></td>' +
'<td><input type="text" id="cost' + rowId + '"</td></tr>'
);
}
function totalRow()
{
var rowId = $('#myTable tr').length;
var val = 0;
$("#myTable [id^=cost]").each(function() {
val += parseFloat($(this).val());
});
$('#myTable > tbody:last-child').append(
'<tr><th>T</th>' +
'<td><input type="text" id="totalRow" value="TOTAL" /></td>' +
'<td><input type="text" id="totalCost" value="' + val +'" /></td></tr>'
);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="addRow">Add row</div>
<div id="totalRow">Calculate total row</div>
<br>
<table id="myTable">
<thead>
<tr>
<th>No</th>
<th>Title</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
<tr>
<th>1</th>
<td>
<input type="text" id="title1" value="Example" />
</td>
<td>
<input type="text" id="cost1" value="25" />
</td>
</tr>
</tbody>
</table>
Hope it helps!
If text inputs are the only inputs used, try using https://api.jquery.com/input-selector/ to get all the input selectors.
You can iterate through the input selectors, aggregate the values to give you the total.
NOTE: As mentioned in the comments, do not use same id for all the input tags. It is not a best practice
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
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!
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>