Bug 97796 - radio button onChange event is triggered without real change
Summary: radio button onChange event is triggered without real change
Status: RESOLVED FIXED
Alias: None
Product: konqueror
Classification: Applications
Component: khtml forms (show other bugs)
Version: 3.3.2
Platform: Debian testing Linux
: NOR normal
Target Milestone: ---
Assignee: Konqueror Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-01-24 15:42 UTC by Leonardo Piseri
Modified: 2005-12-16 11:37 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In:


Attachments
Simpler testcase (278 bytes, text/html)
2005-03-15 08:17 UTC, Mario Weilguni
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Leonardo Piseri 2005-01-24 15:42:47 UTC
Version:           3.3.2 (using KDE KDE 3.3.2)
Installed from:    Debian testing/unstable Packages
OS:                Linux

here's the code to reproduce the bug (use it in a web server):

<html>
<head><title>Test</title></head>

<body>
<form action="testradio.html">
<table>
 <tr>
  <th>
   <input type="radio" name="do" onChange="this.form.submit();" checked> Head 1
  </th>
  <th>
   <input type="radio" name="do" onChange="this.form.submit();"> Head 2
  </th>
  <th>
   <input type="radio" name="do" onChange="this.form.submit();"> Head 3
  </th>
  <th>
   <input type="radio" name="do" onChange="this.form.submit();"> Head 4
  </th>
 </tr>
 <tr>
  <td>Aaaaaaaaa</td><td>Bbbbbbbbb</td><td>Ccccccccc</td><td>Ddddddddd</td>
 </tr>
 <tr>
  <td>Aaaaaaaaa</td><td>Bbbbbbbbb</td><td>Ccccccccc</td><td>Ddddddddd</td>
 </tr>
 <tr>
  <td>Aaaaaaaaa</td><td>Bbbbbbbbb</td><td>Ccccccccc</td><td>Ddddddddd</td>
 </tr>
 <tr>
  <td>Aaaaaaaaa</td><td>Bbbbbbbbb</td><td>Ccccccccc</td><td>Ddddddddd</td>
 </tr>
</table>

</form>
</body>
</html>
Comment 1 Leonardo Piseri 2005-01-24 15:55:21 UTC
i forgot to say: save the html code as testradio.html (the action of the form), you'll see the form is submitted automaticaly
Comment 2 Mario Weilguni 2005-01-26 08:17:20 UTC
Reproduceable for 3.4.0_beta1
Here's the testcase above: http://www.weilguni.net/bugs/testradio.html
Comment 3 Mario Weilguni 2005-03-15 08:17:07 UTC
Created attachment 10122 [details]
Simpler testcase
Comment 4 Mario Weilguni 2005-03-15 08:30:36 UTC
When you load the testcase above with konqueror, you will get one JS alert box when the page is loaded, and 2 on every click on an unchecked radiobutton.

IMO there are 2 problems here. The first one is that the onChange trigger is called on activation, and the second one is that the onChange trigger is called for radiobuttons which lose the checked status.

I tested the testcase (id=10122) above with firefox, and it seems that firefox only calls onChanged for the case when the "checked" attribute is set, not when it is lost. 

This patch fixes both problems:
Index: rendering/render_form.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/rendering/render_form.cpp,v
retrieving revision 1.284
diff -r1.284 render_form.cpp
158d157
<
164a164,167
>
>     // prevent firing toggled() signals on initialization
>     b->setChecked(element->checked());
>
169c172
< {
---
> {
188c191
< void RenderRadioButton::slotToggled(bool)
---
> void RenderRadioButton::slotToggled(bool activated)
190,192c193,197
<     ref();
<     element()->onChange();
<     deref();
---
>     if(activated) {
>       ref();
>       element()->onChange();
>       deref();
>     }
Comment 5 Stephan Kulow 2005-03-15 10:55:47 UTC
I can't read that diff, but the bool makes sense. I'd say go ahead and commit
Comment 6 Allan Sandfeld 2005-03-15 11:08:35 UTC
I think onChanged should fire everytime the state changes. So Konqueror is right and Firefox wrong. 

What does Opera and IE do?
Comment 7 Mario Weilguni 2005-03-15 11:18:17 UTC
Opera: does not work at all.
IE: difficult to explain, if I'm right it fires when the radio-button looses the focus, and seems to fire only for activation, not for deactivation, so it's similar to Firefox
Comment 8 Germain Garand 2005-03-15 11:50:30 UTC
problem is, if you care to check the spec, only MSIE is right ;(

http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.3

onchange = script [CT] 
The onchange event occurs when a control loses the input focus _and_ its value has been modified since gaining focus. 

Comment 9 Mario Weilguni 2005-03-15 11:58:02 UTC
Can this be really true? What about JS code activating a radio button, there's no focus in/focus out, so no onChange trigger fires?

Will try this with IE and JS.
Comment 10 Germain Garand 2005-03-15 12:20:16 UTC
> What about JS code activating a radio button, there's no focus in/focus out,
> so no onChange trigger fires?

yes, I believe there should be no onChange triggered when there's not at least an associated focus change of some kind on one of the controls.

try:
 <body onLoad="document.lag.thing[1].checked=1"> 
 <form name="lag" action="97796.html"> 
    <input type="checkbox" name="thing" value="1" onChange="alert('here 1')" checked> 1 
<br>
    <input type="checkbox" name="thing" value="2" onChange="alert('here 2')"> 2 

In Geckos, there is no onChange emitted at all.

now thinking about it, the spec is ambiguous here, because a "state" change is not really a "value" change... 
The real value change is not tied to one control but to the group of controls driven by the same "control name" ("do" in your testcase).

And as it is necessary, when you click, to have at least one of the element of the group losing its focus to the profit of the newly checked one to have a real value change, the interpretation of Gecko kind of make sense.





Comment 11 Germain Garand 2005-03-15 12:26:23 UTC
to sum it up, I think the best for radio would be:
   if(activated && hasFocus()) { 
       ref(); 
       element()->onChange(); 
       deref(); 
   } 
 
(not tested)

No idea what we should do for checkboxes though ;(
Comment 12 Allan Sandfeld 2005-03-15 12:54:23 UTC
The state of individual buttons in a radio-group is either "checked" or "indeterminate".

I still believe the only real bug is that we fire the onChange event on load and possibly that we fire it on script changes.
Comment 13 Mario Weilguni 2005-03-15 19:05:36 UTC
CVS commit by mario: 

BUG:97796
RadioButtons do not call their onChange trigger anymore if they are
unchecked, only when they are checked. The triggers are no longer called
in the initialization phase (e.g. the checked attribute)

This is not a perfect solution, since the specs say that onChange trigger 
should fire when focus is lost, however, it's the same behaviour as Firefox
has. MSIE seems to follow the specs here and is slightly different.


  M +10 -4     render_form.cpp   1.285


--- kdelibs/khtml/rendering/render_form.cpp  #1.284:1.285
@@ -163,4 +163,8 @@ RenderRadioButton::RenderRadioButton(HTM
     b->setMouseTracking(true);
     setQWidget(b);
+
+    // prevent firing toggled() signals on initialization
+    b->setChecked(element->checked());
+
     connect(b,SIGNAL(toggled(bool)),this,SLOT(slotToggled(bool)));
 }
@@ -186,9 +190,11 @@ void RenderRadioButton::calcMinMaxWidth(
 }
 
-void RenderRadioButton::slotToggled(bool)
+void RenderRadioButton::slotToggled(bool activated)
 {
+    if(activated) {
     ref();
     element()->onChange();
     deref();
+    }
 }
 
Comment 14 David Faure 2005-03-29 19:10:05 UTC
CVS commit by faure: 

Apply the fix for #97796 (radiobuttons emit onChange on loading) to checkboxes too.
Testcase from ysm: <input type="checkbox" checked=true onchange="alert('onchange')"/>
Will create testregression testcases now.
CCBUG: 97796


  M +4 -0      render_form.cpp   1.286


--- kdelibs/khtml/rendering/render_form.cpp  #1.285:1.286
@@ -122,4 +122,8 @@ RenderCheckBox::RenderCheckBox(HTMLInput
     b->setMouseTracking(true);
     setQWidget(b);
+
+    // prevent firing toggled() signals on initialization
+    b->setChecked(element->checked());
+
     connect(b,SIGNAL(stateChanged(int)),this,SLOT(slotStateChanged(int)));
 }
Comment 15 Leonardo Piseri 2005-12-16 10:52:37 UTC
it seems like the patch haven't been applied... the bug is still present in konqueror 3.4.3 (Debian unstable)
Comment 16 Thiago Macieira 2005-12-16 11:37:59 UTC
They were applied, but not to 3.4.

You have to upgrade to 3.5 to see the fixes.