001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.faces.renderkit.dom_html_basic;
035:
036: import com.icesoft.faces.context.DOMContext;
037: import com.icesoft.faces.context.effects.JavascriptContext;
038: import org.w3c.dom.Element;
039:
040: import javax.faces.component.UICommand;
041: import javax.faces.component.UIComponent;
042: import javax.faces.context.FacesContext;
043: import javax.faces.event.ActionEvent;
044: import java.io.IOException;
045: import java.util.Map;
046:
047: public class ButtonRenderer extends DomBasicRenderer {
048:
049: public void decode(FacesContext facesContext,
050: UIComponent uiComponent) {
051: validateParameters(facesContext, uiComponent, UICommand.class);
052: if (isStatic(uiComponent)) {
053: return;
054: }
055: boolean this ButtonInvokedSubmit = didThisButtonInvokeSubmit(
056: facesContext, uiComponent);
057: if (!this ButtonInvokedSubmit) {
058: return;
059: }
060: String type = ((String) uiComponent.getAttributes().get("type"))
061: .toLowerCase();
062: if ((type != null) && (type.equals("reset"))) {
063: return;
064: }
065: ActionEvent actionEvent = new ActionEvent(uiComponent);
066: uiComponent.queueEvent(actionEvent);
067: }
068:
069: /**
070: * @param facesContext
071: * @param uiComponent
072: * @return boolean
073: */
074: private boolean didThisButtonInvokeSubmit(
075: FacesContext facesContext, UIComponent uiComponent) {
076: boolean this ButtonInvokedSubmit = false;
077: //find if the form submitted by a textField, workaround to deal with the default behaviour of the browser
078: //(e.g.) if a form has a button on it, and enter key pressed on a text field, form submitted by the first intance of button
079: if (!isTextFieldInvokedSubmit(facesContext)) {
080: Map requestParameterMap = facesContext.getExternalContext()
081: .getRequestParameterMap();
082: String componentClientId = uiComponent
083: .getClientId(facesContext);
084: String clientIdInRequestMap = (String) requestParameterMap
085: .get(componentClientId);
086: this ButtonInvokedSubmit = clientIdInRequestMap != null;
087: if (!this ButtonInvokedSubmit) {
088: // detect whether this button is an image button
089: // that invoked the submit
090: String clientIdXCoordinateInRequestMap = componentClientId
091: + ".x";
092: String clientIdYCoordinateInRequestMap = componentClientId
093: + ".y";
094: if (requestParameterMap.get(componentClientId + ".x") != null
095: || requestParameterMap.get(componentClientId
096: + ".y") != null) {
097: this ButtonInvokedSubmit = true;
098: }
099: }
100: }
101: return this ButtonInvokedSubmit;
102: }
103:
104: public void encodeBegin(FacesContext facesContext,
105: UIComponent uiComponent) throws IOException {
106: validateParameters(facesContext, uiComponent, UICommand.class);
107:
108: DOMContext domContext = DOMContext.attachDOMContext(
109: facesContext, uiComponent);
110: String clientId = uiComponent.getClientId(facesContext);
111:
112: if (!domContext.isInitialized()) {
113: Element root = domContext.createElement("input");
114: domContext.setRootNode(root);
115: root.setAttribute("name", clientId);
116: }
117: Element root = (Element) domContext.getRootNode();
118:
119: setRootElementId(facesContext, root, uiComponent);
120:
121: // according to the Sun documentation for ButtonRenderer,
122: // type: valid values are "submit" and "reset"; default to "submit".
123: // But the docs for the image attribute declare that 'image' is also
124: // a valid value for the type attribute.
125: // The logic here holds true when there is no image attribute
126: // But suns JSF implementation allows for type button, we allow it as well.
127: String typeAttribute = ((String) uiComponent.getAttributes()
128: .get("type")).toLowerCase();
129: if (typeAttribute == null
130: || (!typeAttribute.equals("reset") && (!typeAttribute
131: .equals("button")))) {
132: typeAttribute = "submit";
133: }
134: uiComponent.getAttributes().put("type", typeAttribute);
135:
136: // If image attribute is specified, the type is "image"
137: // otherwise take the type from the type attribute and set a label
138: // with value specified by the value attribute
139: String imageAttribute = (String) uiComponent.getAttributes()
140: .get("image");
141: if (imageAttribute != null) {
142: typeAttribute = "image";
143: root.setAttribute("type", typeAttribute);
144:
145: //Paths to resources can be dependent on the environment so
146: //we should use proper JSF techniques to resolve them.
147: String pathToImage = getResourceURL(facesContext,
148: imageAttribute);
149:
150: root.setAttribute("src", pathToImage);
151: root.removeAttribute("value");
152: } else {
153: root.setAttribute("type", typeAttribute);
154: String label = "";
155: Object componentValue = ((UICommand) uiComponent)
156: .getValue();
157: if (componentValue != null) {
158: label = componentValue.toString();
159: } else {
160: label = "";
161: }
162: root.setAttribute("value", label);
163: root.removeAttribute("src");
164: }
165:
166: String styleClass = (String) uiComponent.getAttributes().get(
167: "styleClass");
168: if (styleClass != null) {
169: root.setAttribute("class", styleClass);
170: }
171:
172: JavascriptContext.fireEffect(uiComponent, facesContext);
173:
174: PassThruAttributeRenderer.renderAttributes(facesContext,
175: uiComponent, null);
176: //add iceSubmit for image and submit button only
177: if (typeAttribute.equals("submit")
178: || typeAttribute.equals("image")) {
179: renderOnClick(uiComponent, root);
180: }
181:
182: domContext.stepOver();
183: domContext.streamWrite(facesContext, uiComponent);
184: }
185:
186: /**
187: * @param uiComponent
188: * @param root
189: */
190: protected void renderOnClick(UIComponent uiComponent, Element root) {
191: String onclick = (String) uiComponent.getAttributes().get(
192: "onclick");
193: String submitCode = this .ICESUBMIT + "return false;";
194: if (onclick == null) {
195: onclick = submitCode;
196: } else {
197: onclick += submitCode;
198: }
199: root.setAttribute("onclick", onclick);
200: }
201:
202: public void encodeChildren(FacesContext facesContext,
203: UIComponent uiComponent) throws IOException {
204: validateParameters(facesContext, uiComponent, UICommand.class);
205: }
206:
207: public void encodeEnd(FacesContext facesContext,
208: UIComponent uiComponent) throws IOException {
209: validateParameters(facesContext, uiComponent, UICommand.class);
210: }
211:
212: private boolean isTextFieldInvokedSubmit(FacesContext facesContext) {
213: Object textFieldfocus = facesContext.getExternalContext()
214: .getRequestParameterMap().get(
215: FormRenderer.FOCUS_HIDDEN_FIELD);
216: if (textFieldfocus == null) {
217: return false;
218: }
219:
220: if (textFieldfocus.toString().length() > 0) {
221: return true;
222: } else {
223: return false;
224: }
225: }
226: }
|