com.icesoft.faces.component.panelpopup.PanelPopupRenderer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icefaces-compat Show documentation
Show all versions of icefaces-compat Show documentation
${icefaces.product.name} Compat Component Library
/*
* Copyright 2004-2012 ICEsoft Technologies Canada Corp.
*
* 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.
*/
package com.icesoft.faces.component.panelpopup;
import com.icesoft.faces.component.ExtendedAttributeConstants;
import com.icesoft.faces.component.ext.renderkit.FormRenderer;
import com.icesoft.faces.component.ext.renderkit.GroupRenderer;
import com.icesoft.faces.component.paneltooltip.PanelTooltip;
import com.icesoft.faces.component.util.CustomComponentUtils;
import com.icesoft.faces.context.DOMContext;
import com.icesoft.faces.context.effects.JavascriptContext;
import com.icesoft.faces.context.effects.LocalEffectEncoder;
import com.icesoft.faces.renderkit.dom_html_basic.HTML;
import com.icesoft.faces.renderkit.dom_html_basic.PassThruAttributeRenderer;
import com.icesoft.faces.util.CoreUtils;
import com.icesoft.util.CoreComponentUtils;
import com.icesoft.util.pooling.ClientIdPool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import javax.faces.component.UIComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import java.io.IOException;
import java.util.Map;
/**
*
* PanelPopupRenderer is an extension of ICEfaces D2D GroupRenderer responsible
* for rendering the PanelPopup component.
*
*/
public class PanelPopupRenderer extends GroupRenderer {
private static Log log = LogFactory.getLog(PanelPopupRenderer.class);
// Basically, everything is excluded
private static final String[] PASSTHRU_EXCLUDE =
new String[]{HTML.STYLE_ATTR};
private static final String[] PASSTHRU_JS_EVENTS = LocalEffectEncoder.maskEvents(
ExtendedAttributeConstants.getAttributes(
ExtendedAttributeConstants.ICE_PANELPOPUP));
private static final String[] PASSTHRU =
ExtendedAttributeConstants.getAttributes(
ExtendedAttributeConstants.ICE_PANELPOPUP,
new String[][]{PASSTHRU_EXCLUDE, PASSTHRU_JS_EVENTS});
/*
* (non-Javadoc)
*
* @see com.icesoft.faces.renderkit.dom_html_basic.GroupRenderer#getRendersChildren()
*/
public boolean getRendersChildren() {
return true;
}
/*
* (non-Javadoc)
*
* @see com.icesoft.faces.component.ext.renderkit.GroupRenderer#encodeBegin(javax.faces.context.FacesContext,
* javax.faces.component.UIComponent)
*/
public void encodeBegin(FacesContext facesContext, UIComponent uiComponent)
throws IOException {
validateParameters(facesContext, uiComponent, PanelPopup.class);
String styleClass = (String) uiComponent.getAttributes().get(
"styleClass");
String headerClass = (String) uiComponent.getAttributes().get(
"headerClass");
String bodyClass = (String) uiComponent.getAttributes()
.get("bodyClass");
Boolean resizable = null; // resizable functionality has not been
// implemented yet.
Boolean modal = (Boolean) uiComponent.getAttributes().get("modal");
if (log.isTraceEnabled()) {
log.trace("Value of modal is [" + modal + "]");
}
Boolean visible = (Boolean) uiComponent.getAttributes().get("visible");
String dndType = getDndType(uiComponent);
DOMContext domContext = DOMContext.attachDOMContext(facesContext,
uiComponent);
// initialize DOMContext
PanelPopup panelPopup = (PanelPopup) uiComponent;
String clientId = uiComponent.getClientId(facesContext);
Element rootDiv = domContext.createRootElement(HTML.DIV_ELEM);
setRootElementId(facesContext, rootDiv, uiComponent);
rootDiv.setAttribute(HTML.NAME_ATTR, clientId);
if (uiComponent instanceof PanelTooltip) {
if (((PanelTooltip) uiComponent).isDynamic() && !((PanelTooltip) uiComponent).isVisible()) {
rootDiv.setAttribute(HTML.STYLE_ATTR, "display:none;");
domContext.stepOver();
return;
}
}
Element table = domContext.createElement(HTML.TABLE_ELEM);
table.setAttribute(HTML.CELLPADDING_ATTR, "0");
table.setAttribute(HTML.CELLSPACING_ATTR, "0");
// table.setAttribute(HTML.WIDTH_ATTR, "100%");
rootDiv.appendChild(table);
/*
Text iframe = domContext.createTextNode("");
rootDiv.appendChild(iframe);
*/
// extracted from GroupRenderer encodeBegin
if (dndType != null) {
// Drag an drop needs some hidden fields
Element statusField = createHiddenField(domContext,
facesContext, uiComponent, STATUS);
rootDiv.appendChild(statusField);
Element targetID = createHiddenField(domContext, facesContext,
uiComponent, DROP);
rootDiv.appendChild(targetID);
UIComponent form = findForm(uiComponent);
String formId = form.getClientId(facesContext);
FormRenderer.addHiddenField(facesContext, ClientIdPool.get(formId
+ UINamingContainer.getSeparatorChar(FacesContext.getCurrentInstance()) + HIDDEN_FIELD));
}
// Write Modal Javascript so that on refresh it will still be modal.
String script = modalJavascript(uiComponent, modal, visible, facesContext, clientId);
Element scriptWrapper = domContext.createElement(HTML.SPAN_ELEM);
scriptWrapper.setAttribute(HTML.ID_ATTR, ClientIdPool.get(clientId + "script"));
Element scriptEle = domContext.createElement(HTML.SCRIPT_ELEM);
scriptEle.setAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT);
Text scriptTextNode = domContext.createTextNodeUnescaped(script);
rootDiv.appendChild(scriptWrapper);
scriptWrapper.appendChild(scriptEle);
scriptEle.appendChild(scriptTextNode);
Element root = (Element) domContext.getRootNode();
try {
root.setAttribute(HTML.CLASS_ATTR, styleClass);
} catch (Exception e) {
log.error("Error rendering Modal Panel Popup ", e);
}
JavascriptContext.fireEffect(uiComponent, facesContext);
// get tables , our table is the first and only one
NodeList tables = root.getElementsByTagName(HTML.TABLE_ELEM);
// assumption we want the first table in tables. there should only be
// one
Element t = (Element) tables.item(0);
// clean out child nodes and build a fresh selectinputdate
DOMContext.removeChildrenByTagName(t, HTML.TR_ELEM);
doPassThru(facesContext, uiComponent, root);
String handleId = null;
if (panelPopup.getHeader() != null) {
Element headerTr = domContext.createElement(HTML.TR_ELEM);
Element headerTd = domContext.createElement(HTML.TD_ELEM);
headerTd.setAttribute(HTML.CLASS_ATTR, headerClass);
handleId = ClientIdPool.get(uiComponent.getClientId(facesContext) + "Handle");
headerTd.setAttribute(HTML.ID_ATTR, handleId);
// headerTd.setAttribute(HTML.STYLE_ATTR, "width:100%;");
headerTr.appendChild(headerTd);
Element headerTdSpacer = domContext.createElement(HTML.TD_ELEM);
Element headerDiv = domContext.createElement("div");
headerDiv.setAttribute(HTML.STYLE_ATTR, "width:1px;");
headerTdSpacer.setAttribute(HTML.CLASS_ATTR, headerClass);
headerTdSpacer.appendChild(headerDiv);
headerTr.appendChild(headerTdSpacer);
// add header facet to header tr and add to table
t.appendChild(headerTr);
// set the cursor parent to the new table row Element
// to the new table row Element
domContext.setCursorParent(headerTd);
UIComponent header = panelPopup.getHeader();
CustomComponentUtils.renderChild(facesContext, header);
}
if (panelPopup.getBody() != null) {
Element bodyTr = domContext.createElement(HTML.TR_ELEM);
Element bodyTd = domContext.createElement(HTML.TD_ELEM);
bodyTd.setAttribute(HTML.CLASS_ATTR, bodyClass);
bodyTr.setAttribute(HTML.ID_ATTR, ClientIdPool.get(clientId + "-tr"));
bodyTr.appendChild(bodyTd);
bodyTd.setAttribute(HTML.COLSPAN_ATTR, "2");
// add body facet to body tr then add to table
t.appendChild(bodyTr);
// set the cursor parent to the new table row Element
// this will cause the renderChild method to append the child nodes
// to the new table row Element
domContext.setCursorParent(bodyTd);
UIComponent body = panelPopup.getBody();
CustomComponentUtils.renderChild(facesContext, body);
}
// if the popup is resizable render a resize handle
if (resizable != null && resizable.booleanValue()) {
Element footerTr = domContext.createElement(HTML.TR_ELEM);
footerTr.setAttribute(HTML.HEIGHT_ATTR, "15px");
footerTr.setAttribute(HTML.STYLE_ATTR,
"text-align: right; float: right;");
Element footerTd = domContext.createElement(HTML.TD_ELEM);
footerTd.setAttribute(HTML.STYLE_CLASS_ATTR, "panelPopupFooter");
footerTd.setAttribute(HTML.COLSPAN_ATTR, "2");
Element img = domContext.createElement(HTML.IMG_ELEM);
img.setAttribute(HTML.SRC_ATTR, CoreUtils.resolveResourceURL(
facesContext, "/xmlhttp/css/xp/css-images/resize.gif"));
img.setAttribute(HTML.STYLE_ATTR, "cursor: se-resize");
footerTd.appendChild(img);
footerTr.appendChild(footerTd);
t.appendChild(footerTr);
}
panelPopup.applyStyle(facesContext, root);
domContext.stepOver();
// Rebroadcast Javascript to survive refresh
if (dndType != null) {
scriptTextNode.appendData("; Ice.DnD.adjustPosition('" + uiComponent.getClientId(facesContext) + "');");
StringBuffer dropCall = new StringBuffer();
String call = addJavascriptCalls(uiComponent, "DRAG", handleId,
facesContext, dropCall);
scriptTextNode.appendData("; " + call);
if (panelPopup.isClientOnly()) {
//the "submit" method in the dragdrop_custom.js would check for this
//element inside the panelPopup and will not fire submit if found
Element clientOnly = domContext.createElement(HTML.INPUT_ELEM);
clientOnly.setAttribute(HTML.TYPE_ATTR, "hidden");
clientOnly.setAttribute(HTML.ID_ATTR, clientId + "clientOnly");
root.appendChild(clientOnly);
}
}
// autoPosition handling
String autoPositionJS = null;
boolean positionOnLoadOnly = panelPopup.isPositionOnLoadOnly();
boolean dragged = panelPopup.isDragged();
String positions = panelPopup.getAutoPosition();
if (positions != null && !positions.equalsIgnoreCase("manual") && (!positionOnLoadOnly || (positionOnLoadOnly && !dragged))) {
if (positions.indexOf(',') < 1) {
if (positions.trim().length() != 0) {
log.warn("The autoPosition attribute should be used with an "
+ " x and y value for the position, such as '20,40'");
}
} else {
String x = positions.substring(0, positions.indexOf(','));
String y = positions.substring(positions.indexOf(',') + 1);
autoPositionJS = "Ice.autoPosition.start('" + clientId + "'," + x
+ "," + y + "," + positionOnLoadOnly + ");";
}
} else {
autoPositionJS = "Ice.autoPosition.stop('" + clientId + "');";
}
JavascriptContext.addJavascriptCall(facesContext, "; " + autoPositionJS);
// autoCentre handling
boolean autoCentre = panelPopup.isAutoCentre();
String centreJS;
if (autoCentre && (!positionOnLoadOnly || (positionOnLoadOnly && !dragged))) {
centreJS = "Ice.autoCentre.start('" + clientId + "'," + positionOnLoadOnly + ");";
} else {
centreJS = "Ice.autoCentre.stop('" + clientId + "');";
}
JavascriptContext.addJavascriptCall(facesContext, "; " + centreJS);
JavascriptContext.addJavascriptCall(facesContext, "; Ice.iFrameFix.start('" + clientId + "','" +
CoreUtils.resolveResourceURL(facesContext, "/xmlhttp/blank") + "');");
}
protected void doPassThru(FacesContext facesContext, UIComponent uiComponent,
Element root) {
PassThruAttributeRenderer.renderNonBooleanHtmlAttributes(uiComponent,
root, PASSTHRU);
LocalEffectEncoder.encode(
facesContext, uiComponent, PASSTHRU_JS_EVENTS, null, root, null);
}
private String modalJavascript(UIComponent uiComponent, Boolean modal, Boolean visible,
FacesContext facesContext, String clientId) {
String call = "";
String iframeUrl = CoreUtils.resolveResourceURL(facesContext,
"/xmlhttp/blank");
if (modal != null) {
if (modal.booleanValue() && visible.booleanValue()) {
String trigger = "";
// ICE-3563
if (!((PanelPopup) uiComponent).isRunningModal()) {
Map requestParameterMap = facesContext.getExternalContext().getRequestParameterMap();
if (requestParameterMap.get("ice.focus") != null) {
trigger = (String) requestParameterMap.get("ice.focus");
}
((PanelPopup) uiComponent).setRunningModal(true);
CoreComponentUtils.setFocusId("");
}
String autoPosition = (String) uiComponent.getAttributes().get("autoPosition");
boolean positionOnLoadOnly = ((Boolean) uiComponent.getAttributes().get("positionOnLoadOnly")).booleanValue();
call = "Ice.modal.start('" + clientId + "', '" + iframeUrl
+ "', '" + trigger + "'," + "manual".equalsIgnoreCase(autoPosition) + "," + positionOnLoadOnly + "," +
getIE8DisableModalFrame(facesContext) + ");" +
"ice.onElementRemove('" + clientId + "',function() {Ice.modal.stop('" +
clientId + "');});";
if (log.isTraceEnabled()) {
log.trace("Starting Modal Function");
}
} else {
// ICE-3563
if (((PanelPopup) uiComponent).isRunningModal()) {
((PanelPopup) uiComponent).setRunningModal(false);
CoreComponentUtils.setFocusId("");
}
call = "Ice.modal.stop('" + clientId + "');";
if (log.isTraceEnabled()) {
log.trace("Stopping modal function");
}
}
}
return call;
}
/*
* (non-Javadoc)
*
* @see com.icesoft.faces.renderkit.dom_html_basic.GroupRenderer#encodeChildren(javax.faces.context.FacesContext,
* javax.faces.component.UIComponent)
*/
public void encodeChildren(FacesContext facesContext,
UIComponent uiComponent) throws IOException {
}
/*
* (non-Javadoc)
*
* @see com.icesoft.faces.component.ext.renderkit.GroupRenderer#encodeEnd(javax.faces.context.FacesContext,
* javax.faces.component.UIComponent)
*/
public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
throws IOException {
if (log.isTraceEnabled()) {
log.trace("Encode End Called");
}
}
private String getIE8DisableModalFrame(FacesContext facesContext) {
String value = facesContext.getExternalContext().getInitParameter("com.icesoft.faces.IE8DisableModalFrame");
if ("true".equalsIgnoreCase(value)) {
return "true";
} else {
return "false";
}
}
}