/*
* Copyright 2010 Richard Nichols.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* under the License.
*/
package com.visural.wicket.component.dialog;
import com.jquery.JQueryBGIFrameResourceReference;
import com.visural.javascript.JQueryCenterResourceReference;
import com.visural.wicket.component.submitters.impl.ModalCSSRef;
import com.visural.wicket.security.IPrivilege;
import com.visural.wicket.security.ISecureEnableInstance;
import com.visural.wicket.security.ISecureRenderInstance;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.AbstractBehavior;
import org.apache.wicket.behavior.IBehavior;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.CSSPackageResource;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.JavascriptPackageResource;
import org.apache.wicket.markup.html.WebMarkupContainer;
/**
* A modal dialog box which appears over other content.
*
* The dialog can be opened or closed by straight Javascript or by a
* Wicket AjaxRequestTarget.
*
* It can optionally be closed by clicking outside the dialog.
*
* @author Richard Nichols
*/
public class Dialog extends WebMarkupContainer implements ISecureEnableInstance, ISecureRenderInstance {
private static final long serialVersionUID = 1L;
private boolean clickBkgToClose = false;
public Dialog(String id) {
super(id);
setOutputMarkupId(true);
add(new AbstractBehavior() {
@Override
public void renderHead(IHeaderResponse response) {
response.renderOnDomReadyJavascript(getJS());
}
private String getJS() {
StringBuilder sb = new StringBuilder();
sb.append("if (jQuery('#")
.append(getDivId())
.append("').length == 0) { jQuery(document.body).append('")
.append(getDiv().replace("'", "\\'"))
.append("'); }");
return sb.toString();
}
private String getDivId() {
return getMarkupId() + "_ovl";
}
private String getDiv() {
if (isClickBkgToClose()) {
return ("<div id=\"" + getDivId() + "\" class=\"visuraloverlay\" onclick=\""+getCloseString()+"\"></div>");
} else {
return ("<div id=\"" + getDivId() + "\" class=\"visuraloverlay\"></div>");
}
}
});
if (autoAddToHeader()) {
add(JavascriptPackageResource.getHeaderContribution(new JQueryCenterResourceReference()));
add(CSSPackageResource.getHeaderContribution(new ModalCSSRef()));
if (isSupportIE6()) {
add(JavascriptPackageResource.getHeaderContribution(new JQueryBGIFrameResourceReference()));
}
}
}
/**
* Override and return false to suppress static Javascript and CSS contributions.
* (May be desired if you are concatenating / compressing resources as part of build process)
* @return
*/
protected boolean autoAddToHeader() {
return true;
}
@Override
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
tag.put("class", "visuraloverlaycontent");
}
/**
* Open using the current Ajax context.
* @param target
*/
public void open(AjaxRequestTarget target) {
target.appendJavascript(getOpenString());
}
/**
* Close using the current Ajax context.
* @param target
*/
public void close(AjaxRequestTarget target) {
target.appendJavascript(getCloseString());
}
/**
* Return a Behavior which when applied to a Component will add an "onlick"
* event handler that will open this Dialog.
* @return
*/
public IBehavior getClickToOpenBehaviour() {
return new AbstractBehavior() {
@Override
public void onComponentTag(Component component, ComponentTag tag) {
tag.put("onclick", getOpenString());
}
};
}
/**
* Return a Behavior which when applied to a Component will add an "onlick"
* event handler that will close this Dialog.
* @return
*/
public IBehavior getClickToCloseBehaviour() {
return new AbstractBehavior() {
@Override
public void onComponentTag(Component component, ComponentTag tag) {
tag.put("onclick", getCloseString());
}
};
}
/**
* Returns the Javascript required to open the dialog in the client browser.
* Override to prefix or postfix with your own javascript code.
* @return
*/
protected String getOpenString() {
if (!isEnabled()) {
return "";
}
StringBuilder result = new StringBuilder();
result.append("jQuery('#").append(getMarkupId()).append("_ovl').show();");
if (isSupportIE6()) {
result.append("jQuery('#").append(getMarkupId()).append("_ovl').bgiframe();");
}
result.append("jQuery('#")
.append(getMarkupId())
.append("_ovl').height(jQuery(document).height()); jQuery('#")
.append(getMarkupId())
.append("').center(); jQuery('#")
.append(getMarkupId())
.append("').show();");
return result.toString();
}
/**
* Returns the Javascript required to close the dialog in the client browser.
* Override to prefix or postfix with your own javascript code.
* @return
*/
protected String getCloseString() {
StringBuilder result = new StringBuilder();
result.append("jQuery('#").append(getMarkupId()).append("').hide();");
result.append("jQuery('#").append(getMarkupId()).append("_ovl').hide();");
return result.toString();
}
/**
* Override to enable BGI frame IE6 support.
* @return
*/
public boolean isSupportIE6() {
return false;
}
/**
* True if clicking the background will close the dialog.
* @return
*/
public boolean isClickBkgToClose() {
return clickBkgToClose;
}
/**
* Set whether the dialog should close when the user clicks the background (default: false);
* @param clickBkgToClose
*/
public void setClickBkgToClose(boolean clickBkgToClose) {
this.clickBkgToClose = clickBkgToClose;
}
public IPrivilege getRenderPrivilege() {
return IPrivilege.NULL;
}
public IPrivilege getEnablePrivilege() {
return IPrivilege.NULL;
}
}