Traversing through a table with javascript to compare with row values - javascript

my table looks like this.
<body>
<table class="tblTest">
<tr>
<td>
<label>wer</label></td>
<td>
<label>ur4</label></td>
<td>
<label>ksdj</label></td>
</tr>
<tr>
<td>
<label>eiejr</label></td>
<td>
<label>ur4</label></td>
<td>
<label>yutu56</label></td>
</tr>
<tr>
<td>
<input type="text" /></td>
<td>
<input type="text" /></td>
<td>
<input type="text" />
</td>
</tr>
<tr>
<td>
<label>jweee</label>
</td>
<td>
<label>male</label>
</td>
<td>
<label>ur4</label>
</td>
</tr>
<tr>
<td>
<label>ssssss</label>
</td>
<td>
<label>male</label>
</td>
<td>
<label>ur4s</label></td>
</tr>
<tr>
<td>
<input type="text" /></td>
<td>
<input type="radio" name="gender" value="male" />Male
<br />
<input type="radio" name="gender" value="female" />Female
</td>
<td>
<select name="cars" style="width: 128px">
<option selected="selected" value="Select">Select</option>
<option value="saab">BMW</option>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
</td>
</tr>
</table> <br />
<button type="button" onclick="function1()">Submit</button>
I want a Java script/jQuery which will check the two labels and if there is a mismatch then it will make the Text Box Red and if not then green. I can't use getElementById for the labels only I have to traverse through it and get the td index and do the task. I Don't know how to get prev and closest elements. Please help me with this.
The function which I'm trying is
function function1() {
var inputcontrols = document.getElementsByTagName('input');
for (var i = 0; i < inputcontrols.length; ++i)
{
var element = inputcontrols[i];
//element.style.background = "#90EE90"; by default making it green
var ind = $(this).closest('td').prev('td').text();
alert(ind);
}
Trying to get the td text in "ind", but its returning empty.

First get all the inputs, and use the each loop to iterate these. And by using the index to get the appropriate label texts.
The reason text() did not work for you, is because you are trying to get the text from the td element. This is empty, because it only contains a HTMLElement label. Look at the jQuery specs to see the difference between text() and html()
function function1() {
$('table').each(function(n, table) {
$(table).find('tr').each(function(n, tr) {
tr = $(tr);
var td = undefined;
var c = 0;
tr.find('input,select').each(function(i, input) {
if(!td || !td.is($(input).closest('td'))) {
td = $(input).closest('td');
c++;
}
var lbl1 = $(tr.prev().prev().find('td')[c]).find('label').text();
var lbl2 = $(tr.prev().find('td')[c]).find('label').text();
if(lbl1 === lbl2) {
$(input).css('backgroundColor', 'green');
} else {
$(input).css('backgroundColor', 'red');
}
});
});
});
}

The first problem I see is that you're using $(this) which is what how you chain the function scope in jQuery. For example:
$('a').each(function() {
// 'this' scopes to the current 'a' element inside the 'each' loop
$(this).css('color', '#FF0000');
});
Since you've already found your input controls and stored them in var element you need to pass that element into jQuery so it knows what you're looking for.
var element = inputcontrols[i];
$(element).closest('td').prev('td').text();
Next, if you're trying to compare the text field to the previous label you need to fix your traversal steps to be:
From the text field
Find its parent tr not td (go up to the row)
Find its the previous tr (go back a row)
Find its child label (drill down into the previous row)
Get the text from the label

assuming that you only have two table rows, you can try this-
function function1() {
var inputs = $('.tblTest input');
var tr1 = $('.tblTest tr:nth(0)');
var tr2 = $('.tblTest tr:nth(1)');
for (var i = 0; i < inputs.length; ++i)
{
var element = inputcontrols[i];
if(tr1.find('td:nth('+ i +') label').html().trim() == tr2.find('td:nth('+ i +') label').html().trim()) {
element.style.background = "green";
}
else {
element.style.background = "red";
}
}
}

Related

Why is my code returning "undefined" on innerHtml?

I made a listener to attatch an id "selectedRow" to the row a user has clicked on. The intent from there is be able to manipulate the data in that row; Previously i was using content editable however I'm trying to make it more obvious to the user that they are editing a row (this is for a project) so i've created an editing panel to do so. I've however ran in to some problems with a lot of data being returned as undefined when using .innerHTML when sending the TD to the input boxes.
I've tried using .HTML instead
$('tr').click(function() {
if(document.getElementById("SELECTEDROW")) {
var oldRow = document.getElementById("SELECTEDROW");
oldRow.classList.remove("selected");
$("#SELECTEDROW").removeAttr('id');
}
$(this).attr('id', 'SELECTEDROW');
selectedRow = document.getElementById("SELECTEDROW");
table = selectedRow.parentNode;
console.log("Row " + selectedRow.childNodes[1].innerHTML + " Selected");
selectedRow.classList.add("selected");
editRow();
});
function editRow() {
var currentTD = selectedRow.childNodes;
var inputs = document.getElementById("inputs").childNodes;
var i = 0;
for (i = 0; i < currentTD.length; i++) {
inputs[i].innerHTML = currentTD.html;
}
console.log('Now Editing:' + currentTD[1].innerHTML);
document.getElementById("editingPanel").style.display = "block";
document.getElementById("content").style.height = "49%";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Role</th>
<th>Address</th>
<th>Phone</th>
<th>Email</th>
<th>Password</th>
</tr>
<tr>
<td>1</td>
<td>Bill Robbins</td>
<td>Conductor</td>
<td>12, Caldrow Ave, Plymouth, Pl21XE</td>
<td>01921202384</td>
<td>XxbillyboyxX#bossman.com</td>
<td>CaTsRbAe1967</td>
</tr>
<tr>
<td>2</td>
<td>Kat Robbins</td>
<td>Admin</td>
<td>12, Caldrow Ave, Plymouth, Pl21XE</td>
<td>019232042454</td>
<td>katrobs#gmail.com</td>
<td>thR33mel0ns</td>
</tr>
</table>
</div>
<div id="editingPanel">
<div id="inputFields">
<form id="inputs">
<input id="input1" type="text" name=""/>
<input id="input2" type="text" name="">
<input id="input3" type="text" name="">
<input id="input4" type="text" name="">
<input id="input5" type="text" name="">
<input id="input6" type="text" name="">
<input id="input7" type="text" name="">
<input id="input8" type="text" name="">
</form>
</div>
<div id="editButtons">
<button onclick="addRow()">New Row</button>
<button onclick="editRow()">Save Row</button>
<button onclick="removeRow()">Delete Row</button>
</div>
</div>
The expected output would be for each td's text to be copied into the input boxes.
You need to get the children properly. You also need to assign the text to the value property of the input, not its innerHTML
function editRow() {
// You need to get elements by tag name, not childNodes
var currentTD = selectedRow.getElementsByTagName("td");
// You need to get elements by tag name, not childNodes
var inputs = document.getElementById("inputs").getElementsByTagName("input");
var i = 0;
for (i = 0; i < currentTD.length; i++) {
console.log(inputs[i]);
console.log(currentTD[i]);
// set the "Value" of an input box, not its "innerHTML"
// also you need to apply the [i] to the currentTD because it is a list
inputs[i].value = currentTD[i].innerHTML;
}
You can try this:
$("body").on("click","tr",function(){ //Just in case you are going to use dynamic content, because the click method doesn't work on dynamically created/added elements
for(let i=0;i<7;i++){
$("#input"+(i+1)).val($(this).children()[i].innerHTML); //You are using jQuery for a reason, to simplify code, so avoid using unnecessary JS where you can by using simplified jQuery
}
});

how to select second input box from cell using javascript

I have the table with following structure . I am generating a dynamic table on the basis of input provided by user which will repeat this row .
I want to get the value of this text box and trying to use the code below
if (row.getAttribute('val') === 'answer') {
var Cell = table.rows[i].cells[0];
alert(Cell.innerHTML);
}
<tr val='answer'>
<td>
<input type='checkbox' />
<input style='width:483px' type='text' />
</td>
</tr>
I am putting alert to check if i am getting the correct value .I can see the two inputs in the alert message I want to get the value of text box using javascript not jquery
You can use querySelectorAll to select all rows and then use loop to get only rows with val='answer' and then use querySelector to get input with type="text"
var rows = document.querySelectorAll('tr');
for (var i = 0; i < rows.length; i++) {
if (rows[i].getAttribute('val') == 'answer') {
var input = rows[i].querySelector('input[type="text"]');
console.log(input.value);
}
}
<table>
<tr val='answer'>
<td>
<input type='checkbox' />
<input value="Some value" style='width:483px' type='text' />
</td>
</tr>
</table>

HTML Table - Iterate over row and sum the fields

I have then following table:
<table style="width:100%" id="testTable">
<tr>
<th>length per</th>
<th>width per</th>
<th>length</th>
<th>width</th>
<th>total</th>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
</table>
<input type=button value='+' onclick="addRow()" />
<input type=button value='Calculate' onclick="Calculate()" />
I also have the javascript which adds the value and puts it in total:
<script>
function Calculate() {
var lengthPerInput = $("input[name='length-per-input']").val();
var widthPerInput = $("input[name='width-per-input']").val();
var lengthTotal = $("input[name='length-total-input']").val();
var widthTotal = $("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$("input[name='total-output']").val(total);
}
</script>
The aim here is to have it iterate over the two rows, then add each one separately.
I know how to get each row by using:
$('#testTable tr').each(function(){
console.log(this);
$(this).find('length-per-input').each(function(){
console.log(this);
})
})
But using the row (accessed via "this") I don't know how to get the correct cells, get their value, then perform the calculate on that row for the total.
Any advice on this please? Thank you!
function Calculate(tr_row) {
var lengthPerInput = tr_row.find("input[name='length-per-input']").val();
var widthPerInput = tr_row.find("input[name='width-per-input']").val();
var lengthTotal = tr_row.find("input[name='length-total-input']").val();
var widthTotal = tr_row.find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
tr_row.find("input[name='total-output']").val(total);
}
For every row you call function to summ the values
To the function you pass the row, then it can collect values on that row
$('#testTable tr').each(function(){
Calculate($(this))
})
You can use each() function to iterate through table and use find() function to find cell values.
function Calculate() {
$('#testTable tr').each(function() {
var lengthPerInput = $(this).find("input[name='length-per-input']").val();
var widthPerInput = $(this).find("input[name='width-per-input']").val();
var lengthTotal = $(this).find("input[name='length-total-input']").val();
var widthTotal = $(this).find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$(this).find("input[name='total-output']").val(total);
});
}
Working Plunker
How to get a table cell value using jQuery?

JavaScript add new row and populate new rows inputs with data from dropdown value

I hope you can help me with a Javascript problem I'm having, I've been staring at this for days and I just can't figure it out!!
I've got a script that splits the value of an option dropdown and populates certain feilds with the splitted values.
Then I've got an 'Add Order Line' hyperlink to add a new row to a table, but I want the above feature to happen on any new line as well but nothing happens
I've recreated this in jsfiddle.
$(window).load(function(){
var selectEl = document.getElementById('part_selection');
selectEl.onchange = function () {
//var input1 = document.getElementsByName('PART_NO');
var input2 = document.getElementById('PART_DESCRIPTION');
var input3 = document.getElementById('PART_PRICE');
var input4 = document.getElementById('UNIT_MEAS');
var val = this.value;
var parts = val.split("_");
/*input1.value = parts[0];*/
input2.value = parts[1];
input3.value = parts[2];
input4.value = parts[3];
}
});
$(function(){
var counter = 1;
$('a.add-line').on('click',function()
{
counter ++;
$(this).prev('table.orderlinelist').find('tr').last().clone().find('input').val('').end().find('input.ORDER_LINE_NO').val(counter).end().appendTo('table.orderlinelist');
});
});
<table class="orderlinelist">
<tr>
<td>Line</td>
<td>Part</td>
<td>Part Description</td>
<td>Unit Price</td>
<td>Qty</td>
<td>UoM</td>
<td>Line Total</td>
</tr>
<tr >
<td>
<input type="text" name="ORDER_LINE_NO[]" class="ORDER_LINE_NO" id="ORDER_LINE_NO" value="1" readonly="readonly"/>
</td>
<td>
<select name="PART_NO" id="part_selection">
<option value="">Select a Part</option>
<option class="dropdown1" value="5461_Coxmoor Sideboard_299.00_EACH">5461</option>
</select>
</td>
<td>
<input type="text" name="part_desc" id="PART_DESCRIPTION" readonly />
</td>
<td>
<input type="text" name="PART_PRICE[]" id="PART_PRICE" class="orderprice"/>
</td>
<td>
<input type="text" name="QTY[]" id="QTY" class="orderqty"/>
</td>
<td>
<input type="text" name="UNIT_MEAS[]" id="UNIT_MEAS" class="orderuom"/>
</td>
<td>
<input type="text" name="TOTAL" id="TOTAL" class="orderprice"/>
</td>
</tr>
</table>
Add Line
Can you point me in the right direction?
Cheers
These are steps you can take to do what you want:
first add class attributes to the input tags, instead of ID.
Use jQuery .on() to handle your dynamic event.
Use closest to find the current row.
then using jQuery find, find the inputs based on their class attributes.
And continue the rest of your code scenario.
I took these steps on your code like:
$(document).on("change", "table.orderlinelist .part_selection", function () {
var jrow = $(this).closest('tr');
var input2 = jrow.find('.PART_DESCRIPTION');
var input3 = jrow.find('.PART_PRICE');
var input4 = jrow.find('.UNIT_MEAS');
var val = this.value;
var parts = val.split("_");
input2.val(parts[1]);
input3.val(parts[2]);
input4.val(parts[3]);
});
This is your working DEMO
you are duplicating the identifiers of elements and assigning this event change the "select" Specific.
yours is better to work with classes in this way
http://jsfiddle.net/4dPX2/16/
$(".orderlinelist").on("change", ".part_selection", function (e) {});

For loop breaking IndexOf

Well I've ripped my hair off because I assumed I was finished this script but suddenly adding ONE more for loop broke every single indexOf, I tried to create checks so the console wouldn't freak out, but sadly no success. using a static value for "z" or LevelCheck allows for all the indexOfs to work properly but as soon as a for loop is involved, it seems none of the indexOfs wishes to work
<script type="text/javascript">
var tempval = new Array();
function Renew(){ //Reset tempval back to val
for(d=0;d<val.length;d++){
tempval[d] = val[d];
}
}
function UpdateLoop(){
Renew();
var Levels = document.getElementById("Lvl");
if(Levels){
for(z=0; z<=Levels.value; z++){
Update(z);
}
}
}
function Update(LevelCheck){
for (i=0; i<=key.length; i++){
if(key[i] != null){
if ( key[i].indexOf("rate") > -1 ) { //Search through
for (r=0; r<=key.length; r++){
if(key[i].indexOf(key[r]) > -1){ //Finds out which form it should replace
var raw=tempval[i];
for (y=0; y<=key.length; y++){
if(key[i] != "movespeed" && key[i] != "Movrate"){ //add a check to see if string is not there
var item = document.getElementById(key[y]);
if (item) { //Make it use formula value and then put that result into a value and loop back into function until level reached. If level changed to a lower number, reset to original value and repeat
//raw=raw.replace(key[y],document.getElementById(key[y]).value); //replace this with val[y]
raw=raw.replace(key[y],tempval[y]);
}
}
else
break;
}
if(raw != null){
if(raw.indexOf("Mov") > -1){
for(x=0; x<=key.length; x++){
if(key[x].indexOf("movespeed") > -1){
//raw=raw.replace("Mov",document.getElementById(key[x]).value);
raw=raw.replace("Mov",tempval[x]);
break;
}
}
}
if(raw.indexOf("Lvl") > -1){
raw=raw.replace("Lvl",document.getElementById('Lvl').value);
}
if(raw.indexOf("Exp") > -1){
raw=raw.replace("Exp","0");
}
}
if( document.getElementById('Lvl').value == LevelCheck){
alert("Input:"+tempval[i]);
if(key[i] == "Movrate"){
document.getElementById("movespeed").value = eval(raw);
}
else{
var check = document.getElementById(key[r]);
if (check){
document.getElementById(key[r]).value = eval(raw);
}
}
}
else{
tempval[r] = eval(raw);
}
break; //So it doesn't keep searching
}
}
}
}
}
}
</script>
Html portion(This is generated via php so I just used what the browser generated)
<table>
<tbody>
<tr>
<td>Creature Name:</td>
<td>
<input type="Text" name="CName" value="Thing" size="10%">
</td>
</tr>
<tr>
<td>Level:</td>
<td>
<input type="Text" id="Lvl" name="level" onchange="" value="1" size="10%">
</td>
</tr>
<tr>
<td>movespeed:</td>
<td>
<input type="Text" name="movespeed" id="movespeed" value="1" size="10%">
</td>
</tr>
<tr>
<td>str:</td>
<td>
<input type="Text" name="str" id="str" value="4" size="10%">
</td>
</tr>
<tr>
<td>dex:</td>
<td>
<input type="Text" name="dex" id="dex" value="3" size="10%">
</td>
</tr>
<tr>
<td>int:</td>
<td>
<input type="Text" name="int" id="int" value="1" size="10%">
</td>
</tr>
<tr>
<td>will:</td>
<td>
<input type="Text" name="will" id="will" value="2" size="10%">
</td>
</tr>
<script type="text/javascript">
var key=new Array();
var val=new Array();
key.push("movespeed");
val.push("1");
key.push("str");
val.push("4");
key.push("dex");
val.push("3");
key.push("int");
val.push("1");
key.push("will");
val.push("2");
key.push("Movrate");
val.push("Mov+1");
key.push("strrate");
val.push("1+str");
key.push("dexrate");
val.push("1+dex+(str/4)");
key.push("intrate");
val.push("1+int");
key.push("willrate");
val.push("1+will");
</script>
<tr>
<td>
<input type="button" name="button" value="Use Formula" onclick="UpdateLoop();">
</td>
<td>
<input type="submit" value="Save">
</td>
Console:
Uncaught TypeError: Object 2 has no method 'indexOf' Monsters.php:62
Update Monsters.php:62
UpdateLoop Monsters.php:39
onclick Monsters.php:28
you need to change your Update function to the following:
function UpdateLoop(){
var Levels = document.getElementById("Lvl");
if(Levels){
for(z=0; z<=Levels.value; z++){
Renew();
Update(z);
}
}
}
After processing Level 0, the tempval array had the values from Level 0, which wiped out the original values from the val array.
Making this change fixed the problem in my tests: http://jsfiddle.net/jimmym715/xTUND/
oh, and what MaxArt said in the comments above is right on the money... there are far better ways to accomplish what you're going for here
Turns out that flat numbers are NOT strings so in order to safely go through every value .toString() had to be present, thanks everyone for trying though.
so it would look like:
key[i].toString().indexOf(key[r])

Categories