1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.custom.suggestajax.tablesuggestajax;
20
21 import org.apache.commons.collections.map.HashedMap;
22 import org.apache.myfaces.component.html.ext.UIComponentPerspective;
23 import org.apache.myfaces.custom.ajax.api.AjaxRenderer;
24 import org.apache.myfaces.custom.dojo.DojoConfig;
25 import org.apache.myfaces.custom.dojo.DojoUtils;
26 import org.apache.myfaces.custom.suggestajax.SuggestAjaxRenderer;
27 import org.apache.myfaces.shared_tomahawk.component.ExecuteOnCallback;
28 import org.apache.myfaces.shared_tomahawk.renderkit.JSFAttr;
29 import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
30 import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
31
32 import javax.faces.component.UIColumn;
33 import javax.faces.component.UIComponent;
34 import javax.faces.component.UIViewRoot;
35 import javax.faces.context.FacesContext;
36 import javax.faces.context.ResponseWriter;
37 import java.io.IOException;
38 import java.util.Collection;
39 import java.util.Iterator;
40 import java.util.Map;
41
42
43
44
45
46
47
48
49
50
51
52
53 public class TableSuggestAjaxRenderer extends SuggestAjaxRenderer implements AjaxRenderer
54 {
55 public static final int DEFAULT_START_REQUEST = 0;
56 public static final int DEFAULT_BETWEEN_KEY_UP = 1000;
57 public static final String DEFAULT_AUTO_COMPLETE = "true";
58
59
60
61
62
63
64
65
66
67
68 private void encodeJavascript(FacesContext context, UIComponent component) throws IOException
69 {
70
71 String javascriptLocation = (String)component.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
72
73 DojoConfig dojoConfig = new DojoConfig();
74 DojoUtils.addMainInclude(context, component, javascriptLocation, dojoConfig);
75 DojoUtils.addRequire(context, component, "extensions.FacesIO");
76 DojoUtils.addRequire(context, component, "extensions.widget.TableSuggest");
77 DojoUtils.addRequire(context, component, "dojo.event.*");
78 }
79
80 public void encodeEnd(FacesContext context, UIComponent component) throws IOException
81 {
82 RendererUtils.checkParamValidity(context, component, TableSuggestAjax.class);
83
84 TableSuggestAjax tableSuggestAjax = (TableSuggestAjax) component;
85
86 encodeJavascript(context,component);
87
88
89 tableSuggestAjax.getAttributes().put("autocomplete","off");
90
91 String clientId = component.getClientId(context);
92 String actionURL = getActionUrl(context);
93
94 String charset = (tableSuggestAjax.getCharset() != null ? tableSuggestAjax.getCharset() : "");
95 String ajaxUrl = context.getExternalContext().encodeActionURL(addQueryString(actionURL, "affectedAjaxComponent=" + clientId +
96 "&charset=" + charset + "&" + clientId + "=%{searchString}"));
97
98 ResponseWriter out = context.getResponseWriter();
99
100 String valueToRender = RendererUtils.getStringValue(context,tableSuggestAjax);
101 valueToRender = escapeQuotes(valueToRender);
102
103 if (getChildren(tableSuggestAjax) != null
104 && !getChildren(tableSuggestAjax).isEmpty())
105 {
106 StringBuffer divId = new StringBuffer();
107 divId.append(clientId).append(":::div");
108
109 out.startElement(HTML.DIV_ELEM, component);
110 out.writeAttribute(HTML.ID_ATTR, divId , null);
111 out.endElement(HTML.DIV_ELEM);
112 super.encodeEnd(context, tableSuggestAjax);
113
114 String tableSuggestComponentVar = DojoUtils.calculateWidgetVarName(divId.toString());
115
116 Map attributes = new HashedMap();
117 String betweenKeyUp = "";
118 String startRequest = "";
119 String autoComplete = "";
120
121
122 attributes.put("dataUrl", ajaxUrl);
123 attributes.put("mode", "remote");
124
125
126 if (tableSuggestAjax.getBetweenKeyUp() != null) {
127 betweenKeyUp = tableSuggestAjax.getBetweenKeyUp().toString();
128 }
129 else {
130 betweenKeyUp = Integer.toString(DEFAULT_BETWEEN_KEY_UP);
131 }
132 attributes.put("searchDelay", betweenKeyUp);
133
134
135 if (tableSuggestAjax.getStartRequest() != null) {
136 startRequest = tableSuggestAjax.getStartRequest().toString();
137 }
138 else {
139 startRequest = Integer.toString(DEFAULT_START_REQUEST);
140 }
141 attributes.put("startRequest", startRequest);
142
143
144 if (tableSuggestAjax.getAutocomplete()!=null) {
145 autoComplete = tableSuggestAjax.getAutocomplete();
146 }
147 else {
148 autoComplete = DEFAULT_AUTO_COMPLETE;
149 }
150 attributes.put("autoComplete", autoComplete);
151
152
153 if (tableSuggestAjax.getPopupId() != null) {
154 attributes.put("popupId", tableSuggestAjax.getPopupId());
155 }
156
157
158 if (tableSuggestAjax.getPopupStyleClass() != null) {
159 attributes.put("popupStyleClass", tableSuggestAjax.getPopupStyleClass());
160 }
161
162
163 if (tableSuggestAjax.getTableStyleClass() != null) {
164 attributes.put("tableStyleClass", tableSuggestAjax.getTableStyleClass());
165 }
166
167
168 if (tableSuggestAjax.getComboBoxStyleClass() != null) {
169 attributes.put("comboBoxStyleClass", tableSuggestAjax.getComboBoxStyleClass());
170 }
171
172
173 if (tableSuggestAjax.getRowStyleClass() != null) {
174 attributes.put("rowStyleClass", tableSuggestAjax.getRowStyleClass());
175 }
176
177
178 if (tableSuggestAjax.getEvenRowStyleClass() != null) {
179 attributes.put("evenRowStyleClass", tableSuggestAjax.getEvenRowStyleClass());
180 }
181
182
183 if (tableSuggestAjax.getOddRowStyleClass() != null) {
184 attributes.put("oddRowStyleClass", tableSuggestAjax.getOddRowStyleClass());
185 }
186
187
188 if (tableSuggestAjax.getHoverRowStyleClass() != null) {
189 attributes.put("hoverRowStyleClass", tableSuggestAjax.getHoverRowStyleClass());
190 }
191
192
193 attributes.put("textInputId", clientId);
194
195 DojoUtils.renderWidgetInitializationCode(context.getResponseWriter(), component, "extensions:TableSuggest", attributes, divId.toString(), true);
196
197 out.startElement(HTML.SCRIPT_ELEM, null);
198 out.writeAttribute(HTML.TYPE_ATTR, HTML.SCRIPT_TYPE_TEXT_JAVASCRIPT, null);
199
200 StringBuffer buffer = new StringBuffer();
201
202 buffer.append("dojo.addOnLoad(function() {\n")
203 .append(tableSuggestComponentVar).append(".comboBoxValue.value = \"").append(valueToRender).append("\";\n")
204 .append(tableSuggestComponentVar).append(".onResize();\n")
205 .append("});\n");
206
207 out.write(buffer.toString());
208
209 out.endElement(HTML.SCRIPT_ELEM);
210 }
211 }
212
213 public void decode(FacesContext facesContext, UIComponent component)
214 {
215 super.decode(facesContext, component);
216 }
217
218 public void encodeAjax(FacesContext context, UIComponent uiComponent)
219 throws IOException
220 {
221 String clientId = (String)context.getExternalContext()
222 .getRequestParameterMap().get("affectedAjaxComponent");
223
224 UIViewRoot root = context.getViewRoot();
225
226 UIComponent ajaxComp = root.findComponent(clientId);
227
228
229
230 if (ajaxComp instanceof UIComponentPerspective)
231 {
232 UIComponentPerspective componentPerspective = (UIComponentPerspective) ajaxComp;
233
234 componentPerspective.executeOn(context, new ExecuteOnCallback()
235 {
236 public Object execute(FacesContext facesContext, UIComponent uiComponent)
237 {
238 try
239 {
240 renderResponse ( (TableSuggestAjax) uiComponent, facesContext);
241 }
242 catch (IOException e)
243 {
244 e.printStackTrace();
245 }
246
247 return uiComponent;
248 }
249 });
250 }
251 else
252 {
253 renderResponse ( (TableSuggestAjax) uiComponent, context);
254 }
255 }
256
257
258 private void renderResponse(TableSuggestAjax tableSuggestAjax,
259 FacesContext context) throws IOException
260 {
261
262 context.getResponseWriter().write("[");
263 renderColumnHeaders(tableSuggestAjax, context);
264
265 StringBuffer response = new StringBuffer();
266 response.append("[");
267
268 Collection suggestedItems =
269 getSuggestedItems(context, tableSuggestAjax);
270
271 if (getChildren(tableSuggestAjax) == null
272 || getChildren(tableSuggestAjax).isEmpty())
273 {
274 return;
275 }
276
277 for (Iterator it = suggestedItems.iterator(); it.hasNext();)
278 {
279
280 Object addressEntryObject = it.next();
281
282 context.getExternalContext().getRequestMap().put(
283 tableSuggestAjax.getVar(), addressEntryObject);
284
285 response.append("[");
286
287 Iterator columns = tableSuggestAjax.getChildren().iterator();
288 while (columns.hasNext())
289 {
290 UIComponent column = (UIComponent) columns.next();
291
292 Iterator columnChildren = column.getChildren().iterator();
293 while (columnChildren.hasNext())
294 {
295 Object component = columnChildren.next();
296
297 if (!(component instanceof HtmlOutputText))
298 {
299 continue;
300 }
301
302 HtmlOutputText htmlOutputText =
303 (HtmlOutputText) component;
304
305 response.append("{");
306
307
308 if (htmlOutputText.getFor() != null)
309 {
310 response.append("\"forText\": ");
311 String forText = RendererUtils.getClientId(context,
312 tableSuggestAjax,
313 htmlOutputText.getFor());
314 response.append("\"").append(forText).append("\",");
315 response.append("\"label\": ");
316 response.append("\"").append(escapeQuotes(htmlOutputText.getLabel())).append("\"");
317 }
318
319 else if (htmlOutputText.getForValue() != null)
320 {
321 response.append("\"forValue\": ");
322 String forValue = RendererUtils.getClientId(context,
323 tableSuggestAjax,
324 htmlOutputText.getForValue());
325 response.append("\"").append(forValue).append("\",");
326 response.append("\"label\": ");
327 response.append("\"").append(escapeQuotes(htmlOutputText.getLabel())).append("\",");
328 response.append("\"value\": ");
329 response.append("\"").append(escapeQuotes(htmlOutputText.getValue().toString())).append("\"");
330 } else {
331 response.append("\"label\": ");
332 response.append("\"").append(escapeQuotes(htmlOutputText.getValue().toString())).append("\"");
333 }
334 response.append("}");
335 if (columnChildren.hasNext() || columns.hasNext()) {
336 response.append(",");
337 }
338 }
339 }
340 response.append("]");
341 if (it.hasNext()) {
342 response.append(",");
343 }
344 }
345
346 context.getExternalContext().getRequestMap().remove(tableSuggestAjax.getVar());
347 response.append("]");
348 context.getResponseWriter().write(response.toString());
349 context.getResponseWriter().write("]");
350
351 }
352
353
354
355
356 private void renderColumnHeaders(TableSuggestAjax tableSuggestAjax,
357 FacesContext context) throws IOException
358 {
359 StringBuffer columnHeaders = new StringBuffer();
360 columnHeaders.append("[");
361
362 Iterator it = tableSuggestAjax.getChildren().iterator();
363
364 while (it.hasNext())
365 {
366 UIComponent column = (UIComponent) it.next();
367
368 if (column instanceof UIColumn)
369 {
370 UIComponent tableHeader = (UIComponent) column.getFacet("header");
371
372 if (tableHeader != null && tableHeader instanceof HtmlOutputText)
373 {
374 HtmlOutputText htmlOutputText = (HtmlOutputText) tableHeader;
375 columnHeaders.append("\"").append(htmlOutputText.getValue()).append("\"");
376 if (it.hasNext()) {
377 columnHeaders.append(",");
378 }
379 }
380 }
381 }
382 columnHeaders.append("],");
383 context.getResponseWriter().write(columnHeaders.toString());
384 }
385
386 private String escapeQuotes(String input)
387 {
388 return input != null ? input.replaceAll("\"", "\\\\\"") : "";
389 }
390
391 }
392
393