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 :-)


Actions

Information

6 responses

30 11 2006
Closet Wicket lover

Just a small detail,

instead of

“if(!confirm(‘remove definition?’)) return false;”

in your first example, why not, more simply

“return confirm(‘remove definition?’);”

Cheers!
Closet Wicket lover

1 12 2006
Eelco Hillenius

Oh, common… that’s just too easy. Remember we’re building J(2)EE apps here! ;)

1 12 2006
ArchitectCoderSpotter

Igor once told me that writing such code makes you an (insert jaws theme here) ‘Architect Coder’

4 06 2008
Wicket and Tapestry compared « Chillenious!

[...] is – obviously – flexibility. For examples of what you can do with a dynamic tree, check out this post and this rant. Also, components like wizards and tab panels make heavy use of this in Wicket, and [...]

10 09 2008
Gustavo

you are a genius!!!
Excelent work!!!!
Tks!!!! ;)

9 07 2009
vela

Confirmation dialog box for AjaxFallbackButton.

A confirmation dialog should be displayed on submit of a AjaxFallbackButon.
If the user chooses the option (‘yes’ or ‘no’), then how to find out the option selected by the user.

Leave a comment