Ask confirmation on link clicks with Wicket

30 11 2006

An often asked question is how to show a confirmation dialog before ‘comitting’ a link. The easiest way to do that is something like this:

Link remove = new Link("removeFieldLink") {
  @Override
  public void onClick() {
    FieldDefinition definition = (FieldDefinition) item.getModelObject();
    programService.deleteFieldDefinition(definition);
  }
};
remove.add(new SimpleAttributeModifier(
      "onclick", "return confirm(’remove definition?’);"));

But say you don’t want to do this by using JavaScript? Make it an abstract reusable component, like Ed Eustace did for Teachscape and use it like this:

Link remove = new Link("removeFieldLink") {
  @Override
  public void onClick() {
    ManageProfileFieldsPanel.this.replaceWith(
      new ConfirmDeletePanel(ManageProfileFieldsPanel.this.getId(),
        "really delete?") {
      @Override
      protected void onCancel() {
        this.replaceWith(ManageProfileFieldsPanel.this);
      }
      @Override
      protected void onConfirm() {
        FieldDefinition definition =
          (FieldDefinition) item.getModelObject();
        programService.deleteFieldDefinition(definition);
        this.replaceWith(ManageProfileFieldsPanel.this);
      }
    });
  }
};

Note the replaceWith trick. The ConfirmDeletePanel doesn’t have to know about what context it runs in, and we’re creating it with same id as the component we’re going to replace (the current this, ManageProfileFieldsPanel.this).

The ConfirmDeletePanel can be written like this:

public abstract class ConfirmDeletePanel extends Panel {
  public ConfirmDeletePanel(String id, String message) {
    super(id);
    add(new Label("message", message));
    add(new Link("confirm") {
      @Override
      public void onClick() {
        onConfirm();
      }
    });
    add(new Link("cancel") {
      @Override
      public void onClick() {
        onCancel();
      }
    });
  }
  protected abstract void onCancel();
  protected abstract void onConfirm();
}

and I’m sure you can think of some suitable HTML that goes with it :)

 

UPDATE: I just looked at this again, and realized you could make it work more magical if you prefer to save a few strokes.

public abstract class ConfirmDeletePanel extends Panel {
  private final WebMarkupContainer previous;

  private ConfirmDeletePanel(WebMarkupContainer parent, String message) {
    super(parent.getId());
    this.previous = parent;
    parent.replaceWith(this);
    add(new Label("message", message));
    add(new Link("confirm") {
      @Override
      public void onClick() {
        onConfirm();
        ConfirmDeletePanel.this.replaceWith(previous);
      }
    });
    add(new Link("cancel") {
      @Override
      public void onClick() {
        onCancel();
      }
    });
  }

  protected void onCancel() {
    ConfirmDeletePanel.this.replaceWith(previous);
  };

  protected abstract void onConfirm();
}

which can then be used like this:

Link remove = new Link("removeFieldLink") {
  @Override
  public void onClick() {
     new ConfirmDeletePanel(ManageProfileFieldsPanel.this, "really delete?") {
      @Override
      protected void onConfirm() {
        FieldDefinition definition =
          (FieldDefinition) item.getModelObject();
        programService.deleteFieldDefinition(definition);
      }
    });
  }
};

I think I prefer the more explicit version myself, but if you like your code more compact, this might work for you :-)





Added Russian locale

26 11 2006

And… thanks to Dmitry Kandalo, we now have a Russian version of the FormInput example (and the default validators). Keep ‘em coming!

Screenshot Russian FormInput example





Wicket now supports resource bundles in XML format

13 11 2006

Since a few days, Wicket (2.0) supports loading properties in the XML format that Java supports since version 5. The great advantage of this is that you can maintain your localized messages in any encoding you like, without having to do ugly things like using the unicode escpace codes.

As a bonus I converted Wicket 2.0’s examples to use just one HTML file, and use message bundles (both properties and xml format) for all the localized strings. This is a much better pattern then using a separate HTML file for each locale.

Check out 2.0’s FormInput example to see for yourself.





Added Thai to FormInput example

13 11 2006

And the latest translation for the form input example is Thai. Thanks for giving the translations Tor Sampaongern!

form-input-thai.png





Chinese Wicket book available now

3 11 2006

We just got a message on the wicket-user list that Wang Lei finished his Chinese book on Wicket. Very cool indeed!

I tried to learn Chinese for a couple of months when I worked in China (another profession, long time ago), but I didn’t get much further then a couple of scentences, trying to get the tones right. And on-line translation tools only go so far :)

So, I couldn’t tell you much about this book, other than that it rocks there is one in the first place! Thanks Wang Lei.