Archive for January, 2008

SortableDataProvider vs. ListDataProvider

January 26, 2008

I implemented a data view that has a column for sorting data similar to wicket example. However I started testing it and it turned out that pageable navigation didn’t work. I started debugging and found out that it works (you can page through) with a simple ListDataProvider implementation however it doesn’t work with SortableDataProvider. I almost went to the forum to ask a question, when i noticed this little caveat. It is required to implement iterator() method in SortableDataProvider, meanwhile it is NOT required to do so in ListDataProvider. And it turns out there is a reason for it.

Because list implementation is not sortable, list view for any page will not change. That means you can click page 1 and get items (a,d,e,b,c). Then you can click page 2 and you can get items (f,h,g,j,i). And so on…

However if you have a sortable list that is also pageable if you sort the list, the contents must change:

it should be

page1 – (a,b,c,d,e)

page2 – (f,g,h,i,j)

Because of that the iterator stub has 2 arguments (first, count). First is the first element on the page, and count how many records are on the page. Therefore, if you want to sort the whole list, but return only the data relevant to the page you are on, you should do

public Iterator iterator(int first, int count) {

.

.

.

Collections.sort (list, new LetterComparator())

.

.

.

return list.sublist(first, first + count).iterator;

}

Conditional Rendering: Revisited

January 14, 2008
In the previous post, I said that conditional rendering in Wicket is not straightforward. Turns out I was wrong. Starting at Wicket 1.3, there is an XHTML tag wicket:enclosure.Conditional rendering inWicket is much easier, because wicket:enclosure allows for scoped visibility. The premise is that all of the wicket components in it’s range can have it’s visibility attribute changed based on one of the components enclosed by wicket:enclosure tag.Click here for an example. Thank you Alex!

Conditional Rendering

January 12, 2008

If you want to render a component in Wicket conditionally, it is not as straightforward. Wicket generates component hierarchy based on java and markup files. Therefore you can’t have a conditional if-else in java because markup(html) doesn’t support if-else. A workaround is to hide the component.We can create a component adaptor that will wrap our component that needs to be conditionally rendered. Adaptor will extend Border class.

import org.apache.wicket.Component;
import org.apache.wicket.markup.html.border.Border;

public abstract class ConditionalRenderAdaptor extends Border {
/**
* Component that provides conditional rendering to the child component
*
* @param id
* @param child
*/
public ConditionalRenderAdaptor(String id, Component child) {
super(id);
add(child);
setVisible(renderCondition());
}

public abstract boolean renderCondition ();
}

And the markup looks like this

<wicket:border>
<table width=”0%” border=”0″>
<tr>
<td width=”0%” valign=”top”>
<wicket:body/>
</td>
</tr>
</table>
</wicket:border>

Example

You want to hide an instance of class Record, if the user hasn’t registered yet and show it if the user has registered.Extend ConditionalRenderAdaptor and provide an implementation for renderCondition().

class Record extends ConditionalRenderAdaptor {

private static final long serialVersionUID = 1L;

public Record() {
super(“record”, new Label(“User Name”, new Model (user.getUserName() )) );
}

@Override
public boolean renderCondition() {
return user != null;
}

}

You can use it like this:

class HomePage extends WebPage {

….

Record userRecord= new Record ();

add(userRecord);

}

and in the markup:

<span wicket:id=”record” >

<tr>

<td>

<span wicket:id=”userName”>some value</span>

</td>

</tr>

</span>

“userName” will only show if the user record exists.This is not a perfect solution and if anyone knows how to do actual conditional rendering please let me know!

Read the rest of this entry »