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.custom.inputTextHelp;
20  
21  import java.io.IOException;
22  
23  import javax.faces.component.UIComponent;
24  import javax.faces.component.UIInput;
25  import javax.faces.context.FacesContext;
26  import javax.faces.context.ResponseWriter;
27  import javax.faces.convert.ConverterException;
28  
29  import org.apache.myfaces.renderkit.html.util.AddResource;
30  import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
31  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
32  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
33  import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
34  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
35  import org.apache.myfaces.renderkit.html.ext.HtmlTextRenderer;
36  
37  /**
38   * @JSFRenderer
39   *   renderKitId = "HTML_BASIC"
40   *   family = "javax.faces.Input"
41   *   type = "org.apache.myfaces.TextHelp"
42   * 
43   * @author Thomas Obereder
44   * @version Date: 09.06.2005, 22:50:48
45   */
46  public class HtmlTextHelpRenderer extends HtmlTextRenderer
47  {
48      private static final String JAVASCRIPT_ENCODED = "org.apache.myfaces.inputTextHelp.JAVASCRIPT_ENCODED";
49  
50      protected void renderNormal(FacesContext facesContext, UIComponent component) throws IOException
51      {
52          if(component instanceof HtmlInputTextHelp)
53          {
54              HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
55              addJavaScriptResources(facesContext);
56              renderInputTextHelp(facesContext, helpTextComp);
57          }
58          else
59          {
60              super.renderNormal(facesContext, component);
61          }
62      }
63  
64      public static boolean isSelectText(UIComponent component)
65      {
66          if(component instanceof HtmlInputTextHelp)
67          {
68              HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
69              return helpTextComp.isSelectText();
70          }
71          return false;
72      }
73  
74      public static String getHelpText(UIComponent component)
75      {
76          if(component instanceof HtmlInputTextHelp)
77          {
78              HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
79              if(helpTextComp.getHelpText() != null)
80                  return helpTextComp.getHelpText();
81          }
82          return null;
83      }
84  
85      public void renderInputTextHelp(FacesContext facesContext, UIInput input)
86              throws IOException
87      {
88          ResponseWriter writer = facesContext.getResponseWriter();
89  
90          writer.startElement(HTML.INPUT_ELEM, input);
91  
92          writer.writeAttribute(HTML.ID_ATTR, input.getClientId(facesContext), null);
93          writer.writeAttribute(HTML.NAME_ATTR, input.getClientId(facesContext), null);
94          writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_TEXT, null);
95  
96          renderHelpTextAttributes(input, writer, facesContext);
97  
98          String value = RendererUtils.getStringValue(facesContext, input);
99          value = (value==null || value.length()==0) ? getHelpText(input) : value;
100 
101         if (value != null)
102         {
103             writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
104         }
105 
106         writer.endElement(HTML.INPUT_ELEM);
107     }
108 
109     private void renderHelpTextAttributes(UIComponent component,
110                                           ResponseWriter writer,
111                                           FacesContext facesContext)
112             throws IOException
113     {
114         if(!(component instanceof HtmlInputTextHelp) || getHelpText(component) == null || ("").equals(getHelpText(component).trim()))
115         {
116             HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
117         }
118         else
119         {
120             String id = component.getClientId(facesContext);
121             HtmlInputTextHelp textHelp = (HtmlInputTextHelp)component;
122             
123             HtmlRendererUtils.renderHTMLAttributes(writer, component,
124                                                    HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK);
125             writer.writeAttribute(HTML.ONFOCUS_ATTR,
126                                   buildJavascriptFunction(component, id, textHelp.getOnfocus()), null);
127             writer.writeAttribute(HTML.ONCLICK_ATTR,
128                                   buildJavascriptFunction(component, id, textHelp.getOnclick()), null);
129         }
130 
131         if (isDisabled(facesContext, component))
132         {
133             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
134         }
135     }
136     
137     private String buildJavascriptFunction(UIComponent component, String id, String componentScript) 
138     {
139         StringBuffer jsFunction = new StringBuffer();
140         if(isSelectText(component))
141         {
142             jsFunction.append(HtmlInputTextHelp.JS_FUNCTION_SELECT_TEXT);
143             jsFunction.append("('");
144             jsFunction.append(    getHelpText(component)).append("', '");
145             jsFunction.append(    id);
146             jsFunction.append("')");
147         }
148         else
149         {
150             jsFunction.append(HtmlInputTextHelp.JS_FUNCTION_RESET_HELP );
151             jsFunction.append("('");
152             jsFunction.append(    getHelpText(component)).append("', '");
153             jsFunction.append(    id);
154             jsFunction.append("')");
155         }
156         
157         if(componentScript != null && !("").equals(componentScript.trim())) {
158             jsFunction.append(";");
159             jsFunction.append(componentScript);
160         }
161         
162         return jsFunction.toString();
163     }
164 
165     public void decode(FacesContext facesContext, UIComponent component)
166     {
167         super.decode(facesContext, component);
168     }
169 
170     public Object getConvertedValue(FacesContext facesContext, UIComponent component, Object submittedValue) throws ConverterException
171     {
172         if(submittedValue!=null && component instanceof HtmlInputTextHelp &&
173            ((HtmlInputTextHelp) component).getHelpText()!=null &&
174            submittedValue.equals(((HtmlInputTextHelp) component).getHelpText()))
175         {
176             submittedValue = "";
177         }
178 
179         return super.getConvertedValue(facesContext, component, submittedValue);
180     }
181 
182     public static void addJavaScriptResources(FacesContext facesContext)
183     {
184         // check to see if javascript has already been written (which could happen if more than one calendar on the same page)
185         if (facesContext.getExternalContext().getRequestMap().containsKey(JAVASCRIPT_ENCODED))
186         {
187             return;
188         }
189 
190         AddResourceFactory.getInstance(facesContext).addJavaScriptAtPosition(
191                 facesContext, AddResource.HEADER_BEGIN, HtmlTextHelpRenderer.class, "inputTextHelp.js");
192 
193         facesContext.getExternalContext().getRequestMap().put(JAVASCRIPT_ENCODED, Boolean.TRUE);
194     }
195 }