|
Hi Wicket people!
I am working in a project with Wicket and encountered what I think may be a bug in Wicket 1.4.x. The suspected bug is in org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#generateCallbackScript. On lines 185 - 190 of AbstractDefaultAjaxBehavior.js (1.4.16) it reads: if (!Strings.isEmpty(indicatorId)) { String hide = ";Wicket.hideIncrementally('" + indicatorId + "');"; success = success + hide; failure = failure + hide; } Here it is generating the Javascript code to hide the busy indicator. Then, later on in that same method, on lines 229 to 249 it reads: if (!Strings.isEmpty(indicatorId)) { final AppendingStringBuffer indicatorWithPrecondition = new AppendingStringBuffer( "if ("); if (precondition != null) { indicatorWithPrecondition.append("function(){") .append(precondition) .append("}.bind(this)()"); } else { indicatorWithPrecondition.append("true"); } indicatorWithPrecondition.append(") { Wicket.showIncrementally('") .append(indicatorId) .append("');}") .append(call); call = indicatorWithPrecondition; } As you can see the code for generating the Wicket.showIncrementally call is a lot more complex that that for generating the Wicket.hideIncrementally call, which is weird as these are two sides of the same coin. Methods to these calls need to be balanced. The resulting Javascript code looks like this: if (condition) {Wicket.hideIncrementally()} var wcall = <ajax call code>; Wicket.showIncrementally(); The 'if (condition)' block is only around the hideIncrementally, but should also be around the showIncrementally. Now, in some circumstances (when condition == true), the indicator is not hidden, but then is shown. This makes the calls unbalanced and the busy indicator never stops spinning. Because of the way these functions work, this is not recovered from anymore, the busy indicator does not stop until we do a full page reload. I checked the sources of Wicket 1.5, and I think the same problem is in there as well. I am not a Wicket Developer but I would be willing to create a patch if there are clear instructions how to do that (haven't found them so far). However with a bit of luck (for me :) a Wicket Dev can make this fix? I think it's just a matter of surrounding the call to Wicket.showIncrementally with the same 'if (condition)' as is around Wicket.hideIncrementally... <small>EDIT: Escaped HTML brackets that were removed by Nabble</small> |
|
Ok I found the instructions to create a patch:
http://wicket.apache.org/contribute/patch.html I will look into that when I get some time. |
|
In reply to this post by Stijn
|
|
In reply to this post by Stijn
UPDATE: Igor Vaynberg has commented on the JIRA issue. He states that the code is correct.
I will immediately admit that I am no Wicket expert by far, so I could be wrong. But I am sure I see the problem with the busy indicator happening; it never stops spinning. So if the code generated by AbstractDefaultAjaxBehavior is correct, there must be something wrong in the way we use it. Here is the javascript code, copied from the link around the icon that, once clicked, causes the busy indicator to spin. An AJAX request is fired and the response is handled correctly. All is as expected except for the busy indicator, which never stops spinning. (I split it up in an attempt to improve on the readability) HTML: ------ <A id=actionButton6586 class=actionButton onclick="<javascript code>" href="<url>" wicketFocusSet="true"> <SPAN class=actionButtonLabel title=Acquired>Acquired</SPAN> </A> Javascript code: ---------------- if (function() {return Wicket.$('actionButton6586') != null;}()) { Wicket.showIncrementally('busy'); } var wcall=wicketAjaxGet( '<url>', function() { ;Wicket.hideIncrementally('busy');}.bind(this), function() { ;Wicket.hideIncrementally('busy');}.bind(this), function() {return Wicket.$('actionButton6586') != null;}.bind(this) ); return !wcall; The original fragment is below for reference. The icon button that this Javascript is on is part of a dialog that closes once the button is pressed. I now suspect that may be the cause of the problem? Here is the Java code we use to create this dialog and make it IAjaxIndicatorAware. Java code (just the most important stuff): ----------------------------------------- public abstract class PlanonWebBaseDialog extends PnWebGenericWebBaseDialog implements IModalDialogManager { protected class DialogButton extends PnWebButton implements IAjaxIndicatorAware { public final String getAjaxIndicatorMarkupId() { return getAjaxIndicatorId(); } private void onClick() throws PnErrorListException, AuthorizationException { // Do not fire button events when an other dialog is showing // Happens when pressing the button triggers the showing of another dialog if (!hasDialog() && doAction()) { close(PnSession.getAjaxRequestTarget()); } } } // ... } So the base class we use for a dialog has a DialogButton nested class that implements IAjaxIndicatorAware. The actual dialogs in our application are subclasses of this class and instantiate DialogButtons for the OK and Cancel buttons etc. The getAjaxIndicatorId is on the dialog itself and searches for the parent element that is IAjaxIndicatorAware and delegates to it's getAjaxIndicatorMarkupId to finally determine the markup ID of the busy indicator that is on the main page. I suspect we may have done something wrong there, because if I change the dialog and DialogButton in such a way that PlanonWebBaseDialog implements IAjaxIndicatorAware instead of the DialogButton, the issue with the busy indicator spinning forever disappears. Can you see from the generated markup whether we are returning the correct indicator markup ID? Can you explain why moving the 'implements IAjaxIndicatorAware' from the button to the dialog itself solves the issue? Sorry for polluting JIRA. :) Original fragment: ----------------- <A id=actionButton6586 class=actionButton onclick="if (function(){return Wicket.$('actionButton6586') != null;}()) { Wicket.showIncrementally('busy');}var wcall=wicketAjaxGet('?wicket:interface=:17:modalWindow:content:buttonForm:actionOnSelectionPanel:actionGroupList:2:actionList:1:actionButton::IBehaviorListener:0:-1',function() { ;Wicket.hideIncrementally('busy');}.bind(this),function() { ;Wicket.hideIncrementally('busy');}.bind(this), function() {return Wicket.$('actionButton6586') != null;}.bind(this));return !wcall;" href="http://localhost:8070/Hera/clientWithLaunchCenter/?wicket:interface=:17:modalWindow:content:buttonForm:actionOnSelectionPanel:actionGroupList:2:actionList:1:actionButton::ILinkListener::" wicketFocusSet="true"><SPAN class=actionButtonLabel title=Acquired>Acquired</SPAN></A> |
| Powered by Nabble | Edit this page |
