How to control highlighted cell with arrow keys - javascript

I have HTML table
When I click on it's cell (not header) this cell is highlighted in red. the rest cells in the same row are highlighted in pink color.
I want to control this red cell using arrow keys.
Here is my HTML code:
<html>
<head>
<title>Table Highlight</title>
</head>
<style>
.highlighted{
color: white;
background-color: red;
}
tr.normal td {
color: black;
background-color: white;
}
.highlighted1 {
color: white;
background-color: pink;
}
</style>
<body onLoad="onLoad()" >
<table id="tbl" border="1">
<tr>
<td style="width:70">Id
<td style="width:70">Name
<td style="width:70">Year
<td style="width:70">Task
</tr>
<tr>
<td style="height:20">
<td style="height:20">
<td style="height:20">
<td style="height:20">
</tr>
<tr>
<td style="height:20">
<td style="height:20">
<td style="height:20">
<td style="height:20">
</tr>
<tr>
<td style="height:20">
<td style="height:20">
<td style="height:20">
<td style="height:20">
</tr>
</table>
<script>
tbl = document.getElementById('tbl');
tbl2 = document.getElementById('tbl');
cnt = 0;
function onLoad() {
td = document.getElementsByTagName('td');
for(j=4;j<td.length;j++){
td[j].innerHTML = " ";
td[j].onclick = function(){highlight(this)}
td[j].onkeydown=function(){key_highlight(event)}
}
}
function key_highlight(oo) {
td = document.getElementsByTagName('td');
for(n=1;i<tbl2.rows;n++){
cnt=0;
/*
if(cnt > tbl2[i].cells.length) return;
highlight(tbl2[i]);
}*/
alert();
//if(oo.keyCode==39)
if(cnt>tbl2.rows[n].cells.length) return;
highlight(tbl2[n].cells);
cnt++;
}
}
function highlight(o) {
for (i=0; i<tbl.cells.length; i++){
tbl.cells[i].className="normal";
tbl.cells[i].parentNode.className="normal";
}
o.parentNode.className = (o.className == "highlighted1")?"normal":"highlighted1";;
o.className=(o.className == "highlighted")?"normal":"highlighted";
}
</script>
</body>

You need to check for keycode on keydown event for the document and apply "highlighted" class to respective td.
HTML :
<table id="tbl" border="1">
<tr>
<td style="width:70" class="highlighted">Id</td>
<td style="width:70">Name</td>
<td style="width:70">Year</td>
<td style="width:70">Task</td>
</tr>
<tr>
<td style="height:20"> 1</td>
<td style="height:20"> Bob</td>
<td style="height:20"> 1998</td>
<td style="height:20"> NA</td>
</tr>
<tr>
<td style="height:20">2</td>
<td style="height:20">Maz</td>
<td style="height:20">2000</td>
<td style="height:20">QA</td>
</tr>
<tr>
<td style="height:20">3</td>
<td style="height:20">Mary</td>
<td style="height:20">1999</td>
<td style="height:20">Code</td>
</tr>
</table>
Jquery code:
var active;
$(document).keydown(function(e){
active = $('td.highlighted').removeClass('highlighted');
var x = active.index();
var y = active.closest('tr').index();
if (e.keyCode == 37) {
x--;
}
if (e.keyCode == 38) {
y--;
}
if (e.keyCode == 39) {
x++
}
if (e.keyCode == 40) {
y++
}
active = $('tr').eq(y).find('td').eq(x).addClass('highlighted');
});
Refer to fiddle for live Demo

You have to keep track of cell position (cellX,cellY) both when you click and when you press a key. Add a global keypress handler (document.onkeydown = ) and increment or decrement cellX and cellY according to the keys pressed.
Chech the running fiddle:
http://jsfiddle.net/aehq9c6f/1/
tbl = document.getElementById('tbl');
tbl2 = document.getElementById('tbl');
var cellX=null;
var cellY=null;
document.onkeydown = keyPressed;
cnt = 0;
function onLoad() {
td = document.getElementsByTagName('td');
for(j=4;j<td.length;j++){
td[j].innerHTML = " ";
td[j].onclick = function(){highlight(this)}
td[j].onkeydown=function(){key_highlight(event)}
}
}
function keyPressed(e) {
var code;
if (!e) var e = window.event;
if (e.keyCode) code = e.keyCode;
else if (e.which) code = e.which;
var KeyVal=getCharDesc(code);
var maxX=4;
var maxY=4;
if(KeyVal=="left") {
if(cellX===null) cellX=maxX;
if(cellY===null) cellY=maxY/2;
cellX--;
if(cellX<0) cellX=maxX-1;
highlight(tbl.rows[cellY].cells[cellX]);
} else if(KeyVal=="right") {
if(cellX===null) cellX=-1;
if(cellY===null) cellY=maxY/2;
cellX++;
if(cellX>maxX-1) cellX=0;
highlight(tbl.rows[cellY].cells[cellX]);
} else if(KeyVal=="up") {
if(cellX===null) cellX=maxX/2;
if(cellY===null) cellY=maxY;
cellY--;
if(cellY<1) cellY=maxY-1; // avoid top row
highlight(tbl.rows[cellY].cells[cellX]);
} else if(KeyVal=="down") {
if(cellX===null) cellX=maxX/2;
if(cellY===null) cellY=0; // avoid top row
cellY++;
if(cellY>maxY-1) cellY=1; // avoid top row
highlight(tbl.rows[cellY].cells[cellX]);
}
}
function getCharDesc(char_code) {
switch(char_code) {
case 37:return "left";
case 38:return "up";
case 39:return "right";
case 40:return "down";
}
}
function highlight(o) {
for (var i = 0, row; row = tbl.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
row.cells[j].className="normal";
row.cells[j].parentNode.className="normal";
if(row.cells[j]===o) {
cellX=j;
cellY=i;
// alert(cellX+", "+cellY);
}
}
}
o.parentNode.className = (o.className == "highlighted1")?"normal":"highlighted1";;
o.className=(o.className == "highlighted")?"normal":"highlighted";
}
The extra tests like
if(cellX===null) ...
are to allow first keypress if nothing is selected (cellX and cellY are null), if you hit left, cursor will start from right, etc.. (window must have focus so first click window to test).
I changed tbl.cells[i] to tbl.rows[i].cells[j] because on my setup (Firefox) table.cells[..] was not defined

Related

Border around specific set of cells

I have done the component with table like this.
The problem is, when user chooses a range of cell like this, how can i put the border around that groups( the border likes the first one in group of cells) ?
I tried to use different class for each cell's border style, but it seems imposible, because i dont know which cell user will pick, how big the group of cell's size will be
Thank a lot and sorry about my English
Had the same task this week and sadly the question did not hold any answer, except for external libraries. So here is my approach.
In the following example I am using the class Marked to mark the cells as being selected and the dataset to flag which cells define which outer bound(s).
;window.onload = (event) => {
//REM: Assign mousedown event
document.querySelector('table').addEventListener('mousedown',_onMouseDownTable, false)
};
/***
* MouseDown event for the table, handles cells
*/
function _onMouseDownTable(event){
//REM: Checking for 'td'...
if(
event.target &&
event.target.tagName.toLowerCase() === 'td'
){
const tObject = {Down: event.target};
//REM: ...add event for marking cells
this.onmousemove = ((object, event) => {
if(
event.target &&
event.target.tagName.toLowerCase() === 'td'
){
object.Move = event.target
}
else{
delete object.Move
};
_markCells(object.Down, object.Move)
}).bind(null, tObject);
//REM: ...add event for finish marking cells
this.onmouseleave = this.onmouseup = ((object, event) => {
this.onmouseleave = this.onmousemove = this.onmouseup = null;
}).bind(null, tObject)
}
};
/***
* Marks cells between cell a and cell b
*/
function _markCells(a, b){
if(a && b){
//REM: Table of a (thus usually b)
const tTable = a.closest('table');
//REM: Remove existing marks and border data
tTable.querySelectorAll('td.Marked, td[data-bounds-left], td[data-bounds-right], td[data-bounds-top], td[data-bounds-bottom]').forEach((td) => {
td.classList.remove('Marked');
delete td.dataset.boundsLeft;
delete td.dataset.boundsRight;
delete td.dataset.boundsTop;
delete td.dataset.boundsBottom
});
//REM: The lowest (top to bottom / left to right) and the largest coordinate
const
tMaxColumn = Math.max(Number(a.dataset.columnIndex), Number(b.dataset.columnIndex)),
tMaxRow = Math.max(Number(a.dataset.rowIndex), Number(b.dataset.rowIndex)),
tMinColumn = Math.min(Number(a.dataset.columnIndex), Number(b.dataset.columnIndex)),
tMinRow = Math.min(Number(a.dataset.rowIndex), Number(b.dataset.rowIndex));
//REM: Mark all cells between Min and Max
for(let row = tMinRow; row <= tMaxRow; row++){
for(let column = tMinColumn; column <= tMaxColumn; column++){
const tCell = tTable.querySelector(`td[data-row-index='${row}'][data-column-index='${column}']`);
if(tCell){
//REM: If outer left bound...
if(column === tMinColumn){
tCell.dataset.boundsLeft = true
};
//REM: If outer right bound...
if(column === tMaxColumn){
tCell.dataset.boundsRight = true
};
//REM: If outer top bound...
if(row === tMinRow){
tCell.dataset.boundsTop = true
};
//REM: If outer bottom bound...
if(row === tMaxRow){
tCell.dataset.boundsBottom = true
};
//REM: Set cell as marked
tCell.classList.add('Marked')
}
}
}
}
};
td{
border: 2px solid #000;
background-color: grey;
height: 25px;
width: 200px;
}
td.Marked{
background-color: #1e90ff
}
td.Marked[data-bounds-left]{
border-left-color: red
}
td.Marked[data-bounds-right]{
border-right-color: red
}
td.Marked[data-bounds-top]{
border-top-color: red
}
td.Marked[data-bounds-bottom]{
border-bottom-color: red
}
<table>
<tbody>
<tr>
<td data-column-index="0" data-row-index="0"></td>
<td data-column-index="1" data-row-index="0"></td>
<td data-column-index="2" data-row-index="0"></td>
<td data-column-index="3" data-row-index="0"></td>
<td data-column-index="4" data-row-index="0"></td>
</tr>
<tr>
<td data-column-index="0" data-row-index="1"></td>
<td data-column-index="1" data-row-index="1"></td>
<td data-column-index="2" data-row-index="1"></td>
<td data-column-index="3" data-row-index="1"></td>
<td data-column-index="4" data-row-index="1"></td>
</tr>
<tr>
<td data-column-index="0" data-row-index="2"></td>
<td data-column-index="1" data-row-index="2"></td>
<td data-column-index="2" data-row-index="2"></td>
<td data-column-index="3" data-row-index="2"></td>
<td data-column-index="4" data-row-index="2"></td>
</tr>
<tr>
<td data-column-index="0" data-row-index="3"></td>
<td data-column-index="1" data-row-index="3"></td>
<td data-column-index="2" data-row-index="3"></td>
<td data-column-index="3" data-row-index="3"></td>
<td data-column-index="4" data-row-index="3"></td>
</tr>
<tr>
<td data-column-index="0" data-row-index="4"></td>
<td data-column-index="1" data-row-index="4"></td>
<td data-column-index="2" data-row-index="4"></td>
<td data-column-index="3" data-row-index="4"></td>
<td data-column-index="4" data-row-index="4"></td>
</tr>
</tbody>
</table>
Note that this is just a draft and not a finished solution, since it depends heavily on the already existing implementation and use-case.

Javascript, Cycle trough 3 classes in a single td tag

I am using simple html and inlay js + css to create a simple site that just tracks wether a worker is at work or not (by simply clicking on a td with their name), thing is I never worked with js and after a day of reading documentations and looking up stackoverflow and w3schools, I can't get my code running.
My problem is whenever i try to click on a td the background color doesnt change and when I got a solution the whole table background color changed, but I want a single td at a time, can anyone help me?
so far i got:
<script language=javascript type="text/javascript">
var el
function colCell() {
if (typeof event !== 'undefined')
el = event.srcElement;
elements = document.getElementsByTagName('td');
if (el.style.backgroundColor == "#E5F0F8")
{
el.style.backgroundColor = "#0066bb"
el.style.color ="#ffffff"
}
else if (el.style.backgroundColor == "#0066bb")
{
el.style.backgroundColor = "#ff00ff"
el.style.color = "#ffffff"
}
else
{
el.style.backgroundColor = "#E5F0F8"
el.style.color = "#000000"
}
}
if (window.addEventListener)
window.addEventListener('click', function(e) {
el = e.target
}, true)
</script>
With this table :
<div class="contentSection">
<table class="awht2">
<tr>
<td colspan="5" class="line">LCS</td>
</tr>
<tr>
<td onclick="colCell()" style="background-color: #E5F0F8;">
TestFarbe
</td>
Consider the td and tr repeated a few times.
sorry for being so noob'ish this is my first project with js and html
Some improvements here and there:
<script language=javascript type="text/javascript">
var el
function colCell(el) {
elements = document.getElementsByTagName('td');
if (el.style["background-color"] == "rgb(229, 240, 248)")
{
el.style["background-color"] = "#0066bb"
el.style.color ="#ffffff"
}
else if (el.style["background-color"] == "rgb(0, 102, 187)")
{
el.style["background-color"] = "#ff00ff"
el.style.color = "#ffffff"
}
else
{
el.style["background-color"] = "#E5F0F8"
el.style.color = "#000000"
}
}
/*if (window.addEventListener)
window.addEventListener('click', function(e) {
el = e.target
}, true)*/
</script>
<div class="contentSection">
<table class="awht2">
<tr>
<td colspan="5" class="line">LCS</td>
</tr>
<tr>
<td onclick="colCell(this)" style="background-color: #E5F0F8;">
TestFarbe
</td>
<td onclick="colCell(this)" style="background-color: #E5F0F8;">
TestFarbe2
</td>
<td onclick="colCell(this)" style="background-color: #E5F0F8;">
TestFarbe3
</td>
<td onclick="colCell(this)" style="background-color: #E5F0F8;">
TestFarb4
</td>
<td onclick="colCell(this)" style="background-color: #E5F0F8;">
TestFarbe5
</td>
</tr>
</table>
</div>
you do not need to have a window event, you can pass this to the function.
var cells = document.getElementsByTagName('td');
for(var i =0;i<cells.length;i++){
cells[i].addEventListener('click',function(e){
e.target.classList.toggle('gray');
e.target.classList.toggle('blue');
},false)
}
td {
background-color: #E5F0F8;
color:#000000;
}
.blue{
background-color:#0066bb;
color:#ffffff;
}
<div class="contentSection">
<table class="awht2">
<tr>
<td colspan="5" class="line">LCS</td>
</tr>
<tr>
<td>
TestFarbe
</td>
</tr>
</table>
</div>
Pass the event object with colCell(). Then use window.getComputedStyle to get the current back ground color. This will be in rgb. Convert this rgb to hex and then use the element.style.property , where element is the target from which event originated & property is any css property
function colCell(e) {
let target = event.target;
// the background color will be in rgb . In that this snippet is
// considering only integers and replacing characters and
// special characters with empty string. Then using filter to
// get only the values which are not empty
let x = window.getComputedStyle(target).backgroundColor.replace(/[^0-9]/g, ' ').trim().split(' ').filter(e => e !== "");
let getHex = rgbToHex(+x[0], +x[1], +x[2]).toUpperCase()
if (getHex === "#E5F0F8") {
target.style.backgroundColor = "#0066bb"
target.style.color = "#ffffff"
} else if (el.style.backgroundColor === "#0066bb") {
target.style.backgroundColor = "#ff00ff"
target.style.color = "#ffffff"
} else {
target.style.backgroundColor = "#E5F0F8"
target.style.color = "#000000"
}
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(229) + componentToHex(240) + componentToHex(248);
}
<div class="contentSection">
<table class="awht2">
<tr>
<td colspan="5" class="line">LCS</td>
</tr>
<tr>
<td onclick="colCell(event)" style="background-color: #E5F0F8;">
TestFarbe
</td>
</table>
</div>
I have used code fro rgb to hex conversion

filtering a html table based on a condition entered in textbox javascript

i have a html table that displays student name and the number of leaves he has taken.how do i filter giving a constraint on the no of leaves and display it
,like if enter 5 in the text box,students with leave of 5 or more should be filtered and displayed.
the code i have now display the records with the entered value
function myFunction1() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput1");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[6];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
A jQuery version
var filter = $('#myInput1').val.toUpperCase();
$("#myTable tr td:eq(6)").each( function() {
var str = $(this).html().toUpperCase()
if( str.indexOf(filter) > -1)
$(this).parent('tr').css('display','')
else
$(this).parent('tr').css('display','none')
})
quick knock-together that does what you're looking for, from what I can understand. I have also used the same filter function to allow me to screen by name or by student-year. It's a flexible filter routine, wish I'd taken the time to avoid hard-wiring the handling of strings vs numbers, but for your purposes, that'd be overkill, I think.
A strange gotcha with table rows: you can't simply display="none" and display="block" them, it garbles the table structure. That's why it's display="none and display="" below. A few sources pointed that out, and I'm glad they did. I was beating my head on that wall for a while...
Best of luck!
// Store all the inputs...
var filterByName = document.getElementById("filter-by-name");
var filterByYear = document.getElementById("filter-by-year");
var filterByLeaves = document.getElementById("filter-by-leaves");
// And store the table itself.
var studentInfoTable = document.getElementsByClassName("student-info")[0];
// these functions will be called in the event listeners.
// By doing this, I only have a single filter function.
function byName() {
var filterString = filterByName.value;
filterBy("name", filterString);
};
function byYear() {
var filterString = filterByYear.value;
filterBy("year", filterString);
};
function byLeaves() {
var filterString = filterByLeaves.value;
filterBy("leaves", filterString);
};
/**
* The filter function itself, accepts the field to filter
* by and the string to use as the filter data.
* In essence, we take each row of the body, find the td
* to filter by, compare that with the filter data itself.
* There are two types of compare: either text or numeric.
*
**/
function filterBy(filter, filterString) {
var selector = ".student-" + filter;
var rows = studentInfoTable.querySelectorAll("tbody tr");
for (var i = 0; i < rows.length; i++) {
var filterEl = rows[i].querySelector(selector);
switch(filter) {
case "name":
if (filterEl.textContent.indexOf(filterString) == -1) {
rows[i].style.display = "none";
} else {
rows[i].style.display = "";
};
break;
case "year":
case "leaves":
if (parseInt(filterEl.textContent) >= parseInt(filterString) || filterString.length == 0) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
};
break;
}
}
};
// The event listeners for each input.
filterByName.addEventListener("keyup", byName);
filterByYear.addEventListener("keyup", byYear);
filterByLeaves.addEventListener("keyup", byLeaves);
.student-info {
font-family: Arial, sans-serif;
width: 100%;
table-layout: fixed;
}
thead {
font-weight: bold;
}
label {
display: block;
}
.student-name {
width: 40%;
}
.student-id,
.student-year,
.student-leaves {
width: 20%;
text-align: center;
}
<table class="student-info">
<thead>
<td class="student-name">Name</td>
<td class="student-id">S. Id</td>
<td class="student-year">Year</td>
<td class="student-leaves">Leaves</td>
</thead>
<tbody>
<tr>
<td class="student-name">Abraham Abas</td>
<td class="student-id">00141</td>
<td class="student-year">2018</td>
<td class="student-leaves">4</td>
</tr>
<tr>
<td class="student-name">Billy Bragg</td>
<td class="student-id">00143</td>
<td class="student-year">2018</td>
<td class="student-leaves">7</td>
</tr>
<tr>
<td class="student-name">Conor Chace</td>
<td class="student-id">00147</td>
<td class="student-year">2019</td>
<td class="student-leaves">5</td>
</tr>
<tr>
<td class="student-name">Daniel Daye</td>
<td class="student-id">00150</td>
<td class="student-year">2019</td>
<td class="student-leaves">0</td>
</tr>
<tr>
<td class="student-name">Edward Eppington</td>
<td class="student-id">00151</td>
<td class="student-year">2018</td>
<td class="student-leaves">6</td>
</tr>
<tr>
<td class="student-name">Frank Ford</td>
<td class="student-id">00153</td>
<td class="student-year">2020</td>
<td class="student-leaves">9</td>
</tr>
</tbody>
</table>
<div class="student-filter">
<h2>
Filter by...
</h2>
<label>Name:
<input type="text" id="filter-by-name">
</label>
<label>Year:
<input type="text" id="filter-by-year">
</label>
<label>Leaves:
<input type="text" id="filter-by-leaves">
</label>
</div>
Search Textbox:-
<label>Search:<input class="form-control input-sm" placeholder="" aria-controls="DataTables_Table_0" type="search" id="txtSearch" onkeyup="filter(this);"></label>
Script:-
function filter(element) {
var value = $(element).val();
$("#DataTables_Table_1 tr").each(function () {
if ($(this).text().search(value) > -1) {
$(this).show();
}
else {
$(this).hide();
}
});
}

Count ++ and -- doesn't work

I'm trying to create a function that when a user clicks on a td element of a table with the class "n" the counter goes one up.
However, upon the click of the td element, it also gets asigned the class "selected". So what I'm trying to do is when a user clicks again on the element with the class "selected" the counter goes -1.
Basically it should work like a toggle that once its cliked, its +1 and clicked again and it goes -1. I have tried this function but it doesn't work.
The code below is my function:
$('#plan td')
.bind('click',function(event) {
if ($(this).hasClass("n"))
count +=1;
}).bind('click',function(event) {
if ($(this).hasClass("selected"))
count -=1;
$('.msg span.count').html(count);
});
This is resposnible for assigning the class "selected":
$('#plan td.n').click(function(){
if (!$(this).hasClass("taken"))
if ($(this).hasClass("selected") || $(".selected").length < 4)
$(this).toggleClass("selected");
});
This is the html part:
<div id='plan'>
<table>
<tr>
<td class='n' id='_1a'>T</td>
<td class='n' id='_1b'>F</td>
<td class='n' id='_1c'>T</td>
<td>1</td>
<td class='n' id='_1d'>T</td>
<td class='n' id='_1e'>F</td>
<td class='n' id='_1f'>T</td>
</tr>
</table>
</div>
You're spreading out your work far too thin. All of this can be handled in one handler.
$('#plan .n').click(function() {
var $this = $(this);
if ($this.hasClass('selected') || $('.selected').length < 4) {
$this.toggleClass('selected');
}
if ($this.hasClass('selected')) {
count -= 1;
} else {
count += 1;
}
$('.msg span.count').html(count);
});
you can change you javascript this way
var count = 0;
$('#plan td')
.bind('click', function(event) {
if ($(this).hasClass("selected")) {
count -= 1;
$(this).removeClass("selected");
} else if ($(".selected").length < 4) {
count += 1;
$(this).addClass("selected");
}
$('.msg span.count').html(count);
})
JSFiddle
This can be simplified to:
$('.n').click(function(){
var cnt = $('#cnt').text();
$(this).toggleClass('selected');
if( $(this).hasClass('selected') ){
cnt ++;
} else{
cnt --;
}
$('#cnt').text(cnt);
});
HTML:
<div id='plan'>
<table>
<tr>
<td class='n' id='_1a'>T</td>
<td class='n' id='_1b'>F</td>
<td class='n' id='_1c'>T</td>
<td>1</td>
<td class='n' id='_1d'>T</td>
<td class='n' id='_1e'>F</td>
<td class='n' id='_1f'>T</td>
</tr>
</table>
</div>
<span id="cnt">0</span>
JSFiddle

Pure Javascript: onClick toggle rows/ image: Firefox/Chrome - works: IE - does not work

Got some great help from Zeb Rawnsley (you rock!) on resolving the preceding question to my current issue.
Working with some code to allow subordinate rows to be hidden via a collapsible link behind an image. This works perfectly fine in Firefox and Chrome but the image does not alternate after the first iteration in IE (IE 8 specifically my company's standard).
The section of interest is here (I think):
var closedImgHTML = "<img name=\"togglepicture\" src=\"http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_closed_folder.png\" border=\"0\" height=\"50\">";
var openImgHTML = "<img name=\"togglepicture\" src=\"http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_open_folder.png\" border=\"0\" height=\"50\">";
and possibly here (but I don't think so):
lnk.innerHTML =(lnk.innerHTML == openImgHTML)?closedImgHTML:openImgHTML;
This CodePen is for the working version (Firefox/Chrome):
http://codepen.io/anon/pen/yjLvh
This is the HTML for the working version:
<html>
<head>
<style type="text/css">
table { empty-cells: show; }
cell {font-family:'Calibri';font-size:11.0pt;color: #000000;}
TD{font-family: Calibri; font-size: 10.5pt;}
TH{font-family: Calibri; font-size: 10.5pt; }
</style>
</head>
<body>
<SCRIPT type=text/javascript>
var tbl;
var toggleimage=new Array("http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_open_folder.png","http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_closed_folder.png")
var closedImgHTML = "<img name=\"togglepicture\" src=\"http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_closed_folder.png\" border=\"0\" height=\"50\">";
var openImgHTML = "<img name=\"togglepicture\" src=\"http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_open_folder.png\" border=\"0\" height=\"50\">";
function trim(str){
return str.replace(/^\s*|\s*$/g,"");
}
function getParent(el, pTagName) {
if (el == null) return null;
else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) // Gecko bug, supposed to be uppercase
return el;
else
return getParent(el.parentNode, pTagName);
}
function toggleSection(lnk){
var td = lnk.parentNode;
var table = getParent(td,'TABLE');
var len = table.rows.length;
var tr = getParent(td, 'tr');
var rowIndex = tr.rowIndex;
var rowHead=table.rows[rowIndex].cells[1].innerHTML;
lnk.innerHTML =(lnk.innerHTML == openImgHTML)?closedImgHTML:openImgHTML;
vStyle =(tbl.rows[rowIndex+1].style.display=='none')?'':'none';
for(var i = rowIndex+1; i < len;i++){
if (table.rows[i].cells[1].innerHTML==rowHead){
table.rows[i].style.display= vStyle;
table.rows[i].cells[1].style.visibility="hidden";
}
}
}
function toggleRows(){
tables =document.getElementsByTagName("table");
for(i =0; i<tables.length;i++){
if(tables[i].className.indexOf("expandable") != -1)
tbl =tables[i];
}
if(typeof tbl=='undefined'){
alert("Could not find a table of expandable class");
return;
}
//assume the first row is headings and the first column is empty
var len = tbl.rows.length;
var link =''+closedImgHTML+'';
var rowHead = tbl.rows[1].cells[1].innerHTML;
for (j=1; j<len;j++){
//check the value in each row of column 2
var m = tbl.rows[j].cells[1].innerHTML;
if(m!=rowHead || j==1){
rowHead=m;
tbl.rows[j].cells[0].innerHTML = link;
// tbl.rows[j].cells[0].style.textAlign="center";
tbl.rows[j].style.background = "#FFFFFF";
}
else
tbl.rows[j].style.display = "none";
}
}
var oldEvt = window.onload;
var preload_image_1=new Image()
var preload_image_2=new Image()
preload_image_1.src=toggleimage[0]
preload_image_2.src=toggleimage[1]
var i_image=0
function testloading() {
isloaded=true
}
function toggle() {
if (isloaded) {
document.togglepicture.src=toggleimage[i_image]
}
i_image++
if (i_image>1) {i_image=0}
}
window.onload = function() { if (oldEvt) oldEvt(); toggleRows(); testloading();}
</SCRIPT>
<TABLE class=expandable width="400px" border="1" cellspacing="0" frame="box" rules="all" >
<THEAD>
<TR>
<TH bgColor="#E6E4D4"> </TH>
<TH bgColor="#E6E4D4" align="left">Manager</TH>
<TH bgColor="#E6E4D4" align="left">Sales Rep</TH>
<TH bgColor="#E6E4D4" align="left">Amount </TH></TR>
</THEAD>
<TBODY>
<TR>
<TD> </TD>
<TD>Sarah Jones</TD>
<TD><i>Georgia District Reps</i></TD>
<TD>500000</TD></TR>
<TR>
<TD> </TD>
<TD>Sarah Jones</TD>
<TD>Rex Smtih</TD>
<TD>350000</TD></TR>
<TR>
<TD> </TD>
<TD>Sarah Jones</TD>
<TD>Alex Anderson</TD>
<TD>150000</TD></TR>
<TR>
<TD> </TD>
<TD>William Hobby</TD>
<TD><i>Texas District Reps</i></TD>
<TD>630000</TD></TR>
<TR>
<TD> </TD>
<TD>William Hobby</TD>
<TD>Bill Smith</TD>
<TD>410000</TD></TR>
<TR>
<TD> </TD>
<TD>William Hobby</TD>
<TD>Simon Wilkes</TD>
<TD>220000</TD></TR>
</TBODY></font></TABLE>
<br>
<br>
</body>
</html>
The prior set of code without the images (using text for open/close) worked fine in all browsers.
Not sure if there is an image syntax issue in IE or something else. It most certainly is focused on the images since, well, it works fine without images.
Here is the CodePen for the version (text based) working in IE (and others).
http://codepen.io/anon/pen/morpF
Here is the HTML for the "ALL" browser version"
<html>
<head>
<style type="text/css">
table { empty-cells: show; }
cell {font-family:'Calibri';font-size:11.0pt;color: #000000;}
TD{font-family: Calibri; font-size: 10.5pt;}
TH{font-family: Calibri; font-size: 10.5pt; }
</style>
</head>
<body>
<SCRIPT type=text/javascript>
var tbl;
function trim(str){
return str.replace(/^\s*|\s*$/g,"");
}
function getParent(el, pTagName) {
if (el == null) return null;
else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) // Gecko bug, supposed to be uppercase
return el;
else
return getParent(el.parentNode, pTagName);
}
function toggleSection(lnk){
var td = lnk.parentNode;
var table = getParent(td,'TABLE');
var len = table.rows.length;
var tr = getParent(td, 'tr');
var rowIndex = tr.rowIndex;
var rowHead=table.rows[rowIndex].cells[1].innerHTML;
lnk.innerHTML =(lnk.innerHTML == "+")?"--":"+";
vStyle =(tbl.rows[rowIndex+1].style.display=='none')?'':'none';
for(var i = rowIndex+1; i < len;i++){
if (table.rows[i].cells[1].innerHTML==rowHead){
table.rows[i].style.display= vStyle;
table.rows[i].cells[1].style.visibility="hidden";
}
}
}
function toggleRows(){
tables =document.getElementsByTagName("table");
for(i =0; i<tables.length;i++){
if(tables[i].className.indexOf("expandable") != -1)
tbl =tables[i];
}
if(typeof tbl=='undefined'){
alert("Could not find a table of expandable class");
return;
}
//assume the first row is headings and the first column is empty
var len = tbl.rows.length;
var link ='+';
var rowHead = tbl.rows[1].cells[1].innerHTML;
for (j=1; j<len;j++){
//check the value in each row of column 2
var m = tbl.rows[j].cells[1].innerHTML;
if(m!=rowHead || j==1){
rowHead=m;
tbl.rows[j].cells[0].innerHTML = link;
// tbl.rows[j].cells[0].style.textAlign="center";
tbl.rows[j].style.background = "#FFFFFF";
}
else
tbl.rows[j].style.display = "none";
}
}
var oldEvt = window.onload;
window.onload = function() { if (oldEvt) oldEvt(); toggleRows();}
</SCRIPT>
<TABLE class=expandable width="400px" border="1" cellspacing="0" frame="box" rules="all" >
<THEAD>
<TR>
<TH width="10%" bgColor="#E6E4D4"> </TH>
<TH bgColor="#E6E4D4" align="left">Manager</TH>
<TH bgColor="#E6E4D4" align="left">Sales Rep</TH>
<TH bgColor="#E6E4D4" align="left">Amount </TH></TR></THEAD>
<TBODY>
<TR class="cell">
<TD> </TD>
<TD>Sarah Jones</TD>
<TD>&nbsp</TD>
<TD>500000</TD></TR>
<TR>
<TD> </TD>
<TD>Sarah Jones</TD>
<TD>Rex Smtih</TD>
<TD>350000</TD></TR>
<TR>
<TD> </TD>
<TD>Sarah Jones</TD>
<TD>Alex Anderson</TD>
<TD>150000</TD></TR>
<TR>
<TD> </TD>
<TD>William Jones</TD>
<TD> </TD>
<TD>620000</TD></TR>
<TR>
<TD> </TD>
<TD>William Jones</TD>
<TD>Bill Smith</TD>
<TD>410000</TD></TR>
<TR>
<TD> </TD>
<TD>William Jones</TD>
<TD>Simon Wilkes</TD>
<TD>220000</TD></TR>
</TBODY></font></TABLE></body>
</html>
Thanks!
Different browsers serialize the DOM differently. Running your code in IE10 gives me this:
foo.innerHTML = "<img name=\"togglepicture\" src=\"http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_open_folder.png\" border=\"0\" height=\"50\">";
foo.innerHTML; // <img name="togglepicture" height="50" src="http://www.iconlooker.com/user-content/uploads/wall/thumb/misc._icons_open_folder.png" border="0">
IE rearranged the attributes, so you no longer have the same string.
Instead of getting the HTML inside the link element, get the image itself and look at its src property.

Categories

Resources