How to find next elements using jquery? - javascript

In my given example, i have two text boxes. when value in first text box changed i want to find the immediate next text box (note : without id) and change its value.
The example given contains only single text box group. actually it can be more than one text boxes. (group of from & to text boxes of Financial Data)
so, when value in from text box (txtFinancialYearFrom) changed, i want to find the to text box (txtFinancialYearTo) and change its value as well.
JsFiddle Link - Example
Thanks in advance for the help!!
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Data :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>

Using the given information, since you are going to have more blocks (that should be rows on your table), this solution should work:
var rows = $('.fotm-table tr');
$(rows).each(function(){
$('input:first', $(this)).on('change', function(){
var fromValue = $(this).val();
var row = $(this).closest('tr');
$('td:last input', row).val(parseInt(fromValue) + 1);
});
});
The code gets all the rows from your table and for each one of them, it will add a listener that when you change the first textbox (input), it will change the value of the next textbox (here it's adding 1 to it).

If I've understood correctly, you need something like this:
/* Loop through all table rows */
$('tr','table.fotm-table').each(function() {
var tr = this;
/* Cache all inputs a jquery object - you may want to specify which type of input you are targeting i.e. $('input[type="text"]') */
var inputs = $('input',tr);
/* Cache the slave (second in the example) input in a jquery object - you can do the same for multiple inputs, simply by modifying the eq() index parameter
*/
var slaveInput = inputs.eq(1);
/* Listen for changes on the master input */
var masterInput = inputs.eq(0).on('change',function() {
/* Do smt on the slave input - fill it with the next year in the example */
var year = $(this).val();
var followingYear = parseInt(year,10)+1
slaveInput.val(followingYear);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Year :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>
Here's an updated fork of the jsFiddle you provided:
https://jsfiddle.net/jkdaza/thonfzwu/5/

You can use this tricky solution from link:
$('#txtFinancialYearFrom').change(function(el) {
$(':input:eq(' + ($(':input').index(this) + 1) + ')').val('test');
});
https://jsfiddle.net/g34yqL0u/2/

Related

onChange event for calculation in dynamic grid updates wrong rows - Classic asp

I have an old ASP site that needs a change. I need a basic grid to set pricing.
I want to enter a price in one column and have it display text of "Debit" or "Credit" in another column based on positive or negative input. I also want to calculate the extended price based on qty. I've just started with the first (text display) one for now, and can't get it to work.
The grid could have n number of rows based on the data set returned so I have a counter which I concatenate to the input IDs to indicate the row number. The counter is working fine and I can see the id's increment correctly. I've tried to pass the correct input value and id but when the function fires it updates the wrong rows. Actually it updates all the rows below the row I've changed. I have spent WAY too much time banging my head on what I thought would be a 15 min issue. Need a few more pairs of eyes.
<script>
function myFunction(val) {
data_length = document.getElementById("datalength").value;
i = 0;
while(i++ < data_length)
if (val > 0) {
document.getElementById("chargepay" +i).innerHTML = "Credit";
}
else
{
document.getElementById("chargepay" +i).innerHTML = "Debit";
}
}
</script>
Here is the row in the grid loop that has the input field to pass the amount value:
<td align="center"><input id="AMNT<%=count%>" size="10" name="AMNT"
onchange="myFunction(this.value)"/></td>
Here is the row in the grid to display the update from the onchange
<td align="center"><p id="chargepay<%=count%>"</p>td>
When I update the value in the input box in first row, it updates all rows below but not that row. I have a loop, I think. I only want it to update one row at a time as I change the values.
Any help / direction would be appreciated.
If you haven't included you need to include the JQuery library from local system or CDN.
https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
You need to add the change even for every input involved in your mathematical calculation. Here 'this; is passed as argument, so that we can find the parent row(through which all other controls contained in it can be searched.
onchange="myFunction(this)"
Inside the function 'myFunction', We at first finds the closest/parent 'tr'.
Again we selects the input field corresponding to Quantity, Amount etc(you can add more if required). The selection can be based on Id, Name, Class etc
var qty = currentRow.find('input[name=QTY]').val();
//or (id starting with 'QTY')
var qty = currentRow.find('input[id*=QTY]').val();
//or (give any class name and replace it instead of 'class-name')
var qty = currentRow.find('input.class-name').val();
We need to convert the string value to float to perform accurate mathematical calculations. While parsing empty string we may end up with 'NAN' - Not a Number. So we need to check before parsing.
qty = (qty == "" ? 0 : parseFloat(qty));
After all this you can use this value for any math calculation and setting it as text of the tag or any other.
If its p, div, span you need to set it as 'text'
currentRow.find('input[name=TOT]').text(totalAmount);
And if its input you need to set it as 'value'
currentRow.find('p[name=TOT]').val(totalAmount);
function myFunction(elem) {
var currentRow = $(elem).closest('tr');
var qty = currentRow.find('input[name=QTY]').val();
var amt = currentRow.find('input[name=AMNT]').val();
qty = (qty == "" ? 0 : parseFloat(qty));
amt = (amt == "" ? 0 : parseFloat(amt));
var totalAmount = qty * amt;
currentRow.find('p[name=TOT]').text(totalAmount);
currentRow.find('p[name=TYPE]').text(totalAmount > 0 ? 'Credit' : 'Debit');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td align="center">
<input id="QTY1" size="10" name="QTY" onchange="myFunction(this)" />
</td>
<td align="center">
<input id="AMNT1" size="10" name="AMNT" onchange="myFunction(this)" />
</td>
<td align="center">
<p id="TOT1" name="TOT"></p>
</td>
<td align="center">
<p id="chargepay1" name="TYPE"></p>
</td>
</tr>
<tr>
<td align="center">
<input id="QTY2" size="10" name="QTY" onchange="myFunction(this)" />
</td>
<td align="center">
<input id="AMNT2" size="10" name="AMNT" onchange="myFunction(this)" />
</td>
<td align="center">
<p id="TOT2" name="TOT"></p>
</td>
<td align="center">
<p id="chargepay2" name="TYPE"></p>
</td>
</tr>
<tr>
<td align="center">
<input id="QTY3" size="10" name="QTY" onchange="myFunction(this)" />
</td>
<td align="center">
<input id="AMNT3" size="10" name="AMNT" onchange="myFunction(this)" />
</td>
<td align="center">
<p id="TOT3" name="TOT"></p>
</td>
<td align="center">
<p id="chargepay3" name="TYPE"></p>
</td>
</tr>
</table>

How to set index variables in filters and selectors jquery

I have the following row structure that serves as a template to clone it and add it to a table each time a user presses an "Add" button, This template is hidden:
<tr class="plantilla">
<td>
<select class="cmb_arboles" id="cmb_arboles" name="arboles[]">
</select>
</td>
<td>
<input type="text" id="txttoneladas" name="txttoneladas[]"/>
</td>
<td>
<input type="text" id="txtprecio" name="txtprecio[]"/>
</td>
<td>
<select id="cmb_destino" name="destino[]">
</select>
</td>
<td class="eliminar_fila">
Eliminar
</td>
</tr>
When the "add" button is pressed, invokes:
$("#agregar").click(function()
{
nid++;
$("#plantilla tbody tr:eq(0)").clone().attr("id",nid).appendTo("#plantilla tbody");
$("#plantilla tbody tr:eq(nid)").find("td:eq(0)").find("select").attr("id","cmb_arboles_"+nid);
});
The first line, generates the sequence of the row number. The second line clones the entire template as a new row in the table and adds an id = nid to the .
The third line, accesses the row and looks for the select to add the nid sequential to the select id, but this does not work. When doing several tests, I conclude that the problem is that "tr: eq (nid)" does not accept the nid as variable, because when changing the nid by a specific integer, for example 1, it works, adding id to select. The question here is how to put the nid as a parameter in the: eq () so that it works correctly and do what I have explained ????
The same situation happens in the following line of code:
$(document).on('change', '.cmb_arboles', function () {
var $select = $(this);
var $row = $select.closest('tr');
var idd = $row.attr('id');
var valor=$("#tabla tbody tr[id=idd]").find("td:eq(0)").find("select").val();
});
Of lines 1 to 3, you get the number of the row in which you have selected in the select component.
The last line gets the value of the select that was selected, with the information of the row number where the selection was made, but this does not work. When doing several tests, I conclude that the problem is in "tr [id = idd]", which does not correctly process the variable "idd". I made the test of changing the idd by a specific integer, for example 1 and then I generate a new line in the table with id = 1 and the line of code works correctly, returning the option that was selected in the select element.
With these two examples, I want to check if someone can tell me how to place the parameters I mentioned in the two cases, so that the functionality is executed correctly and does what is expected.
I will be enormously grateful.
the issue is you have to give
("#plantilla tbody tr:eq(nid)" as (("#plantilla tbody tr:eq('"+nid+"')"
I have created a fiddle. check it out. I didn't use jquery for the same.
<style>
#template {
display: none;
}
</style>
<table><tbody id="template">
<tr class="plantilla">
<td>
<select class="cmb_arboles" id="cmb_arboles" name="arboles[]">
</select>
</td>
<td>
<input type="text" id="txttoneladas" name="txttoneladas[]" />
</td>
<td>
<input type="text" id="txtprecio" name="txtprecio[]" />
</td>
<td>
<select id="cmb_destino" name="destino[]">
</select>
</td>
<td class="eliminar_fila">Eliminar</td>
</tr></tbody>
</table>
<input type="button" id="agregar" value="Add">
<table>
<tbody id="plantilla"></tbody>
</table>
<script>
var nid = -1;
document.getElementById('agregar').onclick = function(){
var table = document.getElementById('plantilla');
var newRow = document.getElementById('template').innerHTML;
nid++;
newRow = newRow.replace('id="cmb_arboles"', 'id="cmb_arboles_'+nid+'"');
newRow.replace('id="cmb_arboles"', 'id="cmb_arboles_'+nid+'"');
table.innerHTML += newRow;
}
</script>
https://jsfiddle.net/nugee3s6/
You are hard coding the id value in $("#tabla tbody tr[id=idd]") not using the variable above it
If you wanted to use the variable it would be:
$("#tabla tbody tr[id=" +idd +"]")
But it makes no sense to use the ID to search again for the same row since you already have that row element as $row
So change to:
$(document).on('change', '.cmb_arboles', function () {
var $select = $(this);
var $row = $select.closest('tr');
var valor=$row.find("td:eq(0) select").val();
});
Then don't worry about using ID's, you don't need them

Find hidden input when inside a td tag that is near it in same row

I need to find a value of a hidden input in same table row but it seems that i cannot access it with how i am trying to.
function setDateTimeOn(elm) {
var formattedDate = GetCurrentDateTime(); //get formatted date
$(elm) //clicked button
.parent("td") // container td
.next() // next td
.find("span")
.text(formattedDate);
console.log(elm);
var hdn = $(this).closest('tr').find('input[type="hidden"]').val();
console.log(hdn);
}
http://jsfiddle.net/bthorn/xf12y7y4/
What I am searching for is this
<input type="hidden" name="GridView1:_ctl2:hndTxtId" id="GridView1__ctl2_hndTxtId" value="3601">
I want the value 3601 , it is in the same tr
HTML
<table>
<tr>
<td style="width:5px;">
<input type="hidden" name="GridView1:_ctl2:hndTxtId" id="GridView1__ctl2_hndTxtId" value="3601">
</td>
<td style="width:50px;"> <span id="GridView1__ctl2_lblVehicle0">413</span>
</td>
<td style="width:5px;">
<input type="button" id="GridView1__ctl2_AddButton0" name="GridView1:_ctl2:AddButton0" value="On" class="btn-blue" onclick="setDateTimeOn(this)">
</td>
<td style="width:150px;">
<span id="GridView1__ctl2_lblStormTimeOn"></span>
</td>
</tr>
I see it spit out the complete input element tag but the var hdn , I try to do a console.log(hdn) and it is undefined.
The problem is that you're using:
var hdn = $(this).closest('tr').find('input[type="hidden"]').val();
And this here is the global Window object. You want to use the element:
var hdn = $(elm).closest('tr').find('input[type="hidden"]').val();
Updated fiddle

Getting nearest text box to radio button in table

I am having trouble getting the text box nearest to my selected radio button. Here is what I have tried so far which keeps returning me 'undefined'.
HTML:
<fieldset class="capacity-field">
<legend>Capacity</legend>
<table style="margin-bottom: 20px">
<tr>
<td>
<input type="radio" name="capacity" value="raw" checked>Raw (TB):
</td>
<td>
<input type="text" name="raw-capacity" value="256" size="2"> TB
</td>
</tr>
<tr>
<td>
<input type="radio" name="capacity" value="usable">Usable (TB):
</td>
<td>
<input type="text" name="usable-capacity" value="161.28" size="2"> TB
</td>
</tr>
<tr>
<td>
<input type="radio" name="capacity" value="effective">Effective (TB):
</td>
<td>
<input type="text" name="effective-capacity" value="161.28" size="2"> TB
</td>
</tr>
</table>
JavaScript/jQuery
function cap_growth_update(toUpdate) {
var capacity = $("input[name='capacity']:checked").next("input[type='text']").val();
alert(capacity);
}
$(document).ready(function(){
cap_growth_update("T");
});
I know the value of toUpdate is arbitrary at this point, but it will be used as a selector later down the line and thus is included.
The jQuery next() function looks for a sibling element, but since these elements are separated under different td elements, you'll have to climb up the DOM:
$("input[name='capacity']:checked").closest("tr").find("input[type='text']").val();
So what it does, is to go to the closest parent, and then search for the children text input.
Try using parents() with eq() and find()
$("input[name='capacity']:checked").parents().eq(1).find("input[type='text']").val();
Note this is only a suggestion I make based on your markup, your goal could be achieved in other ways (jQuery is a rich library to traverse and manipulate DOM)
$(function() {
$("input:radio").click(function() {
if ($(this).is(":checked")) {
var value = $(this).closest("tr").find("input:text").val();
}
});
});
The code checks for a click event on a radio element then check if the element is checked, if it's checked then obtain the parent row of the radio element, find an input text inside the row an get the value of the input text the it saves the value at the var value, so you can do whatever with the value :)
Regards!

Select closest control element regardless of type (Input, Select etc.) for Validation

Let me explain:
I have a table form and some fields are required and I am trying to create custom validation.
example:
<table>
<tr>
<td class="required">Description</td>
<td>
<input id="input1" />
</td>
<td>Phone</td>
<td>
<input id="input2" />
</td>
</tr>
<tr>
<td class="required">Location</td>
<td>
<select id="select1"/>
</td>
<td>Email</td>
<td>
<input id="input3"/>
</td>
</tr>
</table>
What I wanna do is find all elements with class required
which is pretty easy using:
var requiredElements = document.querySelectorAll(".required");
And then I want to find their closest control element and check if it's value is empty. The problem is I don't know if it's gonna be input or select. I was thinking of using the .closest() function but it could lead to unwanted results if two different inputs are equally close to a required (like in the example above).
Any help would be much appreciated.
You can select a control regardless of type with jQuery by using any one of a number of selectors and combining it with one or more additional selectors.
In the code snippet you provide, the controls you want to select (input1 and select1) are child elements of a table cell element that is a sibling of the cell with the class "required", so we can build a selection thus:
$(".required + td").child
which breaks down as:
Find the elements with the "required" class applied to them.
This will give us the 2 table cells:
<td class="required">Description</td>
and
<td class="required">Location</td>
For each element returned by 1. use the "next adjacent" selector + with td to get the next table cell:
<td><input id="input1" /></td>
and
<td><select id="select1" /></td>
For each element returned by 2. get the child element:
<input id="input1" />
and
<select id="select1" />
There is also a jsFiddle to illustrate actions on the targets (change border to dark red).
Edit
This works because the layout in your snippet consistently places the elements you want to target in the same position relative to the element with your selection criteria. You must have some consistent way of finding elements that are not marked with a class/id otherwise you can't achieve your objective.
Although I like Raad's answer I'd like to post this answer to say what I did to solve my problem.
First of all I added a custom attribute labelFor to every label td with value equal to the id of it's corresponding input as follows:
<table>
<tr>
<td class="required" labelFor="input1">Description</td>
<td>
<input id="input1" />
</td>
<td labelFor="input2">Phone</td>
<td>
<input id="input2" />
</td>
</tr>
<tr>
<td class="required" labelFor="select1">Location</td>
<td>
<select id="select1"/>
</td>
<td labelFor="input3">Email</td>
<td>
<input id="input3"/>
</td>
</tr>
</table>
Then I used the following Validation function:
function validateForm () {
var self = this;
var validationPassed = true;
//First I will gather every .required element in an Array
var requiredTags = document.querySelectorAll(".required");
//Then I will loop through the array
for (var i = 0; i < requiredTags.length; i++) {
//Get value of attribute "labelFor" which would be the controlId that this label refers to
var controlId = $(requiredTags[i]).attr("labelFor");
//Then I use this to check if that control's value is empty.
if ($("#" + controlId).val() == ('' || null)) {
validationPassed = false;
}
}
if (!validationPassed) {
alert("Please fill all the required fields");
}
return validationPassed;
}
This way I check if all required fields are not empty and return true, or return false and an alert to warn user.
I find that the problem Raad described in his Edit is the main reason why this approach could be more useful. You don't have to worry if your input element is always in the same position relatively to your label td element.

Categories

Resources