Skip to content


Wicket Ajax - IAjaxRegionMarkupIdProvider

Fast unbemerkt versammeln sich in den Wicket-Updates neben einer Reihe von Bugfixes kleine Anpassungen, die das Entwickeln mit Wicket einfacher machen können. Da man nicht bei jedem Update nachsieht, was sich verändert hat, weil die Erfahrung gezeigt hat, dass man bei Wicket eigentlich immer auf die aktuelle Version wechseln kann, läuft man Gefahr, dass man wichtige Anpassungen verpasst. Deshalb stelle ich heute eine Erweiterung von Wicket vor, die in meinen Augen ein erhebliches Potential bietet: das Interface IAjaxRegionMarkupIdProvider .

Über dieses Interface ist es möglich, Wicket mitzuteilen, welches Seitenelement in einem Ajax-Response eigentlich ersetzt werden soll. So ist es möglich, z.B. in einem Behavior vor und nach der Komponente Html-Markup einzufügen, dass bei Aktualisierung der Komponente ebenfalls ersetzt wird. Was sich kompliziert anhört ist in der Anwendung recht einfach. Wir implementieren ein Interface, dass einen roten Rahmen um eine Komponente ziehen soll, die per Ajax aktualisiert wird.

package de.wicketpraxis.web.blog.pages.questions.ajax.behavior;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.IAjaxRegionMarkupIdProvider;
import org.apache.wicket.behavior.AbstractBehavior;


public class AjaxRegionBehavior extends AbstractBehavior implements IAjaxRegionMarkupIdProvider {

  @Override
  public void beforeRender(Component component) {
    component.getResponse().write("<div style=\"border:1px solid red;\" id=\""+getAjaxRegionMarkupId(component)+"\">");
    super.beforeRender(component);
  }
  
  @Override
  public void onRendered(Component component) {
    super.onRendered(component);
    component.getResponse().write("</div>");
  }
  
  @Override
  public String getAjaxRegionMarkupId(Component component) {
    return component.getMarkupId()+"_border";
  }
  
}

Das Behavior funktioniert wie folgt: In beforeRender() und in onRendered() wird um die Komponente herum ein div-Tag mit passender Style-Anweisung geschrieben. Hierbei muss in beforeRender() die id des Tags auf den Wert gesetzt werden, den Wicket dann auch über die Interface-Methode getAjaxRegionMarkupId() bekommt. Das führt dazu, dass Wicket die Ersetzung per Ajax automatisch auf den durch das Behavior definierten Rahmen, eben die ID, die per getAjaxRegionMarkupId() definiert wurde, ausweitet.

Die Anwendung ist recht einfach:

package de.wicketpraxis.web.blog.pages.questions.ajax.behavior;

import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.model.Model;


public class AjaxRegionPage extends WebPage {

  
  private Model<Integer> _counter;

  public AjaxRegionPage() {
    
    _counter = Model.of(0);
    final Label label=new Label("label",_counter);
    label.setOutputMarkupId(true);
    label.add(new AjaxRegionBehavior());
    add(label);
    
    add(new AjaxLink<Integer>("link",_counter) {
      @Override
      public void onClick(AjaxRequestTarget target) {
        setModelObject(1+getModelObject());
        target.addComponent(label);
      }
    });
  }
}

Wie man im Code-Beispiel sehen kann, wird das Behavior zur Komponente hinzugefügt. Würde man das Interface nicht implementieren, würden bei jeder Aktualisierung immer neue rote Rahmen um die Komponente entstehen.

<html>
  <head>
    <title>AjaxRegion Page</title>
  </head>
  <body>
    <span wicket:id="label"></span>
    <a wicket:id="link">Count</a>
  </body>
</html>

Bisher war es nötig, diese Anforderung immer auf Komponenten abzubilden, die dann korrekt ersetzt werden mussten. Damit ist es jetzt sehr viel einfacher möglich, Eine Komponente zu dekorieren und diese Dekoration auch per Ajax korrekt zu ersetzten. Auch wenn der erste Gedanke einer Anwendung sich vermutlich um Formularfelder mit fehlerhaften Eingaben dreht, gibt es unzählige Möglichkeiten, wo diese Funktionalität die Entwicklung nachhaltig vereinfachen wird.

Veröffentlicht in Allgemein, .