package org.nocket.component.button;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
import org.apache.wicket.request.resource.JavaScriptResourceReference;
import org.apache.wicket.request.resource.PackageResourceReference;
import org.apache.wicket.request.resource.ResourceReference;
// TODO: Auto-generated Javadoc
/**
* TheDMDOnClickIndicatorAttributeModifier is adds a blocker overlay script to
* ajax buttons and links. The script call is added upfront to the onlick event.
* If a button is clicked, we call a javascript function which activates a overlay
* div to the page and filters all keypressed and keydown events. The overlay div
* blocks the mouse and keyboard input and shows a loading indicator
* image next to a "Please wait" text.
*
* See blocker.js for the javascript functions in this package and the mighty
* org.nocket.less file for css of the blocker div.
*
* This indicator is basically added to all generated buttons. To prevent showing of it
* on certain elements just add data-show-overlay="no" to the corresponsding HTML attribute
* tag.
*
* @author wund013, blaz02
*/
public class DMDOnClickIndicatorAttributeModifier extends AttributeModifier {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The Constant BLOCKER_SCRIPT. */
private static final String BLOCKER_SCRIPT = "block('%s', '%s', '%s');";
/** The Constant BLOCKER_REMOVE_SCRIPT. */
private static final String BLOCKER_REMOVE_SCRIPT = "unblock();";
/** The Constant LOADING_TITLE. */
private static final String LOADING_TITLE = "loading.title";
/** The Constant OVERLAY_ICON. */
private static final String OVERLAY_ICON = "blockericon.gif";
/** The Constant BLOCKER_JS. */
private static final String BLOCKER_JS = "blocker.js";
/** The Constant ONCLICK. */
private static final String ONCLICK = "onclick";
/** The Constant INDICATOR. */
private static final ResourceReference INDICATOR = new PackageResourceReference(
DMDOnClickIndicatorAttributeModifier.class, OVERLAY_ICON);
/**
* Constructor of the DMDOnClickIndicatorAttributeModifier. Just create a
* new instance and attach it to a AjaxLink, AjaxSubmitLink or AjaxButton.
*
* @param parent
* A parent component is needed to load the indicator text from a
* property file attached to the main page. We use the component
* to finde the page.
*/
public DMDOnClickIndicatorAttributeModifier(final Component parent) {
super(ONCLICK, new LoadableDetachableModel<String>() {
private static final long serialVersionUID = 1L;
/**
* @see org.apache.wicket.model.LoadableDetachableModel#load()
*/
@Override
protected String load() {
return String.format(BLOCKER_SCRIPT, parent.getMarkupId(), getIndicatorUrl(),
parent.getString(LOADING_TITLE));
}
/**
* @return url of the animated indicator image
*/
private CharSequence getIndicatorUrl() {
return RequestCycle.get().urlFor(new ResourceReferenceRequestHandler(INDICATOR));
}
});
}
/**
* We override the newValue method of the AttributeAppender to create a
* AttributePrepender. Scripts are add pre the normal wicket onclick
* scripts.
*
* @param currentValue the current value
* @param replacementValue the replacement value
* @return the string
* @see org.apache.wicket.AttributeModifier#newValue(java.lang.String,
* java.lang.String)
*/
@Override
protected String newValue(String currentValue, String replacementValue) {
return super.newValue(currentValue, replacementValue + currentValue);
}
/**
* Returns the Blocker remove script. Add this script to your
* {@link AjaxRequestTarget} to remove the blocker overlay.
*
* @return the blocker remove script
*/
public static String getBlockerRemoveScript() {
return BLOCKER_REMOVE_SCRIPT;
}
/**
* We override the model value of the replacement model if a component is
* deactivated. No deactivated component should have a onclick blocker.
*
* @param component the component
* @see org.apache.wicket.behavior.Behavior#onConfigure(org.apache.wicket.Component)
*/
@SuppressWarnings("unchecked")
@Override
public void onConfigure(Component component) {
if (!(component.isEnabled() && component.isEnableAllowed())) {
((IModel<String>) getReplaceModel()).setObject(StringUtils.EMPTY); // Wicket m(
}
super.onConfigure(component);
}
/**
* RenderHead adds the blocker javascript file to the page.
*
* @param component the component
* @param response the response
* @see org.apache.wicket.behavior.Behavior#renderHead(Component, IHeaderResponse)
*/
@Override
public void renderHead(Component component, IHeaderResponse response) {
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(
DMDOnClickIndicatorAttributeModifier.class,
BLOCKER_JS)));
super.renderHead(component, response);
}
}