Reputation: 1093
Hy guys I'm newbie in Wicket and I'm start playing this framework. I know will be a very useless example but I try to use that for learn wicket basics. This is my situation:
I get a page IndexPage.java that is composed from basically 2 panel, the first one is ListCheesePanel.java ( it basically show a list of cheese with price,etc and a button for to add to the cart the selected cheese) and the second one is CartPanel.java that is essentially a cart wherein you have all the selected cheeses and you can proceed to checkOut.
I would basically add on cheese from my list to the cart using ajax behaviour:
ListCheesePanel.java
public abstract class ListCheesePanel extends GenericPanel<List<Cheese>>{
private static final long serialVersionUID = 1L;
public ListCheesePanel(String id,final IModel<List<Cheese>> listCheeseModel) {
super(id,listCheeseModel);
PageableListView<Cheese> cheeses = new PageableListView<Cheese>("cheeses", listCheeseModel, 4) {
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(final ListItem<Cheese> item) {
Cheese cheese = (Cheese) item.getModelObject();
item.addOrReplace(new Label("name", Model.of(cheese.getName())));
item.addOrReplace(new Label("description", Model.of(cheese.getDescription())));
item.addOrReplace(new Label("price", Model.of("$ " + cheese.getPrice())));
item.addOrReplace(new AjaxFallbackLink<Cheese>("add",item.getModel()) {
private static final long serialVersionUID = 1L;
@Override
public void onClick(AjaxRequestTarget target) {
elementClicked(target, item.getModelObject());
}
});
}
};
addOrReplace(cheeses);
addOrReplace(new PagingNavigator("navigator", cheeses));
}
protected abstract void elementClicked(AjaxRequestTarget target,Cheese cheese);
}
elementClicked
is a method that must be ovverride in order to indicate the cheese and the target.
CartPanel.java
public abstract class CartPanel extends GenericPanel<Cart>{
private static final long serialVersionUID = 1L;
private WebMarkupContainer cartContainer;
private ListView<Cheese> cheesesList;
private Link<Cart> checkOutLink;
private boolean checkOutButtonVisibility;
public CartPanel(String id,final IModel<Cart> cartModel,final boolean checkOutButtonVisibility) {
super(id,cartModel);
this.checkOutButtonVisibility=checkOutButtonVisibility;
cartContainer = new WebMarkupContainer("cartContainer");
cartContainer.setOutputMarkupId(true);
addOrReplace(cartContainer);
cheesesList = new ListView<Cheese>("cart" , getModelObject().getCheeses()){
private static final long serialVersionUID = 1L;
@Override
protected void populateItem(final ListItem<Cheese> item) {
Cheese cheese = item.getModelObject();
item.addOrReplace(new Label("name",cheese.getName()));
item.addOrReplace(new Label("price",cheese.getPrice()));
item.addOrReplace(new Link<Cheese>("remove",item.getModel()) {
private static final long serialVersionUID = 1L;
@Override
public void onClick() {
removeElement(item.getModelObject());
}
});
}
};
cheesesList.setOutputMarkupId(true);
cartContainer.addOrReplace(cheesesList);
cartContainer.addOrReplace(new Label("total",new PropertyModel<Long>(cartModel.getObject(), "total")));
checkOutLink = new Link<Cart>("checkOut",getModel()){
private static final long serialVersionUID = 1L;
@Override
public void onClick() {
setResponsePage(new CheckOutPage(getModel()));
}
@Override
protected void onConfigure() {
super.onConfigure();
Cart cart = cartModel.getObject();
List<Cheese> cheeseList = cart.getCheeses();
setVisible(isCheckOutButtonVisibility() && !cheeseList.isEmpty());
}
};
addOrReplace(checkOutLink);
}
protected abstract void removeElement(Cheese modelObject);
/* Getters and Setters */
public boolean isCheckOutButtonVisibility() {
return checkOutButtonVisibility;
}
}
IndePage.java
public class IndexPage extends CheeseTemplate {
private static final long serialVersionUID = 1L;
private static List<Cheese> cheeses = Arrays.asList(
new Cheese("Gouda", "Gouda is a yellowish Dutch[...]", 1.65),
new Cheese("Edam", "Edam (Dutch Edammer) is a D[...]", 1.05),
new Cheese("Maasdam", "Maasdam cheese is a Dutc[...]", 2.35),
new Cheese("Brie", "Brie is a soft cows' milk c[...]", 3.15),
new Cheese("Buxton Blue", "Buxton Blue cheese i[...]", 0.99),
new Cheese("Parmesan", "Parmesan is a grana, a [...]", 1.99),
new Cheese("Cheddar", "Cheddar cheese is a hard[...]", 2.95),
new Cheese("Roquefort", "Roquefort is a ewe's-m[...]", 1.67),
new Cheese("Boursin", "Boursin Cheese is a soft[...]", 1.33),
new Cheese("Camembert", "Camembert is a soft, c[...]", 1.69),
new Cheese("Emmental", "Emmental is a yellow, m[...]", 2.39),
new Cheese("Reblochon", "Reblochon is a French [...]", 2.99));
private IModel<List<Cheese>> allCheeseListModel;
private IModel<Cart> cartModel;
private Cart cart;
public IndexPage() {
super();
allCheeseListModel = new ListModel<Cheese>(cheeses);
cart=new Cart();
cartModel = new Model<Cart>(cart);
}
public IndexPage(IModel<Cart> cartModel) {
super();
allCheeseListModel = new ListModel<Cheese>(cheeses);
this.cartModel=cartModel;
}
@Override
public Component getMainPanel() {
System.out.println("getMainPanel started");
return new ListCheesePanel(MAIN_PANEL_WICKET_ID,allCheeseListModel){
private static final long serialVersionUID = 1L;
@Override
protected void elementClicked(AjaxRequestTarget target,Cheese cheese) {
Cart cart = cartModel.getObject();
cart.getCheeses().add(cheese);
target.add(?????); // How can i get the cart container to update????
}
};
}
@Override
public Component getRightMenuPanel() {
CartPanel cartPanel = new CartPanel(RIGHT_MENU_PANEL_WICKET_ID,cartModel,true) {
private static final long serialVersionUID = 1L;
@Override
protected void removeElement(Cheese cheese) {
Cart cart = cartModel.getObject();
cart.getCheeses().remove(cheese);
}
};
cartPanel.setOutputMarkupId(true);
return cartPanel;
}
}
My question is:
How can I get the reference of the component to update(so I think is cartContainer in my example because I can't add directly a listView component to the target) if this component is located in another panel??
Thanks in advance
Upvotes: 3
Views: 1487
Reputation: 20029
What I would do, and really like, is to work with events.
I define a global AjaxUpdateEvent like this:
public class AjaxUpdateEvent
{
public AjaxRequestTarget target;
public AjaxUpdateEvent( AjaxRequestTarget target )
{
this.target = target;
}
public AjaxRequestTarget getTarget()
{
return this.target;
}
}
Then, I subclass events that I'm interested in, for example CheeseAddedEvent extends AjaxUpdateEvent
Then, all the components that need to do something when an cheese is added have a onEvent()
@Override
public void onEvent( IEvent<?> event )
{
Object payload = event.getPayload();
@SuppressWarnings( "rawtypes" )
Class clazz = payload.getClass();
//or use isAssignableFrom() or instanceof or any method you like
if ( CheeseAddedEvent.class.equals( clazz ) )
{
CheeseAddedEvent e = ( (CheeseAddedEvent) payload );
e.target.add( this );
}
super.onEvent(event);
}
....
public void onClick(AjaxRequestTarget target)
{
this.send( this.getPage(), Broadcast.BREADTH, new CheeseAddedEvent( target ) );
}
....
Upvotes: 4