In XPages gibt es bei Radio-Buttons im Zusammenhang mit einem Partial-Refresh bei einem onClick-Event einen ziemlich irreführenden Bug, wenn der Anwender auf das zugehörige Label klickt statt auf den Radio-Button selber.
Unmittelbar nach dem Anwender auf das Label geklickt hat, erscheint kurz die Änderung, um danach unmittelbar wieder den alten Stand anzuzeigen. Zur Verdeutlichung haben wir ein kleines Video vorbereitet.
Die Ursache für dieses Phänomen ist das Timing. Durch den Klick auf das Label, wird ein POST-Befehl für das Partial-Refresh ausgelöst. Zu diesem Zeitpunkt ist allerdings die Attributänderung des Radio-Buttons noch nicht angekommen, so dass noch der alte Werte übertragen wird. Das ist auch der Grund, warum magischer Weise über das Partial-Refresh der alte Stand wieder angezeigt wird.
Der Bug ist bei der IBM bekannt: LO71073: XPAGES RADIOBUTTON CLICK ON LABEL UNDONE BY PARTIAL REFRESH. Der aktuelle Status ist: "This APAR is closed as FIN. We have deferred the fix to a future release." Wobei FIN laut dem IBM Software Support Handbook für "der Fehler wird im nächsten Release gefixt" steht.
In der Zwischenzeit kann, wie so häufig, mit Hilfe von dojo Abhilfe geschaffen werden.
Der folgende Code sollte im Client-Side JavaScript onClick-Event hinterlegt werden.
var e = arguments[0] || window.event; e = dojo.fixEvent(e); if (e.target.type != "radio") { e.preventDefault(); dojo.query("input",e.target).forEach(function(inputNode){ dojo.attr(inputNode,"checked",!(dojo.attr(inputNode,"checked"))); }); } return true;
Das Event wird zunächst in der Variable e gespeichert. Mit dojo.fixEvent(e) wird der Unterschied im Eventhandling zwischen IE und den standardkonformen Browsern nivelliert.
Wenn auf das Label geklickt wurde (e.target.type != "radio"), dann wird zunächst das Standardverhalten des Events unterbunden (e.preventDefault()). Anschließend wird das zugehörige Input-Feld gesucht und das Attribute auf "checked" gesetzt.
Der dojo.query-Befehl funktioniert, weil die XPages Laufzeitumgebung ein Radio-Button wie folgt realisiert:
<label> <input type="radio" value="Banana" name="view:_id1:radioGroup1">Banana </label>
Das Input-Element ist also ein Kindelement des geklickten Labels. Somit kann über dojo.query("input", e.target) nach allen Input-Elementen unterhalb des Elementes gesucht werden, auf den das Event ausgelöst wurde. In unserem Fall also das Label.
Es sollte übrigens bei Radiobuttons und Checkboxes immer das onClick-Event verwendet werden, weil der IE beim onChange-Event ebenfalls ein Timing-Problem hat. Wenn im IE das onChange-Event ausgelöst wird, ist die Attributänderung auch noch nicht vollzogen.