Select element with no selected options

T

TJ Walls

Hello All,

Is it possible to create a <select> element with no selected options? I
have tried setting the selectedIndex attribute to -1, but as far as I can
tell this only works for <select multiple> elements.

Am I missing something obvious?

Sincerely,
TJ Walls
Ph.D. Candidate - Stony Brook University
 
M

Michael Winter

Is it possible to create a <select> element with no selected options?

By not giving any OPTION elements the selected attribute, it is possible
for a user agent to initially have no initial value. However, for whatever
reason, most do select the first.
I have tried setting the selectedIndex attribute to -1, but as far as I
can tell this only works for <select multiple> elements.

Works for me in IE, Opera, and Firefox.
Am I missing something obvious?

Perhaps. What exactly are you trying to acheive?

Mike
 
P

Philip Ronan

TJ said:
Hello All,

Is it possible to create a <select> element with no selected options? I
have tried setting the selectedIndex attribute to -1, but as far as I can
tell this only works for <select multiple> elements.

Am I missing something obvious?

You can if you like, but it would be pointless.

Take a look at the HTML specs:
If no OPTION element has the selected attribute set, user agent behavior
for choosing which option is initially selected is undefined.

How about adding <OPTION selected> </OPTION> to the start of your options
list?
 
F

Fred Oz

TJ said:
Hello All,

Is it possible to create a <select> element with no selected options? I

User agent behaviour for an option list with nothing selected is
undefined, so if you do achieve it I suggest the results will be
unpredictable across different browsers.

The HTML specification says that you should ensure that one option is
selected - if none have the "selected" attribute, then the first option
should be selected.
have tried setting the selectedIndex attribute to -1, but as far as I can
tell this only works for <select multiple> elements.

This is a bad idea, as above.
Am I missing something obvious?

Yes, the w3c HTML spec explicitly says don't do it:

<URL:http://www.w3.org/TR/REC-html40/interact/forms.html>


*17.6.1)*
"If no OPTION element has the selected attribute set, user agent
behavior for choosing which option is initially selected is
undefined. Note. Since existing implementations handle this case
differently, the current specification differs from RFC 1866 (
[RFC1866] section 8.1.3), which states:

The initial state has the first option selected, unless a SELECTED
attribute is present on any of the <OPTION> elements.

Since user agent behavior differs, authors should ensure that each
menu includes a default pre-selected OPTION ."


Fred.
 
T

TJ

Thank you all for the quick responses. I am in the process of teaching
myself JavaScript so your time is greatly appreciated.
How about adding <OPTION selected> </OPTION> to the start of your options
list?

Not really what I want to do ... I have a binary tree of select elements,
so if the selected value of a node changes and the selected value of the
parent node matches the previous (child) value I want to clear the parent
selection and not propagate the new value up the tree.

I guess my only recourse is to add a blank option, unless there is
something else painfully obvious that I am missing ...

Sincerely,
TJ Walls
Ph.D. Candidate - Stony Brook University
 
F

Fred Oz

TJ said:
Thank you all for the quick responses. I am in the process of teaching
myself JavaScript so your time is greatly appreciated.

At present we've only discussed HTML... :)
Not really what I want to do ... I have a binary tree of select elements,
so if the selected value of a node changes and the selected value of the
parent node matches the previous (child) value I want to clear the parent
selection and not propagate the new value up the tree.

I guess my only recourse is to add a blank option, unless there is
something else painfully obvious that I am missing ...

Perhaps an option list is not the right thing to be using? Without a
bit of example code to show what you are trying to achieve, any
suggestions are just guessing. Even broken code that comes close may
do, or an example on a site somewhere.

Fred.
 
T

TJ

At present we've only discussed HTML... :)

Fair enough ... :)
Perhaps an option list is not the right thing to be using? Without a
bit of example code to show what you are trying to achieve, any
suggestions are just guessing. Even broken code that comes close may
do, or an example on a site somewhere.

Unfortunately, I still have not setup my web server yet (still playing
with the BSD setup ...), so in case you have a moment to look at this,
I'll post it here.

This does _basically_ what I want. It creates a binary competition tree
and has a user select from this initial pool of competitors all the
winners to a final champion.

The problems are:
1) I don't want the tree to start populated ... I want to force the
user to select all winners.

2) If a user selects a winner to be champion (say, in this test script
team1), then goes back and selects a team to defeat team1 (say team2),
then team2 is propagated up the tree. I would like to clear the user
selections above that change (if it affects the parent node)
and force a re-selection.

Any comments on the script are more than welcome, and with my
apologies:

--------------------------- <snip> ----------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript">
var sgLevels = 4;
function IPow(base, exp) {
var i, ans;
if (exp < 0) {
return 0;
}
ans = 1;
for (i = 0; i < exp; i++) {
ans *= base;
}
return ans;
}
function GetLevel(id) {
var elements = IPow(2, (sgLevels-1));
var i;
for (i = sgLevels-1; i >= 0; i--) {
if (id < elements) {
return i;
}
id -= elements;
elements /= 2;
}
return -1;
}
function GetLevelBase(level) {
var elements = 0;
var i = 0;
for (i = sgLevels-1; i > level; i--) {
elements += IPow(2, i);
}
return elements;
}
function GetChildID(id, childnum) {
var level = GetLevel(id);
var ans;
if (level == -1 || level == sgLevels-1) {
return -1;
}
ans = GetLevelBase(level+1) + 2*(id - GetLevelBase(level)) + childnum;
return ans;
}
function GetParentID(id) {
var level = GetLevel(id);
var ans;
if (level <= 0) {
return -1;
}
ans = GetLevelBase(level-1) + (id - GetLevelBase(level) - (id%2))/2;
return ans;
}

function PosTeam(id, name, left, top) {
var tag = '"team' + id + '"';
var command = '<p style="position:absolute; left:' + left + '; top:' + top + '" ';
command += 'id=' + tag + 'name=' + tag + '>' + name + '</p>';
return command;
}

function PosBox(id, left, top, width) {
var tag = '"box' + id + '"';
var command = '<select style="position:absolute; left:' + left + '; top:' + top + '; width:' + width + '" ';
command += 'id=' + tag + ' name=' + tag + ' onChange="UpdateBox(' + id + ', 1);"><option></option><option></option></select>';
return command;
}

function InitBox(id) {
var level = GetLevel(id);
var tmp;
var cid;
var me;
var i;
if (level == -1 || level == sgLevels-1) {
return;
}

me = document.getElementById('box' + id);
if (level == sgLevels-2) {
for (i = 0; i < 2; i++) {
cid = GetChildID(id, i);
tmp = document.getElementById('team' + cid);
me.options.value = tmp.innerHTML;
me.options.text = tmp.innerHTML;
}
} else {
for (i = 0; i < 2; i++) {
cid = GetChildID(id, i);
tmp = document.getElementById('box' + cid);
me.options.value = tmp.options[tmp.selectedIndex].value;
me.options.text = tmp.options[tmp.selectedIndex].value;
}
}
}

function UpdateBox(id, first) {
var level = GetLevel(id);
var tmp;
var cid;
var me;
var i;
var changed;
var val;
if (first == 1) {
UpdateBox(GetParentID(id), 0);
}
if (level == -1 || level > sgLevels-2) {
return;
}
changed = 0;
me = document.getElementById('box' + id);
val = me.options[me.selectedIndex].value;
for (i = 0; i < 2; i++) {
cid = GetChildID(id, i);
tmp = document.getElementById('box' + cid);
me.options.value = tmp.options[tmp.selectedIndex].value;
me.options.text = tmp.options[tmp.selectedIndex].value;
}
cid = GetChildID(id, me.selectedIndex);
tmp = document.getElementById('box' + cid);
if (val != tmp.options[tmp.selectedIndex].value) {
UpdateBox(GetParentID(id), 0);
}
}


</script>

<title>Tester Tree</title>
</head>

<body>
<form action="">
<input type="button"
name="foo"
value="foo"
onClick="alert('**** You');">
</form>

<form name="myform" action="">
<script type="text/javascript">
var str;
var i, j, ct;
var len = 100;
var wid = 40;
var stop;
var space = 1;
var linetop;

ct = 0;
stop = IPow(2, sgLevels - 1);
for (i = 0; i < sgLevels; i++) {
for (j = 0; j < stop; j++) {
linetop = ((j+1)*space*wid) + 100 - (wid/2)*(space-1);
if (i == 0) {
str = PosTeam(j, 'team' + (j+1), 3, linetop-33);
document.write(str);
} else {
str = PosBox(ct, (i*len)+3, linetop-25, len-8);
document.write(str);
InitBox(ct);

}
ct++;
}
stop /= 2;
space *= 2;
}
</script>

</form>
</body>
</html>
---------------------- <snip> -----------------------------------
 
T

TJ

I should note that I apologize for the vulgarity on the "foo" button ...
I tend to get grumpy when I code late at night and thus tend to make my
programs grumpy with me. I meant to delete that button before posting,
again, I apologize.

Sincerely,
TJ Walls
Ph.D. Candidate - Stony Brook University
 
R

RobG

TJ said:
I should note that I apologize for the vulgarity on the "foo" button ...

Apology accepted...<fx: sound of gasping, body crumples to floor>

Your problem is interesting, I imagine the best solution is to use a
<DIV> for each contestant and CSS to position them on the page in
the right place. An onclick could populate the next round.

You could use CSS to change the style of the winner of each contest
(say bold the text and change the background colour) with styles
contestant (initial state, result not known), winner and loser. I'm
sure empty the tree structure could be built so that it appears on load
and is filled in as you pick winners - playing with the borders should
do this.

It should also be possible to give each contestant DIV an id that
identifies the round and contestant, e.g. 1_1 and 1_2 for the first
two players in round 1. The winner moves to 2_1. The winner of 1_3
and 1_4 moves to 2_2, etc.

If a winner changes, you can remove them from all subsequent matches
and return the other player to "contestant" style.

The only issue I have with onclick is that if the user accidentally
clicks on a round 2 match after the tree is complete, all subsequent
matches will be affected. This is quite drastic if it was not
intended, so you may want to have a prompt in this case or some other
way of allowing the user to select a winner, then a second click to
propagate the "win" through the tree.

You should be able to pass the players in a meta tag, then
build the entire competition tree using JavaScript. Of course, anyone
with JS disabled won't see anything, but this is dependent on JS
anyway.

I would also increase the size of the text as the series progresses, as
the tree becomes quite sparse with only a few iterations.

Finally, have you figured out how to send the results to the server?
The above would allow you to grab all the DIVs, then send the id and
content to the server so you know the contestants for each match and
the style will indicate the winner (or you could infer it from the
contestant that made it into the next round).

I'll post a bit of code later on...

Cheers, Rob.
 
R

RobG

TJ wrote:
[snip]

See if this does what you want. Beware some wrapping, it should be OK
after the first few lines. It doesn't clear the parent tree if you
change a lower node, but everything else works.

Click on a player to make them a winner. They can only be a winner if
they have an opponent. If they are a winner, they are promoted to the
next round. Clicking on an empty node, or one that doesn't have an
opponent yet, will do nothing. You may want an alert at these points,
but I find them annoying so maybe write a warning in the page instead.

The div ids are used as keys to the position of each node in the tree.
This thing will only work with a perfect tree - it must start with 2^n
players or it won't work. You could potentially add in players to
later rounds, but you'd have to adjust the div keys accordingly.

Please excuse the CSS and styles - this is just a prototype example, I
don't know much about CSS yet other than basic styles (hey, I only just
learned the ":empty" tag). I've used px for dimensions 'cos otherwise
IE and Firefox look very different - expect the CSS puritans to moan
about that...

Cheers, Rob.

<html><head><title>Knockout Results</title>
<script type="text/javascript">
function togWin(x) {
if (document.getElementById(nextIs(x.id))
&& x.childNodes.length != 0
&& document.getElementById(pairIs(x.id)).childNodes.length!=0) {

document.getElementById(nextIs(x.id)).innerHTML=(x.childNodes[0].data);
var t = pairIs(nextIs(x.id));
if (!document.getElementById(pairIs(nextIs(x.id)))) {
document.getElementById(nextIs(x.id)).className='winner';
alert('The winner is: '+x.childNodes[0].data);
}
if (x.className == 'competitor') {
x.className = 'winner';
document.getElementById(pairIs(x.id)).className='competitor';
} } }
function pairIs(p) {
var b = p.split('_');
(b[1]%2 == '1')?b[1]-=-1:b[1]-=1;
return b.join('_');
}
function nextIs(n) {
var a = n.split('_');
a[1] = Math.floor((+a[1]+1)/2);
a[0] = +a[0]+1;
return a.join('_');
}
</script>
<style type="text/css">
body {
font-family: sans-serif;
margin-left: 40; margin-top: 10;}
..competitor, .winner {
font-size: 12px;
font-family: sans-serif;
width: 100px;
height: 20px;
border-top: 1px solid #eee;
border-left: 1px solid #eee;
border-bottom: 1px solid black;
border-right: 1px solid black;
position: absolute;
text-align: left;
}
div:empty {
background-color: #eee;
font-weight: normal;
}
..competitor {
background-color: #eee;
font-weight: normal;
}
..winner {
background-color: white;
font-weight: bold;
}
..head {
font-size: 14px;
width: 100px;
height: 20px;
background-color: white;
position: absolute;
font-weight: bold
}
</style>
</head>
<body>
<div style="position: relative; top:10px;">
<div class="head" style="left: 0; top: 0px;">Round 1</div>
<div class="head" style="left: 101; top: 0px;">Round 2</div>
<div class="head" style="left: 202; top: 0px;">Round 3</div>
<div class="head" style="left: 303; top: 0px;">Round 4</div>

<!-- Round One -->
<div id="1_1" class="competitor" style="left: 0; top: 20px;"
onclick="togWin(this);">Steve</div>
<div id="1_2" class="competitor" style="left: 0; top: 42px;"
onclick="togWin(this);">Sam</div>

<div id="1_3" class="competitor" style="left: 0; top: 80px;"
onclick="togWin(this);">Sally</div>
<div id="1_4" class="competitor" style="left: 0; top: 102px;"
onclick="togWin(this);">Wendy</div>

<div id="1_5" class="competitor" style="left: 0; top: 140px;"
onclick="togWin(this);">Peter</div>
<div id="1_6" class="competitor" style="left: 0; top: 162px;"
onclick="togWin(this);">Ivana</div>

<div id="1_7" class="competitor" style="left: 0; top: 200px;"
onclick="togWin(this);">Katcha</div>
<div id="1_8" class="competitor" style="left: 0; top: 222px;"
onclick="togWin(this);">Abdulla</div>
<div class="space"></div>

<!-- Round Two -->
<div id="2_1" class="competitor"
style="position: absolute; left: 102px; top: 30px;"
onclick="togWin(this);"></div>
<div id="2_2" class="competitor"
style="position: absolute; left: 102px; top: 90px;"
onclick="togWin(this);"></div>

<div id="2_3" class="competitor"
style="position: absolute; left: 102px; top: 150px;"
onclick="togWin(this);"></div>
<div id="2_4" class="competitor"
style="position: absolute; left: 102px; top: 210px;"
onclick="togWin(this);"></div>

<!-- Round Three -->
<div id="3_1" class="competitor"
style="position: absolute; left: 200px; top: 60px;"
onclick="togWin(this);"></div>
<div id="3_2" class="competitor"
style="position: absolute; left: 200px; top: 180px;"
onclick="togWin(this);"></div>

<!-- Round Four -->
<div id="4_1" class="competitor"
style="position: absolute; left: 300px; top: 120px;"
onclick="togWin(this);"></div>

</div>
</body>
</html>
 
M

Michael Winter

[snip]
Please excuse the CSS and styles - this is just a prototype
example, I don't know much about CSS yet other than basic styles
(hey, I only just learned the ":empty" tag).

They're called either pseudo-elements or -classes. Pseudo-elements -
first-line, first-letter, before, and after - represent document parts
that are treated as elements, but don't actually exist. Pseudo-classes -
first-child, link, visited, hover, active, focus, and lang - select
elements by special, sometimes dynamic, characteristics.

Notice that empty isn't listed above. It doesn't exist in CSS 1, 2, or
2.1. It's part of CSS 3 which is only a Candidate Recommendation, and
considering that most browsers haven't even implemented CSS 2 completely,
CSS 3 seems a little ambitious.
I've used px for dimensions 'cos otherwise IE and Firefox look
very different - expect the CSS puritans to moan about that...

Indeed. :p It would be better to estimate an approximate (don't try for
exact!) em value so that the positioning would move if font sizes aren't
as expected (which might occur as variations in typefaces). Font sizes
specified with absolute values are also bad practice as some user agents
can't resize them.

By the way, the complaint isn't a purist/puritan thing. It's practical.
<html><head><title>Knockout Results</title>

You missed the DOCTYPE.

[snip]
body {
font-family: sans-serif;
margin-left: 40; margin-top: 10;
}
[snip]

<div class="head" style="left: 101; top: 0px;">Round 2</div>
<div class="head" style="left: 202; top: 0px;">Round 3</div>
<div class="head" style="left: 303; top: 0px;">Round 4</div>

In the declarations above, you specify non-zero values without a unit.
Whilst most user agents will interpret these as pixel units, it's purely
an error correction process. All length values, except zero (where it's
optional), *must* have a length unit.

[snip]

Mike
 
R

RobG

Michael said:
(hey, I only just learned the ":empty" tag).

They're called either pseudo-elements or -classes. Pseudo-elements - [snip]
Notice that empty isn't listed above. It doesn't exist in CSS 1, 2, or
2.1. It's part of CSS 3 which is only a Candidate Recommendation, and
considering that most browsers haven't even implemented CSS 2
completely, CSS 3 seems a little ambitious.

Fair enough, but the only other way to get the 'zilla browsers to show
an empty div was to;

- put a space, which was removed and the div not shown anyway
- put &nbsp;, but then I couldn't find a DOM method to determine if the
content of the cell was &nbsp; or some other text (it's important to
the logic).
- put in some other junk text and hard code the test

none of which I found appealing. It's only there to fool Firefox (which
supports it), IE and Safari seem to draw empty divs at the size you
specify anyway.
Indeed. :p It would be better to estimate an approximate (don't try for
exact!) em value so that the positioning would move if font sizes
aren't as expected (which might occur as variations in typefaces). Font

Ok, I'll have a go but I guess I'll post those questions to
c.i.w.authoring.stylesheets. I presume it's OK to use px for position?
I haven't worked out how to make this all work with relative
positioning yet... but maybe it's a good practice case.

[snip]
By the way, the complaint isn't a purist/puritan thing. It's
practical.

Allow me *some* hyperbole! :)

[snip]

I've added the function to fix the tree when a lower order result is
changed that affects higher order ones. I've also replaced the
horrible document.getElementById() stuff - what was I thinking? Why
pass the id when I can pass direct references to the nodes? Duh.

e.g.

document.getElementById(nextIs(x.id)).innerHTML=(x.childNodes[0].data);

becomes:

nextIs(x).innerHTML=(x.childNodes[0].data);

One last point, at one stage I want to get the node's pair, so I take
say 1_2 and turn it into 1_1 or 2_3 and turn it into 2_4. Can you look
at the line:

(b[1]%2 == '1')?b[1]-=-1:b[1]-=1;

I use split to turn 1_2 into an array b of 1,2. So to get the
string "1" to turn into a number so I can add "1", I tried:

+b[1] += 1;

but it didn't want to work - it turns 1 into 11. Strangely, the
equivalent:

b[1] -= -1

does work - it turns 1 into 2. Am I playing with fire here, or is that
OK?

Cheers, Rob.
 
M

Michael Winter

Michael Winter wrote:
[snip]
[...] CSS 3 seems a little ambitious.

Fair enough,

It was just a warning. You said you were discovering CSS and it seemed
prudent to mention that you might be wandering down what, for the moment,
is a relatively fruitless path. After all, IE won't be supporting it until
at least the new version is released on Longhorn, and even then, I suspect
the majority of existing Windows users will keep using earlier OS and IE
versions.
but the only other way to get the 'zilla browsers to show an empty
div was to;

This might not be an issue in a more dynamic version of this script. With
something more dynamic, allowing for a varying number of competitors,
you'd be better off generating the DIV elements on-the-fly.

[snip]
I presume it's OK to use px for position?

It depends what you're positioning, and what that position is relative to.
With certain concrete parts of a page, there should be no problem.
However, text should use relative units so everything stays in correct
proportion.
I haven't worked out how to make this all work with relative
positioning yet... but maybe it's a good practice case.

Relative as in "position: relative", or relative units?

For the former, you'd have to make the content in the previous column a
fixed width so that the next column uses the same right edge. It would be
easier to wrap each column in a DIV and position the contents (probably
inline-elements, now) within these containers.
Allow me *some* hyperbole! :)

Just making sure there are misconceptions on neither your's, nor the OP's,
part. :D

[snip]
One last point, at one stage I want to get the node's pair, so I
take say 1_2 and turn it into 1_1 or 2_3 and turn it into 2_4.
Can you look at the line:

(b[1]%2 == '1')?b[1]-=-1:b[1]-=1;

I'd use:

(b[1]%2 == 1) or (b[1]%2) or (b[1] & 1)

but not:

(b[1]%2 == '1')
I use split to turn 1_2 into an array b of 1,2. So to get the
string "1" to turn into a number so I can add "1", I tried:

+b[1] += 1;

but it didn't want to work - it turns 1 into 11.

That evaluates to (I realise the brackets are a bit confusing - sorry):

( (+ (b[1]) ) += 1 );

However, this expression isn't valid (your browser should have told you
that).

Whilst, there's generally no problem with

+b[1]

this isn't a left-hand expression; something that can be assigned to. It's
like commanding:

2 = 5; or 'a string' = 'my string';

To do what you want, you'd have to write:

b[1] = +b[1] + 1;

That's because:

b[1] += 1;

is the same as:

b[1] = b[1] + 1;

and the addition operator has a bias towards string concatenation.
Strangely, the equivalent:

b[1] -= -1

does work - it turns 1 into 2. Am I playing with fire here, or is that
OK?

It's not that strange at all. As I said, addition has a bias towards
string concatenation, but subtraction is pretty much meaningless in a
string context. In this case, the operands are forced to numbers (so
potentially NaN) and things occur as normal.

b[1] -= -1;

is effectively:

b[1] = Number(b[1]) - Number(-1);

Hope that helps,
Mike
 
T

TJ

See if this does what you want. Beware some wrapping, it should be OK
after the first few lines. It doesn't clear the parent tree if you
change a lower node, but everything else works.

Wow! ... that's much cooler than the said:

As a said above, the primary point of this project is to teach myself
some JavaScript ... this is a great example for me to break apart a
digest! Thanks a million for taking the time to put it together and post
it! I'll definite make time this weekend to play with it ...

Sincerely,
TJ Walls
Ph.D. Candidate - Stony Brook University
 
T

TJ

TJ wrote:
[snip]
Finally, have you figured out how to send the results to the server?
The above would allow you to grab all the DIVs, then send the id and
content to the server so you know the contestants for each match and
the style will indicate the winner (or you could infer it from the
contestant that made it into the next round).

No, I haven't made it those specifics yet ... my original idea was just
to wrap my select elements in a form and submit the form through a
cgi-script ...

I am a fairy competent Perl programmer, but really don't have any
knowledge about the Perl/CGI interaction (or quite honestly what that even
means ...). Ah well, so much to learn, so little time.

Sincerely,
TJ Walls
Ph.D. Candidate - Stony Brook University
 
R

RobG

TJ wrote:
[snip]
As a said above, the primary point of this project is to teach myself
some JavaScript ... this is a great example for me to break apart a
digest! Thanks a million for taking the time to put it together and post
it! I'll definite make time this weekend to play with it ...

This is just an example, it is not really suitable for the web since
without JavaScript it doesn't work at all and whilst I've stuck to
standards, it will be intolerant of some (particularly older) browsers
- but it is a bit of fun trying to do some of this stuff and create
dynamic pages. This sort of stuff is best suited to intranet or
special interest groups anyway.

I have tested it in fairly recent versions of Safari, IE and Firefox
and it works fine. You can re-size the text and everything stays in
proportion (I've used ems for nearly all measurements).

An interesting thing I came across was getting text to middle align in
a div. Text will top-align with a div by default, no amount of
alignment statements will change that - the CSS text-align property
horizontally aligns text, not vertically. You have to use the line
height to get the text to align - so set the line-height to the same as
the div height and hey presto, middle aligned text.

Below is the final code, more concise, with Mike's suggested mods and
some comments. The div:empty should be ignored by browsers that don't
support it, at worst the empty divs will display as you add text to
them (which isn't such a bad thing, but a bit confusing at first).

Cheers, Rob.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html><head><title>Knockout Results</title>
<script type="text/javascript">
function togWin(x) {
if (nextIs(x) // If there is a next node
&& x.childNodes.length != 0 // and this node has a player
&& pairIs(x).childNodes.length!=0) { // and the pair has a player
// See if the other player has already been promoted & fix
checkTree(nextIs(x),pairIs(x).childNodes[0].data);
// Promote player - write name to next node
nextIs(x).innerHTML=(x.childNodes[0].data);
// Change next node style
nextIs(x).className='competitor';
// If promoted to last node, then ultimate winner
if (!pairIs(nextIs(x))) {
nextIs(x).className='Xwinner';
// alert('The winner is: '+x.childNodes[0].data);
}

// Toggle the class of the current node and pair
if (x.className == 'competitor'
|| x.className == 'loser') {
x.className = 'winner';
pairIs(x).className='loser';
}
}
}
// find the pair of the node
// 1_1 -> 1_2, 2_4 -> 2_3
function pairIs(p) {
var b = p.id.split('_');
// (b[1]%2 == '1')? b[1] -= -1:b[1]-=1;
(b[1]%2 == 1)? b[1] = +b[1]+1 : b[1] = +b[1]-1;
return document.getElementById(b.join('_'));
}
// find the next match slot
// 1_2 or 1_1 -> 2_1
function nextIs(n) {
var a = n.id.split('_');
a[1] = Math.floor((+a[1]+1)/2);
a[0] = +a[0]+1;
return document.getElementById(a.join('_'));
}
function checkTree(nod,nam) {
// if the next node already has the name in it,
// fix and make the pair not a winner.
if(nod.childNodes.length != 0) {
if (nod.childNodes[0].data) {// == nam) {
nod.innerHTML = '';
nod.className = 'competitor';
if (pairIs(nod)) {
pairIs(nod).className = 'competitor';
checkTree(nextIs(nod),nam);
}
}
}
}
</script>
<style type="text/css">
body {
font-family: sans-serif;
margin-left: 40px; margin-top: 10px;}
..loser, .competitor, .winner, .Xwinner {
font-size: 1em;
font-family: sans-serif;
width: 6em;
height: 1.5em;
line-height: 1.5em;
border-top: 1px solid #eee;
border-left: 1px solid black;
border-bottom: 1px solid black;
border-right: 1px solid #eee;
position: absolute;
text-align: left;
padding-left: 0.5em;
}
div:empty {
background-color: white;
font-weight: normal;
}
..loser, .competitor {
background-color: white;
font-weight: normal;
}
..loser {
color: #999;
text-decoration: line-through;
}
..winner, .Xwinner {
background-color: #eef;
font-weight: bold;
display:table-cell;
vertical-align:bottom;
}
..Xwinner {
border:thick solid red;
}
..head {
font-size: 1.2em;
width: 6em;
height: 1.5em;
background-color: white;
position: absolute;
font-weight: bold
}
</style>
</head>
<body>
<div style="position: relative; top:10px;">
<div class="head" style="left: 0em; top: 0em;">Round 1</div>
<div class="head" style="left: 6em; top: 0em;">Round 2</div>
<div class="head" style="left: 12em; top: 0em;">Round 3</div>
<div class="head" style="left: 18em; top: 0em;">Round 4</div>

<!-- Round One -->
<div id="1_1" class="competitor" style="left: 0em; top: 2em;"
onclick="togWin(this);">Steve</div>
<div id="1_2" class="competitor" style="left: 0em; top: 4em;"
onclick="togWin(this);">Sam</div>

<div id="1_3" class="competitor" style="left: 0em; top: 7em;"
onclick="togWin(this);">Sally</div>
<div id="1_4" class="competitor" style="left: 0em; top: 9em;"
onclick="togWin(this);">Wendy</div>

<div id="1_5" class="competitor" style="left: 0em; top: 12em;"
onclick="togWin(this);">Peter</div>
<div id="1_6" class="competitor" style="left: 0em; top: 14em;"
onclick="togWin(this);">Ivana</div>

<div id="1_7" class="competitor" style="left: 0em; top: 17em;"
onclick="togWin(this);">Katcha</div>
<div id="1_8" class="competitor" style="left: 0em; top: 19em;"
onclick="togWin(this);">Abdulla</div>
<div class="space"></div>

<!-- Round Two -->
<div id="2_1" class="competitor"
style="position: absolute; left: 6em; top: 3em;"
onclick="togWin(this);"></div>
<div id="2_2" class="competitor"
style="position: absolute; left: 6em; top: 8em;"
onclick="togWin(this);"></div>

<div id="2_3" class="competitor"
style="position: absolute; left: 6em; top: 13em;"
onclick="togWin(this);"></div>
<div id="2_4" class="competitor"
style="position: absolute; left: 6em; top: 18em;"
onclick="togWin(this);"></div>

<!-- Round Three -->
<div id="3_1" class="competitor"
style="position: absolute; left: 12em; top: 5.5em;"
onclick="togWin(this);"></div>
<div id="3_2" class="competitor"
style="position: absolute; left: 12em; top: 15.5em;"
onclick="togWin(this);"></div>

<!-- Round Four -->
<div id="4_1" class="competitor"
style="position: absolute; left: 18em; top: 10.5em;"
onclick="togWin(this);"></div>
</div>
</body>
</html>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top