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  import java.util.List;
23  import java.util.Map;
24  
25  import javax.faces.application.ResourceDependency;
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.UIInput;
28  import javax.faces.component.behavior.ClientBehavior;
29  import javax.faces.component.behavior.ClientBehaviorHolder;
30  import javax.faces.context.FacesContext;
31  import javax.faces.context.ResponseWriter;
32  import javax.faces.convert.ConverterException;
33  import javax.faces.event.ComponentSystemEvent;
34  import javax.faces.event.ComponentSystemEventListener;
35  import javax.faces.event.ListenerFor;
36  
37  import org.apache.myfaces.renderkit.html.ext.HtmlTextRenderer;
38  import org.apache.myfaces.shared_tomahawk.renderkit.ClientBehaviorEvents;
39  import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
40  import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
41  import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
42  import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
43  import org.apache.myfaces.shared_tomahawk.renderkit.html.util.ResourceUtils;
44  import org.apache.myfaces.tomahawk.application.PreRenderViewAddResourceEvent;
45  import org.apache.myfaces.tomahawk.util.TomahawkResourceUtils;
46  
47  /**
48   * @JSFRenderer
49   *   renderKitId = "HTML_BASIC"
50   *   family = "javax.faces.Input"
51   *   type = "org.apache.myfaces.TextHelp"
52   * 
53   * @author Thomas Obereder
54   * @version Date: 09.06.2005, 22:50:48
55   */
56  @ResourceDependency(library="oam.custom.inputTextHelp", name="inputTextHelp.js")
57  public class HtmlTextHelpRenderer extends HtmlTextRenderer
58  {
59      private static final String JAVASCRIPT_ENCODED = "org.apache.myfaces.inputTextHelp.JAVASCRIPT_ENCODED";
60  
61      protected void renderNormal(FacesContext facesContext, UIComponent component) throws IOException
62      {
63          if(component instanceof HtmlInputTextHelp)
64          {
65              HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
66              //addJavaScriptResources(facesContext);
67              renderInputTextHelp(facesContext, helpTextComp);
68          }
69          else
70          {
71              super.renderNormal(facesContext, component);
72          }
73      }
74  
75      public static boolean isSelectText(UIComponent component)
76      {
77          if(component instanceof HtmlInputTextHelp)
78          {
79              HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
80              return helpTextComp.isSelectText();
81          }
82          return false;
83      }
84  
85      public static String getHelpText(UIComponent component)
86      {
87          if(component instanceof HtmlInputTextHelp)
88          {
89              HtmlInputTextHelp helpTextComp = (HtmlInputTextHelp) component;
90              if(helpTextComp.getHelpText() != null)
91                  return helpTextComp.getHelpText();
92          }
93          return null;
94      }
95  
96      public void renderInputTextHelp(FacesContext facesContext, UIInput input)
97              throws IOException
98      {
99          ResponseWriter writer = facesContext.getResponseWriter();
100 
101         Map<String, List<ClientBehavior>> behaviors = null;
102         if (input instanceof ClientBehaviorHolder)
103         {
104             behaviors = ((ClientBehaviorHolder) input).getClientBehaviors();
105             if (!behaviors.isEmpty())
106             {
107                 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
108             }
109         }
110         
111         writer.startElement(HTML.INPUT_ELEM, input);
112 
113         writer.writeAttribute(HTML.ID_ATTR, input.getClientId(facesContext), null);
114         
115         String name = (String) input.getAttributes().get("name");
116         if (name == null)
117         {
118             name = input.getClientId(facesContext);
119         }
120         writer.writeAttribute(HTML.NAME_ATTR, name, null);
121         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_TEXT, null);
122 
123         renderHelpTextAttributes(input, writer, facesContext);
124 
125         String value = RendererUtils.getStringValue(facesContext, input);
126         value = (value==null || value.length()==0) ? getHelpText(input) : value;
127 
128         if (value != null)
129         {
130             writer.writeAttribute(HTML.VALUE_ATTR, value, JSFAttr.VALUE_ATTR);
131         }
132 
133         writer.endElement(HTML.INPUT_ELEM);
134     }
135 
136     private void renderHelpTextAttributes(UIComponent component,
137                                           ResponseWriter writer,
138                                           FacesContext facesContext)
139             throws IOException
140     {
141         Map<String, List<ClientBehavior>> behaviors = null;
142         if (component instanceof ClientBehaviorHolder)
143         {
144             behaviors = ((ClientBehaviorHolder)component).getClientBehaviors();
145         }
146         if (behaviors != null && !behaviors.isEmpty())
147         {
148             String targetClientId = (String) component.getAttributes().get("targetClientId");
149             if (targetClientId == null)
150             {
151                 targetClientId = component.getClientId(facesContext);
152             }
153             
154             HtmlRendererUtils.renderBehaviorizedEventHandlersWithoutOnclick(facesContext, writer, component, behaviors);
155             HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, targetClientId, behaviors);
156             HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONBLUR_ATTR, component, targetClientId,
157                     ClientBehaviorEvents.BLUR, behaviors, HTML.ONBLUR_ATTR);
158             HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer,  HTML.ONSELECT_ATTR, component, targetClientId,
159                     ClientBehaviorEvents.SELECT, behaviors, HTML.ONSELECT_ATTR);
160             HtmlRendererUtils.renderHTMLAttributes(writer, component,
161                     HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
162 
163             if(!(component instanceof HtmlInputTextHelp) || getHelpText(component) == null || ("").equals(getHelpText(component).trim()))
164             {
165                 HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONFOCUS_ATTR, component, targetClientId,
166                         ClientBehaviorEvents.FOCUS, behaviors, HTML.ONFOCUS_ATTR);
167                 HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONCLICK_ATTR, component, targetClientId,
168                         ClientBehaviorEvents.CLICK, behaviors, HTML.ONCLICK_ATTR);
169             }
170             else
171             {
172                 String id = component.getClientId(facesContext);
173                 HtmlInputTextHelp textHelp = (HtmlInputTextHelp)component;
174 
175                 HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONFOCUS_ATTR, component, targetClientId,
176                         ClientBehaviorEvents.FOCUS, null, behaviors, HTML.ONFOCUS_ATTR, null,
177                         buildJavascriptFunction(component, id, textHelp.getOnfocus()));
178                 HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONCLICK_ATTR, component, targetClientId,
179                         ClientBehaviorEvents.CLICK, null, behaviors, HTML.ONCLICK_ATTR, null,
180                         buildJavascriptFunction(component, id, textHelp.getOnclick()));
181             }
182         }
183         else
184         {
185             if(!(component instanceof HtmlInputTextHelp) || getHelpText(component) == null || ("").equals(getHelpText(component).trim()))
186             {
187                 HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
188             }
189             else
190             {
191                 String id = component.getClientId(facesContext);
192                 HtmlInputTextHelp textHelp = (HtmlInputTextHelp)component;
193 
194                 HtmlRendererUtils.renderHTMLAttributes(writer, component,
195                                                    HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_ONFOCUS_AND_ONCLICK);
196                 writer.writeAttribute(HTML.ONFOCUS_ATTR,
197                                   buildJavascriptFunction(component, id, textHelp.getOnfocus()), null);
198                 writer.writeAttribute(HTML.ONCLICK_ATTR,
199                                   buildJavascriptFunction(component, id, textHelp.getOnclick()), null);
200             }
201         }
202 
203         if (isDisabled(facesContext, component))
204         {
205             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
206         }
207     }
208     
209     public static void renderBehaviorizedEventHandlersWithoutOnclick(
210             FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent, String targetClientId,
211             Map<String, List<ClientBehavior>> clientBehaviors) throws IOException {
212         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONDBLCLICK_ATTR, uiComponent, targetClientId,
213                 ClientBehaviorEvents.DBLCLICK, clientBehaviors, HTML.ONDBLCLICK_ATTR);
214         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEDOWN_ATTR, uiComponent, targetClientId,
215                 ClientBehaviorEvents.MOUSEDOWN, clientBehaviors, HTML.ONMOUSEDOWN_ATTR);
216         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEUP_ATTR, uiComponent, targetClientId,
217                 ClientBehaviorEvents.MOUSEUP, clientBehaviors, HTML.ONMOUSEUP_ATTR);
218         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEOVER_ATTR, uiComponent, targetClientId,
219                 ClientBehaviorEvents.MOUSEOVER, clientBehaviors, HTML.ONMOUSEOVER_ATTR);
220         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEMOVE_ATTR, uiComponent, targetClientId,
221                 ClientBehaviorEvents.MOUSEMOVE, clientBehaviors, HTML.ONMOUSEMOVE_ATTR);
222         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEOUT_ATTR, uiComponent, targetClientId,
223                 ClientBehaviorEvents.MOUSEOUT, clientBehaviors, HTML.ONMOUSEOUT_ATTR);
224         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYPRESS_ATTR, uiComponent, targetClientId,
225                 ClientBehaviorEvents.KEYPRESS, clientBehaviors, HTML.ONKEYPRESS_ATTR);
226         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYDOWN_ATTR, uiComponent, targetClientId,
227                 ClientBehaviorEvents.KEYDOWN, clientBehaviors, HTML.ONKEYDOWN_ATTR);
228         HtmlRendererUtils.renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYUP_ATTR, uiComponent, targetClientId,
229                 ClientBehaviorEvents.KEYUP, clientBehaviors, HTML.ONKEYUP_ATTR);
230     }    
231     
232     private String buildJavascriptFunction(UIComponent component, String id, String componentScript) 
233     {
234         StringBuffer jsFunction = new StringBuffer();
235         if(isSelectText(component))
236         {
237             jsFunction.append(HtmlInputTextHelp.JS_FUNCTION_SELECT_TEXT);
238             jsFunction.append("('");
239             jsFunction.append(    getHelpText(component)).append("', '");
240             jsFunction.append(    id);
241             jsFunction.append("')");
242         }
243         else
244         {
245             jsFunction.append(HtmlInputTextHelp.JS_FUNCTION_RESET_HELP );
246             jsFunction.append("('");
247             jsFunction.append(    getHelpText(component)).append("', '");
248             jsFunction.append(    id);
249             jsFunction.append("')");
250         }
251         
252         if(componentScript != null && !("").equals(componentScript.trim())) {
253             jsFunction.append(";");
254             jsFunction.append(componentScript);
255         }
256         
257         return jsFunction.toString();
258     }
259 
260     public void decode(FacesContext facesContext, UIComponent component)
261     {
262         super.decode(facesContext, component);
263     }
264 
265     public Object getConvertedValue(FacesContext facesContext, UIComponent component, Object submittedValue) throws ConverterException
266     {
267         if(submittedValue!=null && component instanceof HtmlInputTextHelp &&
268            ((HtmlInputTextHelp) component).getHelpText()!=null &&
269            submittedValue.equals(((HtmlInputTextHelp) component).getHelpText()))
270         {
271             submittedValue = "";
272         }
273 
274         return super.getConvertedValue(facesContext, component, submittedValue);
275     }
276 
277     /*public static void addJavaScriptResources(FacesContext facesContext)
278     {
279         // check to see if javascript has already been written (which could happen if more than one calendar on the same page)
280         if (facesContext.getExternalContext().getRequestMap().containsKey(JAVASCRIPT_ENCODED))
281         {
282             return;
283         }
284 
285         AddResourceFactory.getInstance(facesContext).addJavaScriptAtPosition(
286                 facesContext, AddResource.HEADER_BEGIN, HtmlTextHelpRenderer.class, "inputTextHelp.js");
287 
288         facesContext.getExternalContext().getRequestMap().put(JAVASCRIPT_ENCODED, Boolean.TRUE);
289     }*/
290 }