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>
i forgot to say: save the html code as testradio.html (the action of the form), you'll see the form is submitted automaticaly
Reproduceable for 3.4.0_beta1 Here's the testcase above: http://www.weilguni.net/bugs/testradio.html
Created attachment 10122 [details] Simpler testcase
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(); > }
I can't read that diff, but the bool makes sense. I'd say go ahead and commit
I think onChanged should fire everytime the state changes. So Konqueror is right and Firefox wrong. What does Opera and IE do?
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
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.
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.
> 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.
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 ;(
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.
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(); + } }
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))); }
it seems like the patch haven't been applied... the bug is still present in konqueror 3.4.3 (Debian unstable)
They were applied, but not to 3.4. You have to upgrade to 3.5 to see the fixes.