View Javadoc

1   /***
2    Copyright (C) 2005 The Java Community
3   
4    This program is free software; you can redistribute it and/or modify  it under
5    the terms of the GNU General Public License as published by  the Free Software
6    Foundation; either version 2 of the License, or  (at your option) any later
7    version.
8   
9    This program is distributed in the hope that it will be useful,  but WITHOUT
10   ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS
11   FOR A PARTICULAR PURPOSE. See the  GNU General Public License for more details.
12  
13   You should have received a copy of the GNU General Public License  along with
14   this program; if not, write to the Free Software  Foundation, Inc., 59 Temple
15   Place, Suite 330, Boston, MA 02111-1307 USA.
16   */
17  package org.bejug.javacareers.common.ajax;
18  
19  import java.beans.Beans;
20  import java.io.IOException;
21  import java.util.Map;
22  
23  import javax.faces.component.UIComponent;
24  import javax.faces.context.FacesContext;
25  import javax.faces.context.ResponseWriter;
26  
27  import com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer;
28  import com.sun.faces.util.Util;
29  
30  
31  /***
32   * This renderer generates HTML (including JavaScript) for AjaxTextFields,
33   * emitting the necessary markup to provide auto completion for the textfield.
34   * <p/>
35   * This component relies on a cooperating servlet that responds to asynchronous
36   * requests.
37   *
38   * @author Tor Norbye
39   */
40  public class TextFieldRenderer extends HtmlBasicInputRenderer {
41  
42      /***
43       * the next id
44       */
45      private int nextId = 0;
46  
47      /***
48       * the key for the rendererscript.
49       */
50      private static final String RENDERED_SCRIPT_KEY = "bpcatalog-ajax-script-rendered";
51  
52      /***
53       * Creates a new instance of TextFieldRenderer
54       */
55      public TextFieldRenderer() {
56      }
57  
58      /***
59       * begin of the encoding.
60       *
61       * @param context   the FacesContext.
62       * @param component the UIComponent to encode.
63       * @throws IOException thrown when the encoding failes.
64       */
65      public void encodeBegin(FacesContext context, UIComponent component)
66              throws IOException {
67      }
68  
69      /***
70       * encode the children.
71       *
72       * @param context   the FacesContext.
73       * @param component the UIComponent to encode.
74       */
75      public void encodeChildren(FacesContext context, UIComponent component) {
76      }
77  
78      /***
79       * @param context      the FacesContext.
80       * @param component    the component to render.
81       * @param currentValue a String containing the currentvalue of the component.
82       * @throws IOException thrown when the rendering failes.
83       */
84      protected void getEndTextToRender(FacesContext context, UIComponent component,
85                                        String currentValue) throws IOException {
86          //assert component instanceof TextField;
87  
88          ResponseWriter writer = context.getResponseWriter();
89  
90          if (!Beans.isDesignTime()) {
91              renderScriptOnce(writer, component, context);
92          }
93  
94          String menuId = "menu-popup" + (nextId);
95          nextId++;
96  
97          if (!Beans.isDesignTime()) {
98              // Render menu popup (will be positioned etc. by CSS)
99              writer.startElement("div", component);
100             writer.writeAttribute("id", menuId, null);
101             writer.writeAttribute("style",
102                     "position: absolute; top:170px;left:140px;visibility:hidden", null);
103             writer.writeAttribute("class", "popupFrame", null);
104             writer.endElement("div");
105             writer.write("\n");
106         }
107 
108         writer.startElement("input", component);
109         writeIdAttributeIfNecessary(context, writer, component);
110 
111         // Set the autocomplete attribute to "off" to disable browser 
112         // textfield completion with previous entries
113         writer.writeAttribute("autocomplete", "off", null);
114 
115         writer.writeAttribute("type", "text", null);
116         writer.writeAttribute("name", component.getClientId(context), "clientId");
117 
118         if (currentValue != null) {
119             writer.writeAttribute("value", currentValue, "value");
120         }
121 
122         String styleClass = (String) component.getAttributes().get("styleClass");
123 
124         if (styleClass != null) {
125             writer.writeAttribute("class", styleClass, "styleClass");
126         }
127 
128         Util.renderPassThruAttributes(writer, component);
129         Util.renderBooleanPassThruAttributes(writer, component);
130 
131         // Emit the javascript for auto completion
132         TextField comp = (TextField) component;
133         String methodName = comp.getCompletionMethod();
134         String startScript =
135                 "doCompletion('" + comp.getClientId(context) + "','" + menuId + "','" + methodName +
136                 "'," + ((comp.getOnchoose() != null) ? comp.getOnchoose() : "null") + "," +
137                 ((comp.getOndisplay() != null) ? comp.getOndisplay() : "null") + ");";
138         String stopScript = "stopCompletionDelayed('" + menuId + "');";
139         writer.writeAttribute("onfocus", startScript, null);
140         writer.writeAttribute("onkeyup", startScript, null);
141         writer.writeAttribute("onblur", stopScript, null);
142 
143         writer.endElement("input");
144     }
145 
146     /***
147      * Render the &lt;script&gt; tag which contains supporting JavaScript
148      * for this text field.
149      *
150      * @param writer    the ResponseWriter for rendering the script-tag
151      * @param component the UIComponent contained by the script-tag
152      * @param context   the FacesContext.
153      * @throws IOException when the rendering of the sript-tag failes.
154      */
155     private void renderScriptOnce(ResponseWriter writer, UIComponent component, FacesContext context)
156             throws IOException {
157         // Only render the generic <style> and <script> sections once per page:
158         // Store attribute in request map when we've rendered the script such
159         // that we only do this once per page
160         Map requestMap = context.getExternalContext().getRequestMap();
161         Boolean scriptRendered = (Boolean) requestMap.get(RENDERED_SCRIPT_KEY);
162 
163         if (scriptRendered == Boolean.TRUE) {
164             return;
165         }
166 
167         requestMap.put(RENDERED_SCRIPT_KEY, Boolean.TRUE);
168 
169         // CSS
170         writer.write("\n");
171 
172         writer.startElement("link", component);
173         writer.writeAttribute("type", "text/css", null);
174         writer.writeAttribute("rel", "stylesheet", null);
175 
176         //String href = PhaseListener.CSS_VIEW_ID + ".faces";
177         String href = "faces/" + PhaseListener.CSS_VIEW_ID;
178         writer.writeAttribute("href", href, null);
179 
180         writer.endElement("link");
181         writer.write("\n");
182 
183         // JavaScript
184         writer.startElement("script", component);
185         writer.writeAttribute("type", "text/javascript", null);
186 
187         //String src = PhaseListener.SCRIPT_VIEW_ID + ".faces";
188         String src = "faces/" + PhaseListener.SCRIPT_VIEW_ID;
189         writer.writeAttribute("src", src, null);
190 
191         writer.endElement("script");
192         writer.write("\n");
193     }
194 }
195 
196 /***
197  * $Log: TextFieldRenderer.java,v $
198  * Revision 1.6  2005/09/13 08:11:06  schauwvliege
199  * organize imports
200  *
201  * Revision 1.5  2005/08/10 12:07:42  bavo_jcs
202  * Optimized imports according to checkstyle
203  *
204  * Revision 1.4  2005/08/10 09:04:45  bavo_jcs
205  * Optimized imports according to checkstyle
206  *
207  * Revision 1.3  2005/08/09 12:59:50  bavo_jcs
208  * Optimized imports
209  *
210  * Revision 1.2  2005/08/08 12:07:54  bme_jcs
211  * resolved checkstyle errors
212  *
213  * Revision 1.1  2005/07/13 11:42:08  bavo_jcs
214  * Ajax rename and test-cleanup
215  *
216  * Revision 1.1  2005/07/13 11:16:53  bavo_jcs
217  * Moved Ajax files
218  *
219  * Revision 1.1  2005/07/06 14:15:30  bavo_jcs
220  * Ajax integration
221  *
222  */