Wednesday 24 April 2013

Panel which dynamically opens and closes in Wicket




Panel which dynamically opens and closes in Wicket

import java.text.MessageFormat;

import org.apache.wicket.Component;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.value.IValueMap;

public class CustomPanel extends Panel {
  private static final String SHOW_ALL_SCRIPT = "jQuery('a.panel-open').click()";

  private static final String HIDE_ALL_SCRIPT = "jQuery('a.panel-close').click()";

  public CustomPanel(final String id, final Component component) {
    this(id, component, new Model<Boolean>(true));
  }

  public CustomPanel(final String id, final Component component, final IModel<Boolean> open) {
    super(id, open);
    component.setOutputMarkupId(true);

    final WebMarkupContainer link = new WebMarkupContainer("link") {
      private static final String SCRIPT = "var panel = jQuery(''#{0}'');"
          + "var link = jQuery(this); var span = link.children();"
          + "link.toggleClass(''panel-close'').toggleClass(''panel-open'');"
          + "if (panel.css(''display'') == ''none'') "
          + "'{' panel.show(); span.text(''{1}''); link.attr(''title'', ''{3}''); '}'" + "else "
          + "'{' panel.hide(); span.text(''{2}''); link.attr(''title'', ''{4}''); '}'" + "return false;";

      @Override
      protected void onComponentTag(final ComponentTag tag) {
        super.onComponentTag(tag);
        if (!tag.isClose()) {
          final IValueMap attributes = tag.getAttributes();

          final Boolean isPanelOpen = getModel().getObject();
          if (isPanelOpen != null && isPanelOpen) {
            attributes.put("class", "panel-close");
            attributes.put("title", getCloseText());
          } else {
            attributes.put("class", "panel-open");
            attributes.put("title", getOpenText());
          }
          attributes.put("onclick", MessageFormat.format(SCRIPT, component.getMarkupId(), getCloseText(),
              getOpenText(), getClosePanelText(), getOpenPanelText()));
        }
      }

    };
    add(link);
    link.add(new Label("text", new AbstractReadOnlyModel<String>() {
      private static final long serialVersionUID = 1045024635866272771L;

      @Override
      public String getObject() {
        final Boolean isPanelOpen = getModel().getObject();
        if (isPanelOpen != null && isPanelOpen) {
          return getCloseText();
        } else {
          return getOpenText();
        }
      }
    }));
  }

  @Override
  protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {
    renderComponentTagBody(markupStream, openTag);
    super.onComponentTagBody(markupStream, openTag);
    // Render the body of the link

  }

  @SuppressWarnings("unchecked")
  protected IModel<Boolean> getModel() {
    return (IModel<Boolean>) getDefaultModel();
  }

  private String getCloseText() {
    return getString("close");
  }

  private String getOpenText() {
    return getString("open");
  }

  private String getClosePanelText() {
    return getString("closePanel");
  }

  private String getOpenPanelText() {
    return getString("openPanel");
  }

  public static AttributeAppender getShowAllBehavior() {
    return new AttributeAppender("onclick", true, new Model<String>(SHOW_ALL_SCRIPT), " ");
  }

  public static AttributeAppender getHideAllBehavior() {
    return new AttributeAppender("onclick", true, new Model<String>(HIDE_ALL_SCRIPT), " ");
  }

}


CustomPanel.html

<wicket:panel xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<a wicket:id="link" href="#">
<span wicket:id="text"></span>
</a>

</wicket:panel>