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
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
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
112
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
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 <script> 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
158
159
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
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
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
184 writer.startElement("script", component);
185 writer.writeAttribute("type", "text/javascript", null);
186
187
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 */