Reputation: 9011
So essentially I want to use Wicket 1.5 to display an item and its associated quantity. The data structure I am using to back this is a Map (new HashMap()) where Item is a POJ whose details are of no consequence. Essentially I would like to use one of wicket's repeaters, but I only have experience using ListView. Is there a repeater that would work well with a Map, or am I going to need to code my own? If I need to code my own, what is the best class to override?
I would the output of the repeater to essentially be something like:
QuantityX : ItemName (ItemNum)
so for example:
2x : someItem (255609)
The map can change through user input, but I am familiar with refreshing component's markup with AJAX via Wicket. Your help is much appreciated.
Upvotes: 3
Views: 2054
Reputation: 46876
See this article: Wicket Model magic: Map-backed ListView
public CustomFieldsPanel( String id, final IModel<Map<String,ProductCustomField>> fieldMapModel, final FeedbackPanel feedbackPanel ) {
super( id, fieldMapModel );
this.feedbackPanel = feedbackPanel;
this.setOutputMarkupId( true ); // AJAX JavaScript code needs to have some id="...".
IModel<List<ProductCustomField>> listModel = new LoadableDetachableModel() {
@Override protected List<ProductCustomField> load() {
Map<String,ProductCustomField> map = (Map) CustomFieldsPanel.this.getDefaultModelObject();
return new ArrayList(map.values());
}
};
ListView<ProductCustomField> listView;
add( listView = new ListView<ProductCustomField>("fieldsRows", listModel){
@Override
protected void populateItem( final ListItem<ProductCustomField> item ) {
item.add( new CustomFieldRowPanel("fieldRow", item.getModel()){
// Delete icon was clicked.
@Override
protected void onDelete( AjaxRequestTarget target ) {
Map<String,ProductCustomField> fieldsMap = (Map) CustomFieldsPanel.this.getDefaultModelObject();
fieldsMap.remove( item.getModelObject().getName() );
target.add( CustomFieldsPanel.this ); // Update UI.
try {
CustomFieldsPanel.this.onChange( target ); // Persists.
} catch (Exception ex){
feedbackPanel.error( ex.toString() );
}
}
});
}
});
...
}
Upvotes: 0
Reputation: 9011
I ended up using ListView where the ListView Model held Map.Entry as suggested by Thorsten above. It works as intended, and thank you Thorsten.
Upvotes: 1
Reputation: 420
One option would be to use your Listview and feeding it with a list you can retrive from the map like Arrays.asList(HashMap#values#toArray)
Generally I prefer the Loop to Reapeat stuff, because you just provide an Integer Model like AbstractReadOnlyModel to define the number of iterations. In this case you can easyly build your own models an helper methods to get the data from anywhere.
I you really want to build your own repeater you should extend AbstractRepeater but you should rather build around Loop.
Upvotes: 0