Forum Moderators: open
I am having a small problem here.
I have a pretty nice script. At least I think so.
But the problem is that I need to get it working perfectly.
Here is what happens.
When I click on a checkbox, the row color changes.....neat....
:D
Then I have a check box at the top to toggle all the checkboxes. When I click on it, all the checkboxes on taht pages are checked.....neat....
:D
BUT......when I use the 'toggle all' checkbox, the background color didn't change...
;(
That makes me very grouchy....can someone make my day by providing a fix pls?
<script type="text/javascript" language="JavaScript">
function getParent(el) {
if (document.all)
while (el.parentElement!= null)
if (el.tagName == 'TR') return el;
else el = el.parentElement;
else if (document.getElementById) {
if (el.nodeType == 1 && el.tagName.toLowerCase() == 'tr') return el;
else return getParent(el.parentNode);
}
}
function setParentTR(e, CSSattr, CSSvalue) {
var el = (e && e.srcElement)? e.srcElement : (e && e.target)? e.target : null;
if (el) {
var which = el.checked;
var parentTR = getParent(el);
parentTR.style[CSSattr] = (which)? CSSvalue : '';
}
}
</script>
<script type="text/javascript" language="JavaScript">
var global=1;
function checkAll(formId, cName, check )
{
if(check==1)
{
for (i=0,n=formId.elements.length;i<n;i++)
if (formId.elements[i].className.indexOf(cName)!=-1)
formId.elements[i].checked = true;
}
if(check==0)
{
for (i=0,n=formId.elements.length;i<n;i++)
if (formId.elements[i].className.indexOf(cName)!=-1)
formId.elements[i].checked = false;
}
}
function toggle()
{
checkAll(document.getElementById('myform'), 'filecheck', global);
if (global==0)
{
global=1;
}
else if(global==1)
{
global=0;
}
}
</script>
<form id="myform"><table width="100%"><tr bgcolor="#CCCCCC" ><td><input type="checkbox" onclick="toggle();"></td>
<td>DATA</td>
<td align="left">DATA2</td><td>TIME</td></tr><tr bgcolor="#F1F1F1" ><td><input type="checkbox" class="filecheck" onclick="setParentTR(event,'background','#D9E9F8')"></td>
<td>DATA1</td><td align="left">DATA1</td><td>Feb 03 2005 (02:29)</td></tr><tr bgcolor="#FFFFFF" ><td><input type="checkbox" class="filecheck" onclick="setParentTR(event,'background','#D9E9F8')"></td>
<td>DATA2</td><td align="left">DATA2</td><td>Feb 03 2005 (03:11)</td></tr><tr bgcolor="#F1F1F1" ><td><input type="checkbox" class="filecheck" onclick="setParentTR(event,'background','#D9E9F8')"></td>
<td>DATA3</td><td align="left">DATA3</td><td>Feb 03 2005 (03:49)</td></tr></table>
</form>
The Bernard Marx solution, of course, is utter perfection.
The best tip is to make use of multiple classNames (appending & removing), rather than modifying each element's style properties directly. This gives greater flexibility, and gets round the problem of how to revert a row's style back to it's unselected state.
The striping of the odd rows (via className), and the event handlers could also be added with script, but I haven't done this.
(Unless I'm missing something) There is no need to pass the event object in a handler - and then query it for its source. It is easier to send the object itself, with the keyword,
[blue]this[/blue]. The global 'state' variable is also not needed. You had a function that got a reference to an element's parent row. I have changed this to
[blue]getAncestor[/blue]. It is now more generic. Making it generic had required the use of regular expressions to cover the case were case should be ignored. Since we no longer need to call [blue]toLowerCase[/blue] on each value string, however, the efficiency is about the same. The HTML has a few changes:
1. Removed:
bgcolor attributes from rows. [color=brown]class="odd"[/color] to the odd (ie not even) rows. [color=brown]id="files"[/color] to table (for stylesheet application) [color=brown]onclick="toggleAll(this);"[/color] [color=brown]onclick="setRow(this)"[/color] -- HTML --
<html>
<head>
<title>checkboxes</title>
<script src="checkboxes.js" type="text/javascript"></script>
<style>
#files tr
{background-color: #F1F1F1;}
#files tr.head
{background-color: #CCCCCC;}
#files tr.odd
{background-color: #FFFFFF;}
#files tr.selected
{background-color: #D9E9F8;}</style>
</head>
<body>
<form id="myform">
<table width="100%" id="files">
<tr class="head" >
<td><input type="checkbox" onclick="toggleAll(this);"></td>
<td>DATA</td>
<td align="left">DATA2</td>
<td>TIME</td>
</tr>
<tr>
<td><input type="checkbox" class="filecheck" onclick="setRow(this)"></td>
<td>DATA1</td>
<td align="left">DATA1</td>
<td>Feb 03 2005 (02:29)</td>
</tr>
<tr class="odd">
<td><input type="checkbox" class="filecheck" onclick="setRow(this)"></td>
<td>DATA2</td>
<td align="left">DATA2</td>
<td>Feb 03 2005 (03:11)</td>
</tr>
<tr>
<td><input type="checkbox" class="filecheck" onclick="setRow(this)"></td>
<td>DATA3</td>
<td align="left">DATA3</td>
<td>Feb 03 2005 (03:49)</td>
</tr>
</table>
</form>
</body>
</html>
-- Script (checkboxes.js) -- *! replace all instances of ¦ with an unbroken pipe character
[color=darkgreen]/* always handy */[/color]
String.prototype.trim = function(){ return this.replace(/^\s*¦\s*$/g,"")}[color=darkgreen]/* Last arg optional - use 'i' or leave out. */[/color]
function getAncestor(elm,prop,val,ignCase)
{
if(val.constructor!= RegExp)
val = new RegExp('\\b'+val+'\\b', ignCase);
while(!(val.test(elm[prop])))
elm = elm.parentNode¦¦elm.parentElement; [color=darkgreen]/* only for IE4 (I think) */[/color]
return elm;
}function setRow(box, select)
{
[color=darkgreen]/* Get fn reference to choose appropriate function,
then call function */[/color]
var classModifier = select? appendClass : removeClass;
classModifier( getAncestor(box,'tagName','tr','i'), 'selected');
row = getAncestor(box,'tagName','tr','i')
}function toggleAll(togBox)
{
var boxes = togBox.form.elements;
var check = togBox.checked;
var box, i=0;
while(box=boxes[i++])
if(box.className == 'filecheck'){
box.checked = check;
setRow(box,check);
}
}function appendClass(elm, appClass)
{
[color=darkgreen]/* only add space if currClass non-empty */[/color]
elm.className += (elm.className? ' ':'') + appClass;
}function removeClass(elm, className)
{
[color=darkgreen]/* Replace className, and surrounding spaces, with a single space;
Trim end (since space may have been added to end) */[/color]
elm.className = elm.className
.replace(new RegExp('\s*'+className+'\s*'),' ')
.trim();
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<style type="text/css">
td{border:2px solid blue;}
tr{background:#fee;}
</style>
<script type="text/javascript">
function rowYourBoat(){
var trs=document.getElementById('tableOne').rows;
for(var i=0;i<trs.length;i++){
if(document.frmOne.elements[i].checked){
trs[i].style.background="#eef";
}else{
trs[i].style.background="#fee";
}
}
}
</script>
</head>
<body>
<form action="" name="frmOne">
<table id="tableOne" onclick="rowYourBoat();">
<tr>
<td><input type="checkbox" /></td><td>data</td><td>data</td>
</tr>
<tr>
<td><input type="checkbox" /></td><td>data</td><td>data</td>
</tr>
<tr>
<td><input type="checkbox" /></td><td>data</td><td>data</td>
</tr>
<tr>
<td><input type="checkbox" /></td><td>data</td><td>data</td>
</tr>
</table>
</form>
</body>
</html>
A little reworking would be req'd to account for the first row/checkbox having different behaviour. Not much though.
The original table is striped, so I'd still apply the striping via className, then change the ELSE branch in your function:
[color=brown]}else{
trs[i].style.background="";[/color] I sometimes worry about response time - and was thinking of taking the bubbling further, so as not to do any looping - but I tried yours with a 200 row table, and there's less than 1/4 second delay even on row 200.
I have to admit, I've always been just the least bit uneasy about using the technique of resetting a property with property="". I realize it is a well-established browser convention, but it doesn't seem to be part of any kind of codified standard, so I sort of feel a nagging wisp of trepidation. Probably unfounded, but there it is.
No sooner than I had finished writing those closing thoughts, I tried background="" on IE. It didn't work. Changing to use backgroundColor, however, does. Which points out why the Star Trek episode was so unrealistic; none of the tribbles featured had any grey hairs (Of course, Bill Gates hadn't yet flunked out of Harvard, at that point, so maybe my antecedants were spared).
1. Tribble fur isn't pigmented, rather the keratin analogue is naturally coloured.
- The varying colours of tribble fur do suggest pigmentation however.
2. Tribbles, much like Alphas in a certain allegorical work by Aldous Huxley, burn brightly, keeping the appearance of youth throughout, then suddenly expire.
3. Ageing tribbles, when they have lost the ability to defend themselves, are immediately set upon, and cannibalized.
4. The entire population was still quite young. Had the episode been longer, we might have indeed have seen grey-haired tribbles, and probably bald ones too. We might also have seen them experiment with various forms of social organization, and express themselves in ever more meaningless forms of popular culture. We certainly would have seen them effectively exterminate themselves by degrading their available resources beyond sustainable limits. However, shortly before this mass extinction, the green ones would have been singled out as "terror-tribbles".
Dynel hair, while extremely resilient to ageing, is no match for the machinations of one Mr. William Gates, upon whom Klingons have nothing.
Tribble longevity is, actually, quite remarkably long. My uncle (whom I'm said to favor, he was the purple one in the bridge scene with Kirk) is still quite active, though he is approaching 90.
Tribbles are predominantly vegetarians, hence their taste for quadro-triticale. I must admit to being a bit of a black sheep in this respect, early on having developed a taste for IBM salesmen.
Oh, and finally, it is we of the magenta hue that are noted for our subversive natures, though, as you might expect, we prefer the term "freedom fighters".
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<style type="text/css">
td{border:2px solid blue;}
tr{background:#fee;}
</style>
<script type="text/javascript">
function rowYourBoat(){
var trs=document.getElementById('tableOne').rows;
for(var i=0;i<trs.length;i++){
if(document.frmOne.elements[i].checked){
trs[i].style.backgroundColor="#eef";
}else{
trs[i].style.backgroundColor="";
}
}
}
function boxCheck(frm,stat){
var frm_el=frm.elements;
var frm_ln=frm_el.length;
for(var i=0;i<frm_ln;i++){
if(frm_el[i].type=="checkbox")frm_el[i].checked=stat;
}
}
</script>
</head>
<body>
<form action="" name="frmOne">
<table id="tableOne" onclick="rowYourBoat();">
<tr>
<td><input type="checkbox" onclick="boxCheck(this.form,this.checked);" /></td><td>data</td><td>data</td>
</tr>
<tr>
<td><input type="checkbox" /></td><td>data</td><td>data</td>
</tr>
<tr>
<td><input type="checkbox" /></td><td>data</td><td>data</td>
</tr>
<tr>
<td><input type="checkbox" /></td><td>data</td><td>data</td>
</tr>
</table>
</form>
</body>
</html>
<tr onmouseover="this.style.backgroundColor='#dbb';" onmouseout="this.style.backgroundColor='';">
<td>data</td>
</tr>
This does beg certain questions if you want to use the effect to toggle, like the checkboxes.
I cooked up a little solution to this. It extends The Tribble Bubble, but doesn't do The Loop - since there's some querying of event objects going on anyway.
I'm sending the URL to all revellers .
Meanwhile, there are 2 solutions that are more specific to the task at hand, and so would require less code.
1. Use Rambo's approach. For the rollovers, we need to temporarily store the current directly applied styling of the element so that it can be re-applied onmouseout. To do this we can either store the initial BG color of the 'moused-over' row in a global variable, or better, for a more OOP approach, use a custom attribute or expando.
2. If all browsers were 'proper' browsers, we could forget BOTH current approaches, and simply add and remove custom attributes. The stylings could then be applied with CSS, using attribute/value selectors. No muss, no fuss.
----
# For one thing, I forgot to escape the backslashes in the RegExp constructor.
You know, like the Beatles tune,". . . mouseover once, mouseover twice! C'mon, baby, it's an I/O device . . . Traveling on the one after Red Hat 9 . . .", or something like that.