View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.renderkit.html.ext;
20  
21  import java.io.IOException;
22  import java.util.Map;
23  
24  import javax.faces.component.UIComponent;
25  import javax.faces.component.UIInput;
26  import javax.faces.context.FacesContext;
27  import javax.faces.context.ResponseWriter;
28  
29  import org.apache.myfaces.component.UserRoleUtils;
30  import org.apache.myfaces.component.html.ext.HtmlInputText;
31  import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
32  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
33  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
34  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
35  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlTextRendererBase;
36  import org.apache.myfaces.shared_tomahawk.renderkit.html.util.JavascriptUtils;
37  
38  
39  /**
40   * @JSFRenderer
41   *   renderKitId = "HTML_BASIC"
42   *   family = "javax.faces.Input"
43   *   type = "org.apache.myfaces.Text"
44   *   
45   * @JSFRenderer
46   *   renderKitId = "HTML_BASIC"
47   *   family = "javax.faces.Output"
48   *   type = "org.apache.myfaces.Text"
49   * 
50   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
51   * @version $Revision: 659874 $ $Date: 2008-05-24 15:59:15 -0500 (Sat, 24 May 2008) $
52   */
53  public class HtmlTextRenderer
54          extends HtmlTextRendererBase
55  {
56      private static final String ONCHANGE_PREFIX = "onChange_";
57      private static final String HIDDEN_SUFFIX   = "_hidden";
58       
59      //private static final Log log = LogFactory.getLog(HtmlTextRenderer.class);
60      protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
61      {
62          if (!UserRoleUtils.isEnabledOnUserRole(uiComponent))
63          {
64              return true;
65          }
66          else
67          {
68              return super.isDisabled(facesContext, uiComponent);
69          }
70      }
71      /**
72       *
73       */
74      protected boolean isDisabledOnClientSide(FacesContext facesContext, UIComponent component)
75      {
76          if (component instanceof HtmlInputText)
77          {
78              return ((HtmlInputText)component).isDisabledOnClientSide();
79          }
80          
81          return false;
82      }      
83  
84      public void encodeEnd(FacesContext facesContext, UIComponent component)
85          throws IOException
86      {
87          if (HtmlRendererUtils.isDisplayValueOnly(component))
88          {
89              renderInputValueOnly(facesContext, component);
90          }
91          else
92          {
93              renderNormal(facesContext, component);
94          }
95      }
96      
97      protected void renderInput(FacesContext facesContext, UIComponent component) throws IOException 
98      {
99          if (!isDisabledOnClientSide(facesContext, component) || isDisabled(facesContext, component))
100         {
101             super.renderInput(facesContext, component);
102             return;
103         }               
104         
105         //render the input component as if it was disabled
106         ResponseWriter writer = facesContext.getResponseWriter();
107 
108         String clientId = component.getClientId(facesContext);
109         String value = RendererUtils.getStringValue(facesContext, component);
110 
111         writer.startElement(HTML.INPUT_ELEM, component);
112         writer.writeAttribute(HTML.ID_ATTR, clientId, null);
113         writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
114         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_TEXT, null);
115         if (value != null)
116         {
117             writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
118         }
119 
120         HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
121         //render as disabled on the client side
122         writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
123         //render the JS function that will change the hidden input field's value when his changes        
124         writer.writeAttribute(HTML.ONCHANGE_ATTR, getOnChangeFunctionName(clientId)+"();", null);
125         
126         writer.endElement(HTML.INPUT_ELEM);
127         
128         //render the hidden input field that will hold this component's value
129         renderHiddenInput(facesContext, (UIInput)component);
130     }    
131     /**
132      *
133      */
134     protected void renderHiddenInput(FacesContext facesContext, UIComponent component) throws IOException
135     {
136         ResponseWriter writer = facesContext.getResponseWriter();
137         
138         String disabledInputClientId = component.getClientId(facesContext);
139         
140         HtmlRendererUtils.writePrettyLineSeparator(facesContext);
141         
142         writer.startElement(HTML.SCRIPT_ELEM, null);
143         writer.writeAttribute(HTML.SCRIPT_TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);                        
144         writer.writeText(createOnChangeListenerJS(disabledInputClientId), null);        
145         writer.endElement(HTML.SCRIPT_ELEM);
146         
147         HtmlRendererUtils.writePrettyLineSeparator(facesContext);  
148         
149         writer.startElement(HTML.INPUT_ELEM, null);
150         writer.writeAttribute(HTML.ID_ATTR, disabledInputClientId + HIDDEN_SUFFIX, null);
151         writer.writeAttribute(HTML.NAME_ATTR, disabledInputClientId + HIDDEN_SUFFIX, null);
152         writer.writeAttribute(HTML.VALUE_ATTR, RendererUtils.getStringValue(facesContext, component), null);
153         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);        
154         writer.endElement(HTML.INPUT_ELEM);
155         
156         HtmlRendererUtils.writePrettyLineSeparator(facesContext);       
157     }
158 
159     protected void renderInputValueOnly(FacesContext facesContext, UIComponent component)
160         throws IOException
161     {
162             HtmlRendererUtils.renderDisplayValueOnly(facesContext,
163                                                      (UIInput) component);
164     }
165 
166     protected void renderNormal(FacesContext facesContext, UIComponent component)
167         throws IOException
168     {
169             super.encodeEnd(facesContext, component);
170     }    
171     
172     /**
173      *
174      */ 
175     protected String getOnChangeFunctionName(String inputDisabledClientId)
176     {
177         StringBuffer buf = new StringBuffer();
178         buf.append(ONCHANGE_PREFIX);
179         buf.append(JavascriptUtils.getValidJavascriptName(inputDisabledClientId, true));
180         
181         return buf.toString();
182     }     
183     /**
184      *
185      */
186     protected String createOnChangeListenerJS(String inputDisabledClientId)
187     {
188         StringBuffer script = new StringBuffer();
189         script.append("function ");
190         script.append(getOnChangeFunctionName(inputDisabledClientId));            
191         script.append("() {\n");                
192         script.append("var hiddenInput = document.getElementById(\"").append(inputDisabledClientId + HIDDEN_SUFFIX).append("\");\n");
193         script.append("var disabledInput = document.getElementById(\"").append(inputDisabledClientId).append("\");\n");
194         script.append("hiddenInput.value=disabledInput.value;\n");        
195         script.append("}\n");        
196         
197         return script.toString();
198     }
199 
200     public void decode(FacesContext facesContext, UIComponent component) 
201     {        
202         if (isDisabledOnClientSide(facesContext, component) && !isDisabled(facesContext, component))
203         {            
204             //in this case we don't need to check the request parameters validity, 
205             //the submitted value comes from the hidden input field
206             Map paramValuesMap = facesContext.getExternalContext().getRequestParameterMap();            
207             Object reqValue = paramValuesMap.get(component.getClientId(facesContext) + HIDDEN_SUFFIX);  
208                        
209             ((UIInput)component).setSubmittedValue(reqValue); 
210             return;
211         }
212         
213         super.decode(facesContext, component);        
214     }
215 }