jquery keyup, keydown doesn't work in table with multiple row - javascript

I have a table which has 200 rows. Jquery keyup or keydown are not working. My jquery code is :
$('.upd_tab tbody tr td:eq(2) input').on('keyup',function(e){
if (e.which==13)
$(this).parent().parent().find('td').eq($(this).parent().index()+1).find('input').focus();
});
Actually I want to focus or go to the input box which is located in next td. This works with 1st tr but not in rest 199 trs
Here is the HTML.
<tbody>
<tr id="chz1">
<td><input maxlength="16"/><div class="bx"></div></td>
<td><input/><div class="bx"></div></td>
<td><input maxlength="6"/><div class="bx"></div></td>
<td><input /></td>
<td><input /></td>
<td><input value="1"/><div class="bx"><button class="sbut"></button></div><input type="hidden" class="hinp"/></td>
<td><input /></td>
<td><div class="bx"></div></td>
<td><div class="bx"></div></td>
</tr>
<tr id="chz2">
<td><input maxlength="16"/><div class="bx"></div></td>
<td><input/><div class="bx"></div></td>
<td><input maxlength="6"/><div class="bx"></div></td>
<td><input /></td>
<td><input /></td>
<td><input value="1"/><div class="bx"><button class="sbut"></button></div><input type="hidden" class="hinp"/></td>
<td><input /></td>
<td><div class="bx"></div></td>
<td><div class="bx"></div></td>
</tr>
<!-- etc -->
</tbody>

Try this one:
$('.upd_tab input').on('keyup',function(e){
e = e || window.event;
var code = e.keyCode;
if (code == '13') {
$(this).closest('td').next().find('input').focus();
}
});

The problem you are having is that :eq(n) selects the nth element from the previous selection. That is, the collection of all td's that are a child of a tr of a tbody of an element with the upd_tab class. It behaves basically like this: $($('.upd_tab tbody tr td')[2]) (and the input below that element). If you would use :eq(10) it would select the input box on the second row.
What you want is :nth-child(3).
$('.upd_tab tbody tr td:nth-child(3) input').on('keyup',function(e){
if (e.which==13)
$(this).parent().parent().find('td').eq($(this).parent().index()+1).find('input').focus();
});
For an easier understanding what elements are being selected, consider colouring them, for example with .css( { 'background': 'blue' } );. This will give you a visual clue what is happening.

Related

Value not displaying in correct input

I have a 2 row table with input fields that does a calculation when I focusout on the first input. The problem I am experiencing is when I focusout on the second row, my new value is displayed in the first row corresponding input. I'm not sure why this is happening. I would greatly appreciate your help.
My expectation is when I enter a value in a row input (Cost) and focusout the new value should be set in the same row but in the input (New Cost).
function Calculate(element) {
var dollar = 216.98;
var id = element.id;
var oldcost = $(element).val();
var newcost = oldcost * dollar;
$("#" + id).closest("tr").find("td #new").val(newcost);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>Cost</th>
<th>New Cost</th>
</tr>
<tr>
<td><input type="number" id="old" onfocusout="Caluculate(this)" /></td>
<td><input type="number" new="new" /></td>
</tr>
<tr>
<td><input type="number" id="old" onfocusout="Caluculate(this)" /></td>
<td><input type="number" new="new" /></td>
</tr>
</table>
There's several issues here. Firstly you're repeating the same id attribute which is invalid; they must be unique. I'd suggest using a class instead. Secondly, there's is no new attribute. I presume that's a typo and should be an id, but again see my first point.
Next, the function you defined is named Calculate() yet the call is to Caluculate().
Then you should also be using unobtrusive event handlers as on* event attributes are very outdated and should be avoided where possible. As you've already included jQuery in the page you can use the on() method. The input event would seem to be more applicable to your usage as well, especially given it also catches the up/down arrow usage on the number control, although you can change this to blur if preferred.
Finally, it's a simply a matter of amending your DOM traversal logic to work with the new classes, like this:
var dollar = 216.98;
$('.old').on('input', function() {
var oldcost = $(this).val();
var newcost = oldcost * dollar;
$(this).closest("tr").find(".new").val(newcost);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>Cost</th>
<th>New Cost</th>
</tr>
<tr>
<td><input type="number" class="old" /></td>
<td><input type="number" class="new" /></td>
</tr>
<tr>
<td><input type="number" class="old" /></td>
<td><input type="number" class="new" /></td>
</tr>
</table>
Your use of id's is kind of messed up. First of all be sure to use an id once in the entire HTML file.
For your usecase better use classes.
Also be sure to type your function names correct ;)
function Calculate(element) {
var dollar = 216.98;
var parent = $(element).closest('tr');
var oldcost = $(element).val();
var newcost = oldcost * dollar;
parent.find(".new").val(newcost.toFixed(2));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>Cost</th>
<th>New Cost</th>
</tr>
<tr>
<td><input type="number" class="old" onfocusout="Calculate(this)" /></td>
<td><input type="number" class="new" /></td>
</tr>
<tr>
<td><input type="number" class="old" onfocusout="Calculate(this)" /></td>
<td><input type="number" class="new" /></td>
</tr>
</table>
They have the same ID. You need to make the ID different
Firstly, there is a a typo.Change caluculate to calculate
There must not be the same id two elemnts have the same id.You could change the id of the first to old-1 or something different

How to set field value based on table cell changed value

I have two input fields with label empID and Name and table with 3 columns tblempID, tblName and tblTxt.
How to set empID value to be the same tblmpID value when any tblTxt cell value changed in each row in table.
T tried the following:
$(document).ready(function(){
tblTxtchange();
$('.tbl1').on('change', tblTextchange);
function tblTxtchange() {
$('.tbl1 tbody tr').each(function () {
$(this).find('.tblTxt').each(function () {
$('.tblTxt').change(function(){
$('.empID').val($('.tblText')
.closest('tr').find($('.tblEmpID').val()));
});
});
});
}
});
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<input id="empID"/>
<input id="Name"/>
<table style="width:100%" class="tbl1">
<tr>
<th>tblempID</th>
<th>tblName</th>
<th>tblTxt</th>
</tr>
<tr>
<td><input class="tblEmpID" /></td>
<td><input class="tblName" /></td>
<td><input class="tblTxt" /></td>
</tr>
<tr>
<td><input class="tblEmpID" /></td>
<td><input class="tblName" /></td>
<td><input class="tblTxt" /></td>
</tr>
<tr>
<td><input class="tblEmpID" /></td>
<td><input class="tblName" /></td>
<td><input class="tblTxt" /></td>
</tr>
</table>
I suspect you're overthinking it. (You're also using .find() incorrectly.) At its simplest, you want a handler for .tblTxt elements which finds the corresponding tblEmpID value and sets it to the #empID element. There's no need for loops, function calls, etc. Something like this:
$('.tblTxt').on('change', function () {
let empID = $(this).closest('tr').find('.tblEmpID').val();
$('#empID').val(empID);
});
I have a running code for your problem please update if you are looking for something else
$('.tblTxt').change(function () {
var row_emp_id = $(this).closest('tr').find('.tblEmpID').val();
$('#empID').val(row_emp_id);
});

Dynamically inserted table: last row not detected by JQuery

I'm using JQuery for creating dynamic table row based on user insertion.
My HTML:
<table id="list">
<thead>
<tr>
<th>first header</th>
<th>second header</th>
<th>third header</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="text" name="first" /></td>
<td><input type="text" name="second" id="second" /></td>
<td><button class="alert hollow button" href="#">X</button> </td>
</tr>
</tbody>
</table>
And JavaScript:
$('#list tr:last td:nth-last-child(2) input[name=second]').keyup(function (event) {
if ($(this).val().length > 4 && $('#list tr:last td:nth-last-child(2) input[name=second]').val().length > 4) {
$('#list tbody').append('<tr>
<td><input type="text" name="first" /></td>
<td><input type="text" name="second" id="second" /></td>
<td><button class="alert hollow button" href="#">X</button></td>
</tr>');
}
});
The above code only works for the first row and the inserted row has no JS code-behind.
You haven't given complete code, but i suspect this is your issue..
Replace this
$('#list tr:last td:nth-last-child(2) input[name=second]').keyup(function (event)
with this
$('#list').on('keyup', 'tr:last td:nth-last-child(2) input[name=second]', function (event)
You are probably not using proper event delegation, and you're trying to bind a keyup event on an element that doesn't exist yet (you say the rows are added dynamically). Instead we bind the keyup to the table that is part of the initial document, and say what happends when a child that meets X criteria has a keyup event fired
Your function does not bind to elements that don't exist on page load, use on for dynamically generated elements
$(document).on('keyup', '#list tr:last td:nth-last-child(2) input[name=second]', function (event) {

Delete button is not working

Html Table:
<table width="100%" border="0" cellspacing="0" cellpadding="0" id="table-data">
<tr>
<td>Name</td>
<td>Location</td>
<td>From</td>
<td>To</td>
<td>Add</td>
</tr>
<tr class="tr_clone">
<td><input type="text" placeholder="who" name="who" /></td>
<td><input type="text" placeholder="location" name="location" /></td>
<td><input type="text" placeholder="Start Date" name="datepicker_start" class="datepicker"/></td>
<td><input type="text" placeholder="End Date" name="datepicker_end" class="datepicker"/></td>
<td><input type="button" name="add" value="Add" class="tr_clone_add"/></td>
<td><input type="button" value="Delete" onclick="deleteRow(this)"/></td>
</tr>
</table><!-- /table#table-data -->
Javascript:
$("input.tr_clone_add").live('click', function() {
var $tr = $(this).closest('.tr_clone');
var $clone = $tr.clone();
$clone.find(':text').val('');
$tr.after($clone);
});
function deleteRow(r)
{
var i = r.parentNode.parentNode.rowIndex;
document.getElementById("table-data").deleteRow(i);
}
Here is my fiddle:
http://jsfiddle.net/tejdeep/b6A9R/
This code is cloning first two cells of a table row. I have add and delete button for every row.
I want this as like this:
http://jsfiddle.net/nKkhW/5/
Add button wants to be there for the cloning row and delete button should be there for the cloned row.
I want to include the functionality while cloning first two cell values has to come to the cloned row?
Let me know if you have doubts in this question.
What I have understood by your question, on that basis I have created Fiddle. Hope it will help you,except the default value case.
Updated fiddle
To delete row, you can try:
var $actualrow = $(this).closest('.tr_clone');
$actualrow.remove();
<input type="button" value="Delete" onclick="deleteRow(this)"/>
The problem is, where is your deleteRow() ? it's not in your fiddle..
fixed : http://jsfiddle.net/b6A9R/5/
and you have to change onLoad to No wrap, otherwise your function will not work.
Here is the updated code for onLoad.
JS
$(document).on('click','input[value="Delete"]',function(){
deleteRow(this);
});
DEMO

How do I Select all text boxes in a table excluding the last one in the table row with JQuery

I want add a key up event to every text box element in a table excluding the last text box in each row. The table is dynamic on both axis.
The key up event will total the values in all but the last text box. The total is then placed in the last text box for the row.
The script for the totaling and setting the total all works fine.
I tired the following to select the target elements:
$("#Grid tr input:text:not(:last)").keyup(function(){
//do total stuff here
})
Unfortunately it works as documented and not as I wanted and selects all but the very last checkbox.
Ideally the solution will not involve any further markup to the table example below or involve any looping. However if that is what it takes, so be it.
<table id="Grid">
<tr id="r1">
<td>Row 1</td>
<td><input type="text" id="txt_a1_b1"></td>
<td><input type="text" id="txt_a1_b2"></td>
<td><input type="text" id="txt_a1_b3"></td>
<td><input type="text" id="txt_a1_b4"></td>
<td><input type="text" id="total_a1"></td>
</tr>
<tr id="r2">
<td>Row 2</td>
<td><input type="text" id="txt_a2_b1"></td>
<td><input type="text" id="txt_a2_b2"></td>
<td><input type="text" id="txt_a2_b3"></td>
<td><input type="text" id="txt_a2_b4"></td>
<td><input type="text" id="total_a2"></td>
</tr>
<tr id="r3">
<td>Row 3</td>
<td><input type="text" id="txt_a3_b1"></td>
<td><input type="text" id="txt_a3_b2"></td>
<td><input type="text" id="txt_a3_b3"></td>
<td><input type="text" id="txt_a3_b4"></td>
<td><input type="text" id="total_a3"></td>
</tr>
</table>
One final point, the total text box does need to be a text box as there is also a requirement to enter a total then split it across the row and I do not want a key up function in the total text box.
I'm surprised noones quite got this yet:
$("#Grid tr :not(:last-child) :text").keyup(function(){
//do total stuff here
})
I would use the each function on the rows and find all but the last input in each row.
$('#Grid > tr').each( function() {
$(this).find('input:not(:last)).keyup( ... )
});
This one finds all inputs (exept last one) in all TRs
$("#Grid tr").find("input:text:not(:last)")
If you want to do it all in one shot, use :last-child:
... $('table tr input:not(:last-child)') ...
From the documentation: "While :last matches only a single element, this matches more than one, one for each parent."

Categories

Resources