Quantcast
Channel: Categorized – Imran Tariq's Blog
Viewing all articles
Browse latest Browse all 9

Wicket: How to write a reusable modal window popup

$
0
0

Wicket is a Java framework for creating web frontends. It allows you to create a webpage in Java, combining all kinds of components into one page.

In many projects, a subset of user interface elements are repeated over the site. Depending on your project, you can have different selection panels or popups that are used multiple times.

In the following tutorial I describe a method to write your own application specific reusable modal window popup.
Start!

For this example, we use the ModalWindow component from Wicket Extensions.If you don’t know what a ModalWindow looks like, you can see a demo. (hint: try to drag and drop it or resize it)
The example from Wicket extensions

The default example from the Wicket Extensions site contains no real reusable components, besides the ModalWindow itself. The Page inside the ModalWindow is tightly coupled to the ModalWindow. It closes its containing ModalWindow and sets a result parameter of the parent page. The components can only be reused in exactly the same way.
How can we make this more reusable?

We can make this more reusable by making the content of the ModalWindow not aware of the ModalWindow itself. The content does not know what will happen when the containing Form (or other data) is submitted. But how can we do that? The magic words are: abstract methods.

Before we start, you can download the code here, so you can get the complete picture.

The image on the right contains the structure of the page and the components we are creating. The page contains a modal window, which in turn contains a content panel.
The Content Panel

Lets start with the content panel inside the ModalWindow popup. This panel contains a selection link, a selection button and a cancel button, created in the constructor:

public SelectContentPanel(String id) {
  super(id);
 
  // Create the form, to use later for the buttons
  Form form = new Form("form");
  add(form);
 
  // Add some example 'selection' methods, to show as example
  // You can also use a full fledged form, I left that as an
  // exercise for the reader :-)
  add(new AjaxLink("selectionLink"){
    public void onClick(AjaxRequestTarget target) {
      onSelect(target, new String("Selection using the link."));
    }
  });
 
  form.add(new AjaxButton("selectionButton"){
    protected void onSubmit(AjaxRequestTarget target, Form form) {
      onSelect(target, new String("Selection using the button."));
    }
  });
 
  // Add a cancel / close button.
  form.add(new AjaxButton("close") {
    public void onSubmit(AjaxRequestTarget target, Form form) {
      onCancel(target);
    }
  });

[..]

HTML:

<a>Select something</a> 
<form>
<input type="button" value="Select something else" />
<input type="button" value="Close" />
  </form>

You probably noticed the calls to onSelect() and onCancel(). These are the abstract methods we are declaring:

abstract void onCancel(AjaxRequestTarget target);
abstract void onSelect(AjaxRequestTarget target, String selection);

These methods are abstract, that way the code that is calling this panel must implement these methods. Because we are calling these methods, this effectively gives the result to the consuming code, without ever knowing what will happen with it.

To use abstract methods, the class itself must be abstract:
public abstract class SelectContentPanel extends Panel
The Modal Window

The Modal Window initializes itself with some values. You can just as easily set these values from the calling class, but for now we keep it local.

public SelectModalWindow(String id) {
    super(id);
 
    // Set sizes of this ModalWindow. You can also do this from the HomePage
    // but its not a bad idea to set some good default values.
    setInitialWidth(450);
    setInitialHeight(300);
 
    setTitle("Select something");
 
    // Set the content panel, implementing the abstract methods
    setContent(new SelectContentPanel(this.getContentId()){
        void onCancel(AjaxRequestTarget target) {
            SelectModalWindow.this.onCancel(target);
        }
 
        void onSelect(AjaxRequestTarget target, String selection) {
            SelectModalWindow.this.onSelect(target, selection);
        }
    });
}

HTML:

<a>Select something</a> 
<form>
<input type="button" value="Select something else" />
<input type="button" value="Close" />
  </form>

The setContent() function call is interesting. Here we create a new SelectContentPanel and implement the methods onCancel() and onSelect(). It is possible to do some extra actions here, but here it is passed one-on-one to the abstract methods of the ModalWindow itself:

abstract void onCancel(AjaxRequestTarget target);
abstract void onSelect(AjaxRequestTarget target, String selection);

The Home Page

The Home Page itself can now instantiate the ModalWindow, override the methods and do something with the data. One big advantage is that you can see from the HomePage class directly what is going to happen after the user selects something or cancels the action:

final ModalWindow selectModalWindow = new SelectModalWindow("modalwindow"){
 
  void onSelect(AjaxRequestTarget target, String selection) {
    // Handle Select action
    resultLabel.setModelObject(selection);
    target.addComponent(resultLabel);
    close(target);
  }
 
  void onCancel(AjaxRequestTarget target) {
    // Handle Cancel action
    resultLabel.setModelObject("ModalWindow cancelled.");
    target.addComponent(resultLabel);
    close(target);
  }
 
};
 
add(selectModalWindow);

Further customization

This example is just passing a String around, you can change it to a more specific class. You can change the onSelect to something more appropriate for your use case. You can even put a Form inside the panel and return the resulting object of the form


Viewing all articles
Browse latest Browse all 9

Trending Articles