Monday, February 26, 2007

Completing the Tree

It seems like things are always easier to do when you've had a good night's rest. This morning I was able to finish adding AJAX to the message tree, with fallback and anchors, in about an hour.

Wicket provides a semi-magical component called AjaxFallbackLink that transparently allows your application to do AJAX if it is capable and falls back to a normal link if it is not. In typical Wicket fashion, the intrusiveness of AJAX is minimal, with much of the magic being handled behind the scenes. The one thing you have to watch out for is the case where the AjaxRequestTarget passed to onClick is null (which is what happens when you fell back).

Then the general paradigm is this:


public void onClick(AjaxRequestTarget target) {
doStuff();
if (target != null) {
doAjaxStuffToo();
}
}


The doAjaxStuffToo would typically involve doing some kind of replace operation in your Wicket page structure and then adding the modified part of the page structure to the target. In the event that AJAX isn't available, you don't have to worry about this, because the entire page is going to be re-rendered anyway.

Thanks to Igor Vaynberg for his help this morning in figuring that out.

Now one might naturally say, "but what about when AJAX isn't available? Won't the page refresh and put me way back up at the top of the page? That will be annoying!" Ordinarily it would, but Wicket makes this easy to deal with. You simply anchor your link to the Component you want (and so that Component needs to have setOutputMarkupId(true) called on it). It's as easy as calling setAnchor(parent) on your AjaxFallbackLink (or other type of Link).

Unfortunately, the setAnchor method defined by Link has the return type of void, so you can't be super lazy and define your Link and call setAnchor on it inside an add method on another component. This is easily worked around by just assigning your Link to something, calling setAnchor and then adding it. I have added WICKET-238 as a wishlist item for Wicket so that this operation is congruent with so many other Wicket operations that are "chainable".

Here's what a final bit of code looks like for handling navigation links. For the full source, look to the repository on tally-ho.dev.java.net.


private void addNavLinks(final TreeNode node, Fragment nodeFragment) {

if (!node.hasChildren()) {
nodeFragment.add(new WebMarkupContainer("nav").setVisible(false));
return;
}

Fragment navFragment = new Fragment("nav", "navigation");

if (node.hasOpenKids()) {
AjaxFallbackLink closeLink = new AjaxFallbackLink("closeLink") {

private static final long serialVersionUID = 1L;

public void onClick(AjaxRequestTarget target) {
node.closeKids();
if (target != null) {
parent.replace(new Entry("entry", root.getChildren(), parent));
target.addComponent(parent);
}
}

};
closeLink.setAnchor(parent);
navFragment.add(closeLink);

navFragment.add(new WebMarkupContainer("openLink").setVisible(false));
navFragment.add(new WebMarkupContainer("openAllLink").setVisible(false));

}

Labels:


Comments: Post a Comment





<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]