IE reverses logic

F

Frank Spade

While the following code works in Firefox and Mozilla,
IE6 reverses the logic (when I click yes on the top it checks no on the
bottom and vice versa).

<form method="POST">
<p>
<input type="radio" name="decide" value="yes"
onchange="decide1[0].checked = decide[0].checked">yes
<input type="radio" name="decide" value="no"
onchange="decide1[1].checked = decide[1].checked">no.</font></p>
<p>
[...]</p>
<p>
<input type="radio" name="decide1" value="yes"
onchange="decide[0].checked = decide1[0].checked">yes
<input type="radio" name="decide1" value="no"
onchange="decide[1].checked = decide1[1].checked">no.</p>
<p>
<input type="submit" value="Submit"><input type="reset"
value="Reset"></p>
</form>

Please advise.
 
R

RobG

Frank said:
While the following code works in Firefox and Mozilla,
IE6 reverses the logic (when I click yes on the top it checks no on the
bottom and vice versa).
[...]

Without going into lengthy explanations (of which I'd likely get the
finer details wrong anyway), the reason is that the way you have
referenced the radio buttons is interpreted differently by IE and
Mozilla.

You are also better off making the action occur "onclick" rather than
"onchange", but opinions may vary.

Fix your references thusly:

<form action="">
<input type="radio" name="decide" value="yes" onclick="
this.form.decide1[0].checked = this.form.decide[0].checked
">yes
<input type="radio" name="decide" value="no" onclick="
this.form.decide1[1].checked = this.form.decide[1].checked
">no.<br>

<input type="radio" name="decide1" value="yes" onclick="
this.form.decide[0].checked = this.form.decide1[0].checked
">yes
<input type="radio" name="decide1" value="no" onclick="
this.form.decide[1].checked = this.form.decide1[1].checked
">no.<br>

<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form>

Tested in Firefox and IE.
 
R

Richard Cornford

RobG wrote:
Without going into lengthy explanations (of which I'd
likely get the finer details wrong anyway), ...
<snip>

You shouldn't let worrying about getting them wrong prevent you from
attempting to explain the finer details. Someone will correct them if
you do make errors, leaving the specifics much clearer (or maybe just
fresher) in your mind.

However, there is considerable value in the act of attempting to explain
things to others. As Lasse Reichstein Nielsen once observed, you can be
certain that you understand something yourself when you can explain it
to others such that they then understand (assuming a reasonably
receptive and perceptive other). Realistically it takes at least a
couple of attempts to formulate a good explanation of anything, but only
attempting that in public will expose the flaws in the early versions
(both factual errors and failures to get points across). But it is worth
the effort, attempting to teach in a great way of learning.

Richard.
 
R

RobG

Richard said:
RobG wrote:


<snip>

You shouldn't let worrying about getting them wrong prevent you from
attempting to explain the finer details. Someone will correct them if
you do make errors, leaving the specifics much clearer (or maybe just
fresher) in your mind.

Thanks for the encouragement, my real motive was lack of time to
properly investigate. So here goes...

Further investigation reveals that IE does not fire the onchange event
until the checkbox loses focus. Clicking "yes" initially just sets
that checkbox to checked. If you then click in the page, the onchange
fires and the second "yes" is checked. But, if you click "no" instead,
the first "yes" onchange fires and changes the second "yes" to clicked
so you have an apparent reversal of logic.

In fact, all that's happened is that the second "no" onchange has not
yet fired. Clicking anywhere else fires it - so if you click back on
the first "yes", it becomes checked, the first "no" onchange fires and
the second "no" is checked. The onchange from the first "yes" is still
lurking....

Setting the initial state of the first "yes" to checked in the HTML can
create even more confusing results.

Mozilla fires the onchange as soon as the checkbox changes BUT on text
inputs, its onchange isn't fired until the input loses focus (if the
text has been modified).

But who is wrong? As luck would have it, MS seem to have gotten this
one right. The W3C HTML 4.01 spec says:

"The onchange event occurs when a control loses the input
focus and its value has been modified since gaining focus."

Mozilla's behaviour, whilst more logical, is actually wrong. And using
checkboxes to cause UI events to be fired is also "wrong", but it's not
at odds with any open standard that I'm aware of (not much solace there
I'm afraid!)

So in fact my presumption regarding references to form elements being
the cause was wrong (thanks Richard), however...

It is still better (IMHO) to refer to form elements the way indicated.

The bottom line is that the behaviour of "onchange" is not consistent
across browsers or (in the case of Mozilla) for different elements in
the same browser and therefore shouldn't be relied upon.

Further more, to achieve the desired result, onclick is more consistent
and should be used instead in this case.

Lastly, clicks on checkboxes should not be used to fire UI events
(bring up dialogs, popup windows, change content, etc.) but that is
just my opinion. Use buttons or other UI widgets that users *expect*
to cause UI changes - the "least surprise" principle.
However, there is considerable value in the act of attempting to explain
things to others. As Lasse Reichstein Nielsen once observed, you can be
certain that you understand something yourself when you can explain it
to others such that they then understand (assuming a reasonably
receptive and perceptive other).
[...]

Yes, hence why I lurk here at all. :)
 
R

RobG

But wait, there's more...

I should have been referring to radio buttons, not checkboxes, but I
don't think that changes anything of what I said. Changing the radio
buttons to checkboxes produces the same inconsistencies.

Back to radio buttons.

Whilst it is simple to programmatically click a control to fire an
onclick, onchange is more difficult and less reliable. You can force
the onchange to fire in IE programmatically:

<input type="button" onclick="
decide[0].focus();
decide[0].checked = 'checked';
decide[0].blur();
">

But it doesn't work in Mozilla. Dropping the focus() line from IE
stops it working too (the radio button never gets focus, so it can't
lose it.)

Which brings up the next issue: a radio button onchange only fires when
the radio button is changed to checked, not when changed to unchecked.
Which makes sense because when checking another button, the focus first
changes to the other element, then changes the one that was checked to
unchecked - it changed whilst out of focus, the onchange doesn't fire.

Finally, RFC 1866 says:

"At all times, exactly one of the radio buttons in a set is
checked. If none of the <INPUT> elements of a set of radio
buttons specifies `CHECKED', then the user agent must check
the first radio button of the set initially."

But neither Mozilla nor IE does, so web developers should ensure that
one button is always set to checked.

Danged if I'll go any further.
 
F

Frank Spade

Richard said:
However, there is considerable value in the act of attempting to explain
things to others. As Lasse Reichstein Nielsen once observed, you can be
certain that you understand something yourself when you can explain it
to others such that they then understand (assuming a reasonably
receptive and perceptive other).
Wow, I love the spirit (and the lesson)! Thanks.
 
R

RobG

Frank said:
Thank you Rob! Beautiful lesson, wonder if I will ever be able to
explain it myself.


Glad to help.

Incidentally, I totally forgot you can fire the onchange
programmatically using:

<input type="button" onclick="
decide[0].checked = 'checked';
decide[0].onchange();
">
 
G

Grant Wagner

RobG said:
Further investigation reveals that IE does not fire the onchange event
until the checkbox loses focus. Clicking "yes" initially just sets
that checkbox to checked. If you then click in the page, the onchange
fires and the second "yes" is checked. But, if you click "no" instead,
the first "yes" onchange fires and changes the second "yes" to clicked
so you have an apparent reversal of logic.

Sounds resonable and matches the behaviour I have seen.
Lastly, clicks on checkboxes should not be used to fire UI events
(bring up dialogs, popup windows, change content, etc.) but that is
just my opinion. Use buttons or other UI widgets that users *expect*
to cause UI changes - the "least surprise" principle.

I'm not sure I agree with this. I can think of many cases where a
checkbox (or set of radio buttons) offers options which expose (or
conseal) functionality:

<table>
<tr valign="top">
<td width="50%">Billing information:
<form>
<input type="text" name="billing_name">
<br>
Shipping information is the same as billing information
<input type="checkbox"
value="shipping_same"
value="1"
onclick="
if (this.checked)
{
document.getElementById('shipping_info').style.display =
'none';
document.getElementById('shipping_same').style.display =
'block';
}
else
{
document.getElementById('shipping_same').style.display =
'none';
document.getElementById('shipping_info').style.display =
'block';
}
">
</form>
</td>
<td width="50%">Shipping information:
<div id="shipping_info"><form>
<input type="text" name="shipping_name">
</form></div>
<div id="shipping_same" style="display:none;"><form>
Same as billing information
</form></div>
</td>
</tr>
</table>

That said, I have seen incredibly horrible uses of checkboxes, radio
buttons and other UI elements for navigation or other functionality that
clearly don't belong under those UI elements.
 
R

RobG

Grant said:
I'm not sure I agree with this. I can think of many cases where a
checkbox (or set of radio buttons) offers options which expose (or
conseal) functionality:

In your example, consider replacing the checkbox with a button:

<form action="">
<label for="billing_name"><b>Billing information:</b><br>
<input type="text" name="billing_name" id="billing_name"><br>
<label for="shipping_same">Copy shipping
information to billing information?&nbsp;
<input type="button" style="width: 5em;" value="Copy" onclick="
this.form.shipping_name.value = this.form.billing_name.value;
this.blur();
">
</label><br>

<label for="shipping_name"><b>Shipping information:</b><br>
<input type="text" name="shipping_name" id="shipping_name">
</label>
</form>

UI consistency is maintained, code maintenance reduced and
functionality increased.

[...]
That said, I have seen incredibly horrible uses of checkboxes, radio
buttons and other UI elements for navigation or other functionality that
clearly don't belong under those UI elements.

Amen to that.
 
M

Michael Winter

You are also better off making the action occur "onclick" rather
than "onchange", but opinions may vary.

Technically, the change event is preferred as it's device-independant,
however the click event seems to be interpreted now as an "activate"
event. That said, Opera doesn't seem to fire a change event at all when a
radio button gains or loses its checked status. Presumably it takes the
remark about a change of *value* to heart.

Assuming that controls are initialised correctly using the checked
attribute, the event listener shouldn't need to depend on the state of the
firing element at all - just toggle the opposing set's based on that set's
state.

Mike
 
R

Richard Cornford

RobG wrote:
So in fact my presumption regarding references to form
elements being the cause was wrong (thanks Richard),
however...
<snip>

The observed symptoms may not have been caused by the references used
but the script as posted is still failing in Opera <= 6 (when not
spoofing IE), NetFront and any other browsers that do not provide custom
scope chains for the intrinsic event handling functions that they
internally generate, for no reason other than the choice of referencing
style. So the general advice was still good.

I did suspect you were wrong in assuming the references were the cause
because in the stated context Mozilla and IE have sufficiently similar
behaviour (both placing the form object on the scope chain).

Richard.
 

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,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top