jquery sum clicked table row from given index to 0 - javascript

<tr data-index="0" data-volume="3.50" data-price="14600.01" onclick="populateSellForm(0)" data-key="11"><td>3.50</td><td>14.600,01</td></tr>
<tr data-index="1" data-volume="5.00" data-price="14449.99" onclick="populateSellForm(1)" data-key="7"><td>5.00</td><td>14.449,99</td></tr>
<tr data-index="2" data-volume="0.78" data-price="14350.00" onclick="populateSellForm(2)" data-key="5"><td>0.78</td><td>14.350,00</td></tr>
<tr data-index="3" data-volume="2.50" data-price="14349.99" onclick="populateSellForm(3)" data-key="1"><td>2.50</td><td>14.349,99</td></tr>
<tr data-index="4" data-volume="1.10" data-price="14250.00" onclick="populateSellForm(4)" data-key="15"><td>1.10</td><td>14.250,00</td></tr>
is there a way sum data-volume and average data-price from given index (asume given index 3) to data-index 0 with jquery
maybe you could point me right direction for i do this

//**Call function range with start and end node to get sum and average **//
<script type="text/javascript">
function range(start,end){
var sumVol = 0;
var sumPrice = 0;
var count = 0;
for(var i=start;i<=end;i++)
{
sumVol += parseFloat($('tr[data-index='+i+']').attr('data-volume'));
sumPrice += parseFloat($('tr[data-index='+i+']').attr('data-price'));
count++;
}
var avgPrice = (sumPrice/count);
return "Sum of Volume = "+sumVol+" & Average Price = "+avgPrice;
}
alert(range(1,3));
</script>

You can use jquery filter function to filter the list, and then sum and avg the result.
$(document).ready(function(){
var sum = 0;
var avg = 0;
var filtered = $("tr").filter(function(){
var id = parseInt($(this).data("index"));
return ((id <=3) && (id >=0));
});
filtered.each(function(){
sum+= parseFloat($(this).data("volume"))
avg+= parseFloat($(this).data("price"))
});
console.log(sum);
console.log(parseFloat(avg/filtered.length));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<table>
<tr data-index="0" data-volume="3.50" data-price="14600.01" onclick="populateSellForm(0)" data-key="11"><td>3.50</td><td>14.600,01</td></tr>
<tr data-index="1" data-volume="5.00" data-price="14449.99" onclick="populateSellForm(1)" data-key="7"><td>5.00</td><td>14.449,99</td></tr>
<tr data-index="2" data-volume="0.78" data-price="14350.00" onclick="populateSellForm(2)" data-key="5"><td>0.78</td><td>14.350,00</td></tr>
<tr data-index="3" data-volume="2.50" data-price="14349.99" onclick="populateSellForm(3)" data-key="1"><td>2.50</td><td>14.349,99</td></tr>
<tr data-index="4" data-volume="1.10" data-price="14250.00" onclick="populateSellForm(4)" data-key="15"><td>1.10</td><td>14.250,00</td></tr>
</table>

My take on this:
I removed onclick="populateSellForm(0)" from the markup since it seems redundant because you already have data-index attribute.
Instead I attached a click event handler to rows. So, on every click on a row the sum of volumes and average price are calculated.
$(document).ready(function() {
$("table tr").on("click", function() {
if(!$(this).data("volume") || !$(this).data("price")) return;
var limit = $(this).data("index"),
trs = $("table tr"),
sumOfVolumes = 0, totalPrice = 0;
$.each(trs, function(i, val){
if(i === 0) return true;
if(i > limit + 1) return false;
sumOfVolumes += +$(trs[i]).data("volume");
totalPrice += +$(trs[i]).data("price");
});
$("#limit").text(limit + 1);
$("#volume").text(sumOfVolumes.toFixed(2));
$("#price").text((totalPrice/(limit + 1)).toFixed(2));
});
});
table {
border-collapse: collapse;
width: 100%;
}
th, td {
text-align: left;
padding: 8px;
}
tr:not(:first-child) {cursor: pointer; }
tr:nth-child(even){background-color: #f2f2f2}
th {
background-color: #4CAF50;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="limit">0</span> first items:<br>
Total volume: <span id="volume">0</span><br>
Average price: <span id="price">0</span><hr>
<table>
<tr>
<th>Volume</th>
<th>Price</th>
</tr>
<tr data-index="0" data-volume="3.50" data-price="14600.01" data-key="11"><td>3.50</td><td>14.600,01</td></tr>
<tr data-index="1" data-volume="5.00" data-price="14449.99" data-key="7"><td>5.00</td><td>14.449,99</td></tr>
<tr data-index="2" data-volume="0.78" data-price="14350.00" data-key="5"><td>0.78</td><td>14.350,00</td></tr>
<tr data-index="3" data-volume="2.50" data-price="14349.99" data-key="1"><td>2.50</td><td>14.349,99</td></tr>
<tr data-index="4" data-volume="1.10" data-price="14250.00" data-key="15"><td>1.10</td><td>14.250,00</td></tr>
</table>

Related

Add columns to a new table row in JQuery

I have the following html:
<table id='myTable'>
<tbody>
<tr>
<td id=col1">12</td>
<td id=col2">55</td>
<td id=col3">142</td>
<td id=col4">7</td>
</tr>
</tbody>
</table>
I would like to use JQuery to append everything after column 3 (col3) to a new row. Ideally I would end up with something like this:
<table id='myTable'>
<tbody>
<tr>
<td id=col1">12</td>
<td id=col2">55</td>
<td id=col3">142</td>
</tr>
<tr>
<td id=col4">7</td>
</tr>
</tbody>
</table>
Any ideas how this could be achieved? I have tried a few things but haven't been able to get it working.
You could define a generic redistribution function, that takes as argument the desired number of columns, and which just fills up the rows with content from top to bottom, using that number of columns.
It could even be a jQuery plugin:
$.fn.redistribute = function(maxNumCols) {
if (maxNumCols < 1) return;
$(this).each(function () {
let cells = Array.from($("td", this));
let $tr = $("tr", this);
let rowCount = Math.ceil(cells.length / maxNumCols);
for (let i = 0; i < rowCount; i++) {
let $row = i >= $tr.length ? $("<tr>").appendTo(this) : $tr.eq(i);
$row.append(cells.splice(0, maxNumCols));
}
});
}
// I/O management
function alignTable() {
let cols = +$("input").val(); // Get desired number of columns
$("#myTable").redistribute(cols); // Apply to table
}
// Refresh whenever input changes
$("input").on("input", alignTable);
// Refresh on page load
alignTable();
table { border-collapse: collapse; border: 2px solid }
td { border: 1px solid; padding: 4px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Desired number of columns: <input type="number" size="3" value="4" min="1">
<table id='myTable'>
<tbody>
<tr>
<td>12</td>
<td>55</td>
<td>142</td>
<td>7</td>
<td>20</td>
<td>410</td>
<td>99</td>
</tr>
</tbody>
</table>
Here is a version with one extra statement that sets the colspan on the very last td element so it occupies the remaining columns in the last row:
$.fn.redistribute = function(maxNumCols) {
if (maxNumCols < 1) return;
$(this).each(function () {
let cells = Array.from($("td", this));
let $tr = $("tr", this);
let rowCount = Math.ceil(cells.length / maxNumCols);
for (let i = 0; i < rowCount; i++) {
let $row = i >= $tr.length ? $("<tr>").appendTo(this) : $tr.eq(i);
$row.append(cells.splice(0, maxNumCols));
}
$("td", this).last().attr("colspan", rowCount * maxNumCols - cells.length + 1);
});
}
// I/O management
function alignTable() {
let cols = +$("input").val(); // Get desired number of columns
$("#myTable").redistribute(cols); // Apply to table
}
// Refresh whenever input changes
$("input").on("input", alignTable);
// Refresh on page load
alignTable();
table { border-collapse: collapse; }
td { border: 1px solid; padding: 4px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Desired number of columns: <input type="number" size="3" value="4" min="1">
<table id='myTable'>
<tbody>
<tr>
<td>12</td>
<td>55</td>
<td>142</td>
<td>7</td>
<td>20</td>
<td>410</td>
<td>99</td>
</tr>
</tbody>
</table>
It sounds like you're still new to jQuery. To give you an idea how to solve your described problem, I have written a solution here. I hope it helps you.
// parameters for splitting
var splitIndex = 3,
splitClass = '.split-columns';
// start the splitting
splitColumnsIntoRows();
function splitColumnsIntoRows() {
var $tables = $(splitClass),
numberTables = $tables.length;
if (numberTables == 0) {
return;
}
for (var i = 0; i < numberTables; i++) {
iterateSplittingRows($($tables[i]).find('tr'));
}
}
function iterateSplittingRows($currentRows) {
var $currentRow,
numberRows = $currentRows.length;
if (numberRows == 0) {
return;
}
for (var i = 0; i < numberRows; i++) {
$currentRow = $($currentRows[i]);
iterateSplittingFields($currentRow, $currentRow.find('th, td'));
}
}
function iterateSplittingFields($currentRow, $currentFields) {
var $newRow,
newRows = [],
childrenLength,
numberFields = $currentFields.length;
if (numberFields == 0) {
return;
}
for (var i = 0; i < numberFields; i++) {
if (i < splitIndex) {
continue;
}
if (i % splitIndex == 0) {
$newRow = $('<tr></tr>');
}
$newRow.append($currentFields[i]);
if (i == numberFields - 1) {
childrenLength = $newRow.children().length;
// fill the row with empty fields if the length does not fit the splitIndex
for (var j = splitIndex; j > childrenLength; j--) {
$newRow.append($('<td></td>'));
}
}
if (
(i >= splitIndex && i % splitIndex == splitIndex - 1)
||
i == numberFields - 1
){
newRows.push($newRow);
}
}
$currentRow.after(newRows);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable" class="split-columns">
<tbody>
<tr>
<td class="col_01">01</td>
<td class="col_02">02</td>
<td class="col_03">03</td>
<td class="col_04">04</td>
<td class="col_05">05</td>
<td class="col_06">06</td>
<td class="col_07">07</td>
<td class="col_08">08</td>
<td class="col_09">09</td>
</tr>
<tr>
<td class="col_10">10</td>
<td class="col_11">11</td>
<td class="col_12">12</td>
<td class="col_13">13</td>
<td class="col_14">14</td>
<td class="col_15">15</td>
<td class="col_16">16</td>
<td class="col_17">17</td>
</tr>
<tr>
<td class="col_19">19</td>
<td class="col_20">20</td>
<td class="col_21">21</td>
<td class="col_22">22</td>
<td class="col_23">23</td>
<td class="col_24">24</td>
<td class="col_25">25</td>
</tr>
</tbody>
</table>

Show calculated arithmetic mean in <td> when the button is clicked

please help me finish this, I'm getting nowhere.
what needs to be done
final results
I've explained in the pictures whats the finish goal.
This is a grade calculator.
There are 3 types of grades.. it should calculate the arithmetic mean for every category and arithmetic mean for all grades no matter which category they are.
Calculated values should be shown on the appropriate block, as shown in the picture.
input[type="number"]{
color : transparent;
text-shadow : 0 0 0 #000;
}
input[type="number"]:focus{
outline : none;
}
</style>
<body>
<div id="stranica" style="display: inline-block; position: left;">
<button type="button" onclick="javascript:dodajocenu();"> Add grade</button>
</div>
<div id="desna" style="display: inline-block; position: absolute; text-align: center;">
<button type="button" onclick=""> Calculate </button>
<br><br>
<table border="1">
<tbody>
<tr>
<td style="width:70px; text-align: center;">Written test</td>
<td style="width:70px; text-align: center;">Essay</td>
<td style="width:70px; text-align: center;">Class Activity</td>
</tr>
<tr>
<td style="text-align: center;"> </td> <!-- insert arithmetic mean of all Writtentest, inside td-->
<td style="text-align: center;"></td> <!-- insert arithmetic mean of all Essay, inside td-->
<td style="text-align: center;"></td> <!-- insert arithmetic mean of all ClassActivity, inside td-->
</tr>
</tbody>
</table>
<br>
<table border="1">
<tbody>
<tr>
<td style="width:140px; text-align: center;">Arithmetic mean of all grades</td>
</tr>
<tr>
<td style="text-align: center;"> </td> <!-- insert arithmetic mean of all numbers-->
</tr>
</tbody>
</table>
</div>
</body>
<script>
var ocena = 0;
var stranica = document.querySelector("#stranica")
function removeElement(obrisi) {
var dugme = obrisi.target;
stranica.removeChild(dugme.parentElement)
}
function dodajocenu() {
ocena++;
//create textbox
var input = document.createElement('input');
input.type = "number";
input.setAttribute("max",5);
input.setAttribute("min",1);
var myParent = document.body;
//Create array of options to be added
var array = ["Written test","Essay","Class Activity"];
//Create and append select list
var selectList = document.createElement('select');
selectList.id = "mySelect";
myParent.appendChild(selectList);
//Create and append the options
for (var i = 0; i < array.length; i++) {
var option = document.createElement('option');
option.value = array[i];
option.text = array[i];
selectList.appendChild(option);
}
//create remove button
var remove = document.createElement('button');
remove.onclick = function(obrisiocenu) {
removeElement(obrisiocenu);
}
remove.setAttribute("type", "dugme");
remove.innerHTML = "-"; //delete
var item = document.createElement('div')
item.classList.add("item")
item.appendChild(input);
item.appendChild(selectList);
item.appendChild(remove);
stranica.appendChild(item)
}
</script>```
var ocena = 0;
function removeElement(obrisi) {
var dugme = obrisi.target;
document.getElementById("stranica").removeChild(dugme.parentElement)
}
function dodajocenu() {
ocena++;
//create textbox
var input = document.createElement('input');
input.type = "number";
input.setAttribute("max", 5);
input.setAttribute("min", 1);
var myParent = document.body;
//Create array of options to be added
var array = ["Kontrolni", "Vezbe", "Aktivnost"];
//Create and append select list
var selectList = document.createElement('select');
selectList.id = "mySelect";
myParent.appendChild(selectList);
//Create and append the options
for (var i = 0; i < array.length; i++) {
var option = document.createElement('option');
option.value = array[i];
option.text = array[i];
selectList.appendChild(option);
}
//create remove button
var remove = document.createElement('button');
remove.onclick = function(obrisiocenu) {
removeElement(obrisiocenu);
}
remove.setAttribute("type", "dugme");
remove.innerHTML = "-"; //delete
var item = document.createElement('div')
item.classList.add("item")
item.appendChild(input);
item.appendChild(selectList);
item.appendChild(remove);
document.getElementById("stranica").appendChild(item)
}
function calcMean() {
var nameList=document.querySelectorAll('#stranica .item #mySelect');
var inputList=document.querySelectorAll('#stranica .item input');
var kontrolniList = [];
var vezbeList = [];
var aktivnostList = [];
var ocenaList = [];
for(var i=0; i< nameList.length; i++){
ocenaList.push(parseInt(inputList[i].value));
if(nameList[i].value=='Kontrolni') {
kontrolniList.push(parseInt(inputList[i].value));
}
else if(nameList[i].value=='Vezbe') {
vezbeList.push(parseInt(inputList[i].value));
}
else if(nameList[i].value=='Aktivnost') {
aktivnostList.push(parseInt(inputList[i].value));
}
}
document.getElementById("kontrolni").innerHTML=avg(kontrolniList);
document.getElementById("vezbe").innerHTML=avg(vezbeList);
document.getElementById("aktivnost").innerHTML=avg(aktivnostList);
document.getElementById("ocena").innerHTML=avg(ocenaList);
}
function avg( arr ) {
var total = 0, i;
for (i = 0; i < arr.length; i += 1) {
total += arr[i];
}
return total / arr.length;
}
<div id="stranica" style="display: inline-block; position: left;">
<button type="button" onclick="javascript:dodajocenu();"> Dodaj ocenu</button>
</div>
<div id="desna" style="display: inline-block; position: absolute; text-align: center;">
<button type="button" onclick="javascript:calcMean();"> Izracunaj prosek</button>
<br><br>
<table border="1">
<tbody>
<tr>
<td style="width:70px; text-align: center;">Kontrolni</td>
<td style="width:70px; text-align: center;">Vezbe</td>
<td style="width:70px; text-align: center;">Aktivnost</td>
</tr>
<tr>
<td id="kontrolni" style="text-align: center;"> </td>
<td id="vezbe" style="text-align: center;"></td>
<td id="aktivnost" style="text-align: center;"></td>
</tr>
</tbody>
</table>
<br>
<table border="1">
<tbody>
<tr>
<td style="width:140px; text-align: center;">Zakljucna ocena</td>
</tr>
<tr>
<td id="ocena" style="text-align: center;"> </td>
</tr>
</tbody>
</table>
</div>
Hope this will work.

Cannot read property 'childNodes' checkbox to get value from same row

Below code should get me the value of the column next to the checked box in the table, but, once the button is clicked, I am getting:
Cannot read property childNodes of null
Note: database from firebase which where the values from the table come from
Table image :
rootRefReAgents.on("child_added", snap => {
var AgentName = snap.child("Name").val();
$("#table_body_Test").append("<tr><td>" + AgentName + "</td><td><INPUT TYPE=\"Checkbox\"> </Input></td></tr>");
});
}
function ActionData(){
let agents = [];
let table = document.getElementById("table_body_Test");
let childNodes = Array.from(table.childNodes);
// let childNodes = table.childNodes;
for (let child of childNodes.values()) {
console.log(`child: ${child}`);
if (child.constructor.name !== "HTMLTableRowElement") {
continue;
}
let agent = child.childNodes.item(1).innerHTML;
console.log(`agent: ${agent}`);
let checkbox = child.childNodes.item(3).childNodes.item(1);
console.log(`checkbox: ${checkbox}`);
console.log(checkbox.checked);
if (checkbox.checked) {
agents.push(agent);
}
}
console.log(`agents: ${agents}`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="testTable" align="center">
<thead>
<tr style="color: #D2002E; background: #FFCC01; height:32px;">
<td>Agents</td>
<td>Select</td>
</tr>
</thead>
<tbody id="table_body_Test">
</tbody>
</table>
<button id="submitBtn" onclick="ActionData()">Next</button>
ES6 brought new methods that simplify the code and its reading
const tableBody = document.querySelector('#testTable tbody' );
document.querySelector('#submitBtn').onclick=()=>
{
let agents = [];
console.clear();
for (let rowX of tableBody.rows )
{
let
agent = rowX.cells[0].textContent,
checkbox = rowX.cells[1].querySelector('input[type=checkbox]')
;
console.log( 'agent:', agent, 'checked:', checkbox.checked);
if (checkbox.checked) { agents.push(agent); }
}
console.log( 'agents (array):', agents.join(' / '));
}
/// bonus info :
/*
rootRefReAgents.on("child_added", snap=>{
let
newRow = tableBody.insertRow(-1);
newRow.insertCell(0).textContent = snap.child("Name").val();
newRow.insertCell(1).innerHTML = '<input type="Checkbox">';
});
*/
#testTable { margin: auto; border-collapse: collapse }
#testTable thead tr {
color: #D2002E;
background: #FFCC01;
height:32px;
font-weight: bold;
}
#testTable tr:nth-child(even) {background-color: lightgrey }
#testTable td { border:1px solid grey; padding: 0 20px; }
#testTable td:nth-child(2) { text-align: center }
<table id="testTable">
<thead>
<tr> <td>Agents</td> <td>Select</td> </tr>
</thead>
<tbody>
<tr> <td>AMC</td> <td> <input type="checkbox" > </td> </tr>
<tr> <td>Mygulfex</td> <td> <input type="checkbox" > </td> </tr>
<tr> <td>topStar</td> <td> <input type="checkbox" > </td> </tr>
<tr> <td>WMC</td> <td> <input type="checkbox" > </td> </tr>
</tbody>
</table>
<button id="submitBtn" >see Selects in console</button>

Table and mouse rollover effect (hover)

I have this table:
<table border="1">
<tr>
<td></td>
<td>Banana</td>
<td>Orange</td>
<td>Plum</td>
</tr>
<tr>
<td>Banana</td>
<td>1:1</td>
<td>1:2</td>
<td>1:3</td>
</tr>
<tr>
<td>Orange</td>
<td>2:1</td>
<td>1:1</td>
<td>1,5:1</td>
</tr>
<tr>
<td>Plum</td>
<td>1:3</td>
<td>2:1</td>
<td>1:1</td>
</tr>
and CSS:
td {
height:60px;
width:60px;
text-align:center;
}
td:hover{
background-color:red;
}
What I want to do, is when I for example point my mouse on 1:3 table cell, it should highlight together with Banana and Plum cells.
Any easy way to do it?
Here's fiddle:
http://jsfiddle.net/CZEJT/
If you dont mind a bit of Javascript in there to ensure compatibility, take a look at this JSFiddle
HTML:
<table>
<tr>
<th></th><th>50kg</th><th>55kg</th><th>60kg</th><th>65kg</th><th>70kg</th>
</tr>
<tr>
<th>160cm</th><td>20</td><td>21</td><td>23</td><td>25</td><td>27</td>
</tr>
<tr>
<th>165cm</th><td>18</td><td>20</td><td>22</td><td>24</td><td>26</td>
</tr>
<tr>
<th>170cm</th><td>17</td><td>19</td><td>21</td><td>23</td><td>25</td>
</tr>
<tr>
<th>175cm</th><td>16</td><td>18</td><td>20</td><td>22</td><td>24</td>
</tr>
</table>
CSS:
table {
border-spacing: 0;
border-collapse: collapse;
overflow: hidden;
z-index: 1;
}
td, th, .ff-fix {
cursor: pointer;
padding: 10px;
position: relative;
}
td:hover::after,
.ff-fix:hover::after {
background-color: #ffa;
content: '\00a0';
height: 10000px;
left: 0;
position: absolute;
top: -5000px;
width: 100%;
z-index: -1;
}
tr:hover{
background-color: #ffa;
}
}
JS:
function firefoxFix() {
if ( /firefox/.test( window.navigator.userAgent.toLowerCase() ) ) {
var tds = document.getElementsByTagName( 'td' );
for( var index = 0; index < tds.length; index++ ) {
tds[index].innerHTML = '<div class="ff-fix">' + tds[index].innerHTML + '</div>';
};
var style = '<style>'
+ 'td { padding: 0 !important; }'
+ 'td:hover::before, td:hover::after { background-color: transparent !important; }'
+ '</style>';
document.head.insertAdjacentHTML( 'beforeEnd', style );
};
};
firefoxFix();
below is an example from one of my sites (css):
/*when hover over shape 5 dim shape 5*/
#shape5{
opacity:1.0;
filter:alpha(opacity=100);}
#shape5:hover{
opacity:0.4;
filter:alpha(opacity=40);}
/*When hoverover text5 dim shape 5!*/
#text5:hover + #shape5{opacity:0.4;
filter:alpha(opacity=40);}
Hope that helps!!
Oh Also view: How to affect other elements when a div is hovered
would you like something like this?
unfortunately it would be necessary some javascript
HTML
<table border="1">
<tr>
<td></td>
<td id='1'>Banana</td>
<td id='2'>Orange</td>
<td id='3'>Plum</td>
</tr>
<tr>
<td>Banana</td>
<td class='o1'>1:1</td>
<td class='o2'>1:2</td>
<td class='o3'>1:3</td>
</tr>
<tr>
<td>Orange</td>
<td class='o1'>2:1</td>
<td class='o2'>1:1</td>
<td class='o3'>1,5:1</td>
</tr>
<tr>
<td>Plum</td>
<td class='o1'>1:3</td>
<td class='o2'>2:1</td>
<td class='o3'>1:1</td>
</tr>
</table>
JAVASCRIPT
var cells1 = $('.o1');
cells1.on('mouseover', function(){
$($(this).parent().children()[0]).css({background: '#ddd'})
$('#1').css({background: '#ddd'})
})
cells1.on('mouseout', function(){
$($(this).parent().children()[0]).css({background: 'none'})
$('#1').css({background: 'none'})
})
var cells2 = $('.o2');
cells2.on('mouseover', function(){
$($(this).parent().children()[0]).css({background: '#ddd'})
$('#2').css({background: '#ddd'})
})
cells2.on('mouseout', function(){
$($(this).parent().children()[0]).css({background: 'none'})
$('#2').css({background: 'none'})
})
var cells3 = $('.o3');
cells3.on('mouseover', function(){
$($(this).parent().children()[0]).css({background: '#ddd'})
$('#3').css({background: '#ddd'})
})
cells3.on('mouseout', function(){
$($(this).parent().children()[0]).css({background: 'none'})
$('#3').css({background: 'none'})
})
CSS
td {
height:60px;
width:60px;
text-align:center;
}
td:hover{
background-color:red;
}
Try this:
Fiddle
Without changing your html structure or adding any third party library:
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
var tds = document.getElementsByTagName('td');
for (var i = 0; i < tds.length; i++) {
var elem = document.getElementsByTagName('td')[i];
elem.addEventListener('mouseover', function () {
var text = this.innerHTML;
for (var j = 0; j < tds.length; j++) {
var elem2 = document.getElementsByTagName('td')[j];
if (elem2.innerHTML == text) {
elem2.style.background = 'red';
}
}
}, false);
elem.addEventListener('mouseout', function () {
for (var j = 0; j < tds.length; j++) {
var elem2 = document.getElementsByTagName('td')[j];
var text = this.innerHTML;
if (elem2.innerHTML == text) {
elem2.style.background = 'none';
}
}
}, false);
}
}, false);
</script>
I apologise that my answer is only in pseudo code, however I would approach this problem by using javascript (most possibly Jquery). I hope this makes sense...
<table id="tbl"> - so I would give the table an ID
<td onHover="changeHeaderColummns(this)"></td> - then on each of the columns have a jsMethod that fires.
<script>
changeHeaderColumsn(col)
{
var colIndex = col.Index; //get the current column index
var row = GetHeaderRow(); // get the header row
highLightColumn(row, colIndex); //change the colour of the cell
//with the same index in the header
row = getCurrentRow(col.RowIndex); //now get the current row
highlightColumn(row, 0); //change the colour of the cell
//with the index of 0
}
getHeaderRow()
{
return getRow(0);
}
getRow(rowIndex)
{
var table = document.getElementByID("tbl);
return table.rows[rowIndex];
}
highlightColumn(row, colIndex)
{
row[colIndex].style.backgroundcolor = "red";
}
for highlight columns you must use js like this jsfiddler. It's work with jQuery ;)
With code
Using jquery
fiddle: http://jsfiddle.net/itsmikem/CZEJT/12/
Option 1: highlights the cell and just the named fruit cells
$("td").on({
"mouseenter":function(){
$(this).closest("tr").find("td:first-child").css("background","#f99");
var col = $(this).index();
$(this).closest("table").find("tr:first-child").find(String("td:nth-child(" + (col + 1) + ")")).css("background","#f99");
$(this).css("background","#f00");
},
"mouseleave":function(){
$(this).closest("table").find("td,tr").css("background","none");
}
});
Option 2: highlights entire rows and columns that intersect the hovered cell
$("td").on({
"mouseenter": function () {
$(this).closest("tr").css("background", "#f99");
var col = $(this).index();
var myTable = $(this).closest("table");
var rows = $(myTable).find("tr");
$(rows).each(function (ind, elem) {
var sel = String("td:nth-child(" + (col + 1) + ")");
$(this).find(sel).css("background", "#f99");
});
$(this).css("background", "#f00");
},
"mouseleave": function () {
$(this).closest("table").find("td,tr").css("background", "none");
}
});

JavaScript - Traversing the HTML DOM using childNodes causes errors in Non IE browsers

I have the following table being rendered in my browser. It's generated from the server side.
<table id="tblQuestions" class="tblQuestionsContainer" border="0">
<tr>
<td id="1" class="tdQuestion">Are u an indian citizen ?</td>
</tr><tr>
<td><table id="answer-1" border="0">
<tr>
<td><input id="answer-1_0" type="radio" name="answer-1" value="1" /><label for="answer-1_0">Yes</label></td><td><input id="answer-1_1" type="radio" name="answer-1" value="0" /><label for="answer-1_1">No</label></td>
</tr>
</table></td>
</tr><tr>
<td id="2" class="tdQuestion">Do you have a passport ?</td>
</tr><tr>
<td><table id="answer-2" border="0">
<tr>
<td><input id="answer-2_0" type="radio" name="answer-2" value="1" /><label for="answer-2_0">Yes</label></td><td><input id="answer-2_1" type="radio" name="answer-2" value="0" /><label for="answer-2_1">No</label></td>
</tr>
</table></td>
</tr>
</table>
Now I am using the following code in my JavaScript to validate the radio button's checked state.
var tblQuestionBoard=document.getElementById("tblQuestions");
tblAnswer = tblQuestionBoard.rows[1].childNodes[0].childNodes[0]
Now tblAnswer should be an object having the Table with id "answer-1"
In IE, I am getting it. But in Mozilla and rest of the browsers I am getting it as undefined.
How to solve this?
It's because you're using childNodes and whitespaces in the DOM are considered to be text nodes by Firefox et. al but not IE
See this answer for an explanation
My suggestions
1.Set up some wrapper functions that ignore any nodeType other than 1 (ELEMENT_NODE) to do DOM traversing. Something like
function child(elem, index) {
// if index is not supplied, default is 1
// you might be more comfortable making this 0-based
// in which case change i initial assignment value to 0 too
index = index || 1;
// get first child element node of elem
elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
next(elem.firstChild) :
elem.firstChild;
// use the index to move to nth-child element node
for(var i=1; i < index;i++) {
(function() {
return elem = next(elem);
})();
}
return elem;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
and use like so - Working Demo - (Code at the bottom of the answer for reference)
<table id="myTable">
<thead>
...
</thead>
<tbody>
...
</tbody>
</table>
<script type="text/javascript">
child(document.getElementById('myTable'), 2); // will get the tbody
</script>
2.Use getElementbyId(), getElementsByTagName() or getElementsByName() instead of relying on position in the DOM
3.Use a JavaScript library that abstracts away browser differences (jQuery comes highly recommended)
The Demo Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript">
window.onload = function() {
document.getElementById('getCellContents').onclick = getCellContents;
}
function child(elem, index) {
index = index || 1;
elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
next(elem.firstChild) :
elem.firstChild;
for(var i=1; i < index;i++) {
(function() {
return elem = next(elem);
})();
}
return elem;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
function getCellContents() {
var row = parseInt(document.getElementById('row').value, 10);
var column = parseInt(document.getElementById('column').value, 10);
var result;
var color;
var table = document.getElementById('table');
var cells = table.getElementsByTagName('td');
for (var i= 0; i < cells.length; i++) {
(function() {
cells[i].bgColor = '#ffffff';
})();
}
if (row && column) {
var tbody = child(table , 2);
var selectedRow = (row <= tbody.getElementsByTagName("tr").length)? child(tbody, row): null;
var selectedCell = (selectedRow && column <= selectedRow.getElementsByTagName("td").length)? child(selectedRow, column): null;
if (selectedRow && selectedCell) {
selectedCell.bgColor = '#00ff00';
result = selectedCell.innerHTML;
color = '#b7b7b7';
}
else {
result = 'Cell does not exist';
color = '#ff0000';
}
}
else {
result = 'You must provide numeric arguments for Row and Column Number';
color = '#ff0000';
}
var results = document.getElementById('results');
results.innerHTML = result;
results.style.color = color;
}
</script>
<title>DOM Traversal</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
font-family: Verdana, Helvetica, Arial;
font-size: 0.8em;
}
h2 {
text-align:center;
}
table {
border: 1px solid #000;
border-collapse: collapse;
}
th, td {
border: 1px solid #000;
padding: 2px;
}
fieldset {
border: 0;
}
label {
display: block;
width: 120px;
text-align: right;
float: left;
padding-right: 10px;
margin: 5px 0;
}
input {
margin: 5px 0;
}
input.text {
padding: 0 0 0 3px;
width: 172px;
}
input.button {
margin: 15px 0 0 130px;
}
span {
font-weight: bold;
color: #b7b7b7;
}
</style>
</head>
<body>
<h2>Example to demonstrate use of JavaScript DOM traversing wrapper functions</h2>
<div style="margin: 0 auto; width: 600px;">
<fieldset>
<label for="row">Row Number:</label><input id="row" class="text" type="text" /><br/>
<label for="column">Column Number:</label><input id="column" class="text" type="text" /><br/>
<input id="getCellContents" type="button" class="button" value="Get Cell Contents" />
</fieldset>
<p>Results: <span id="results"></span></p>
<table id="table">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>Banana</td>
<td>Apple</td>
<td>Orange</td>
<td>Pineapple</td>
<td>Cranberry</td>
</tr>
<tr>
<td>Monkey</td>
<td>Giraffe</td>
<td>Elephant</td>
<td>Tiger</td>
<td>Snake</td>
</tr>
<tr>
<td>C#</td>
<td>Java</td>
<td>Python</td>
<td>Ruby</td>
<td>Haskell</td>
</tr>
<tr>
<td>France</td>
<td>Spain</td>
<td>Italy</td>
<td>Germany</td>
<td>Netherlands</td>
</tr>
</tbody>
</table>
<p style="font-weight:bold;">The Code:
<pre><code>
<script type="text/javascript">
window.onload = function() {
document.getElementById('getCellContents').onclick = getCellContents;
}
function child(elem, index) {
index = index || 1;
elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
next(elem.firstChild) :
elem.firstChild;
for(var i=1; i < index;i++) {
(function() {
if(elem)
return elem = next(elem);
})();
}
return elem;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
function getCellContents() {
var row = parseInt(document.getElementById('row').value, 10);
var column = parseInt(document.getElementById('column').value, 10);
var result;
var color;
var table = document.getElementById('table');
var cells = table.getElementsByTagName('td');
for (var i= 0; i < cells.length; i++) {
(function() {
cells[i].bgColor = '#ffffff';
})();
}
if (row && column) {
var tbody = child(table , 2);
var selectedRow = (row <= tbody.getElementsByTagName("tr").length)?
child(tbody, row): null;
var selectedCell = (selectedRow && column <= selectedRow.getElementsByTagName("td").length)?
child(selectedRow, column): null;
if (selectedRow && selectedCell) {
selectedCell.bgColor = '#00ff00';
result = selectedCell.innerHTML;
color = '#b7b7b7';
}
else {
result = 'Cell does not exist';
color = '#ff0000';
}
}
else {
result = 'You must provide numeric arguments for Row and Column Number';
color = '#ff0000';
}
var results = document.getElementById('results');
results.innerHTML = result;
results.style.color = color;
}
</script>
</code>
</pre>
</p>
</div>
</body>
</html>

Categories