1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.shared.renderkit.html;
20
21 import java.io.IOException;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.logging.Logger;
26
27 import javax.faces.component.UIComponent;
28 import javax.faces.component.UIInput;
29 import javax.faces.component.UINamingContainer;
30 import javax.faces.component.UISelectOne;
31 import javax.faces.component.behavior.ClientBehavior;
32 import javax.faces.component.behavior.ClientBehaviorHolder;
33 import javax.faces.component.html.HtmlSelectOneRadio;
34 import javax.faces.context.FacesContext;
35 import javax.faces.context.ResponseWriter;
36 import javax.faces.convert.Converter;
37 import javax.faces.convert.ConverterException;
38 import javax.faces.model.SelectItem;
39 import javax.faces.model.SelectItemGroup;
40
41 import org.apache.myfaces.shared.renderkit.JSFAttr;
42 import org.apache.myfaces.shared.renderkit.RendererUtils;
43 import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
44 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
45
46
47
48
49
50
51 public class HtmlRadioRendererBase
52 extends HtmlRenderer
53 {
54
55 private static final Logger log = Logger.getLogger(HtmlRadioRendererBase.class.getName());
56
57 private static final String PAGE_DIRECTION = "pageDirection";
58 private static final String LINE_DIRECTION = "lineDirection";
59
60 public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
61 {
62 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(
63 facesContext, uiComponent, UISelectOne.class);
64
65 UISelectOne selectOne = (UISelectOne)uiComponent;
66
67 String layout = getLayout(selectOne);
68
69 boolean pageDirectionLayout = false;
70 if (layout != null)
71 {
72 if (layout.equals(PAGE_DIRECTION))
73 {
74 pageDirectionLayout = true;
75 }
76 else if (layout.equals(LINE_DIRECTION))
77 {
78 pageDirectionLayout = false;
79 }
80 else
81 {
82 log.severe("Wrong layout attribute for component " +
83 selectOne.getClientId(facesContext) + ": " + layout);
84 }
85 }
86
87 ResponseWriter writer = facesContext.getResponseWriter();
88
89 Map<String, List<ClientBehavior>> behaviors = null;
90
91 if (uiComponent instanceof ClientBehaviorHolder)
92 {
93 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
94 if (!behaviors.isEmpty())
95 {
96 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
97 }
98 }
99
100 writer.startElement(HTML.TABLE_ELEM, selectOne);
101 HtmlRendererUtils.renderHTMLAttributes(writer, selectOne,
102 HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
103
104 if (behaviors != null && !behaviors.isEmpty())
105 {
106 writer.writeAttribute(HTML.ID_ATTR, selectOne.getClientId(facesContext), null);
107 }
108 else
109 {
110 HtmlRendererUtils.writeIdIfNecessary(writer, selectOne, facesContext);
111 }
112
113 if (!pageDirectionLayout)
114 {
115 writer.startElement(HTML.TR_ELEM, selectOne);
116 }
117
118 Converter converter;
119 List selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
120 selectOne, facesContext);
121 converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, selectOne);
122
123 Object currentValue =
124 org.apache.myfaces.shared.renderkit.RendererUtils.getStringFromSubmittedValueOrLocalValueReturnNull(
125 facesContext, selectOne);
126
127 int itemNum = 0;
128
129 for (Iterator it = selectItemList.iterator(); it.hasNext(); )
130 {
131 SelectItem selectItem = (SelectItem)it.next();
132
133 itemNum = renderGroupOrItemRadio(facesContext, selectOne,
134 selectItem, currentValue,
135 converter, pageDirectionLayout, itemNum);
136 }
137
138 if (!pageDirectionLayout)
139 {
140 writer.endElement(HTML.TR_ELEM);
141 }
142 writer.endElement(HTML.TABLE_ELEM);
143 }
144
145
146 protected String getLayout(UIComponent selectOne)
147 {
148 if (selectOne instanceof HtmlSelectOneRadio)
149 {
150 return ((HtmlSelectOneRadio)selectOne).getLayout();
151 }
152
153 return (String)selectOne.getAttributes().get(JSFAttr.LAYOUT_ATTR);
154 }
155
156
157 protected String getStyleClass(UISelectOne selectOne)
158 {
159 if (selectOne instanceof HtmlSelectOneRadio)
160 {
161 return ((HtmlSelectOneRadio)selectOne).getStyleClass();
162 }
163
164 return (String)selectOne.getAttributes().get(JSFAttr.STYLE_CLASS_ATTR);
165 }
166
167
168
169
170
171
172 protected int renderGroupOrItemRadio(FacesContext facesContext,
173 UIComponent uiComponent, SelectItem selectItem,
174 Object currentValue,
175 Converter converter, boolean pageDirectionLayout,
176 Integer itemNum) throws IOException
177 {
178
179 ResponseWriter writer = facesContext.getResponseWriter();
180
181 boolean isSelectItemGroup = (selectItem instanceof SelectItemGroup);
182
183
184
185
186
187 UISelectOne selectOne = (UISelectOne)uiComponent;
188
189 if (isSelectItemGroup)
190 {
191 if (pageDirectionLayout)
192 {
193 writer.startElement(HTML.TR_ELEM, selectOne);
194 }
195
196 writer.startElement(HTML.TD_ELEM, selectOne);
197 writer.write(selectItem.getLabel());
198 writer.endElement(HTML.TD_ELEM);
199
200 if (pageDirectionLayout)
201 {
202 writer.endElement(HTML.TR_ELEM);
203 writer.startElement(HTML.TR_ELEM, selectOne);
204 }
205 writer.startElement(HTML.TD_ELEM, selectOne);
206
207 writer.startElement(HTML.TABLE_ELEM, selectOne);
208 writer.writeAttribute(HTML.BORDER_ATTR, "0", null);
209
210 if(!pageDirectionLayout)
211 {
212 writer.startElement(HTML.TR_ELEM, selectOne);
213 }
214
215 SelectItemGroup group = (SelectItemGroup) selectItem;
216 SelectItem[] selectItems = group.getSelectItems();
217
218 for (SelectItem groupSelectItem : selectItems)
219 {
220 itemNum = renderGroupOrItemRadio(facesContext, selectOne, groupSelectItem, currentValue,
221 converter, pageDirectionLayout, itemNum);
222 }
223
224 if(!pageDirectionLayout)
225 {
226 writer.endElement(HTML.TR_ELEM);
227 }
228 writer.endElement(HTML.TABLE_ELEM);
229 writer.endElement(HTML.TD_ELEM);
230
231 if (pageDirectionLayout)
232 {
233 writer.endElement(HTML.TR_ELEM);
234 }
235
236 }
237 else
238 {
239 String itemStrValue = org.apache.myfaces.shared.renderkit.RendererUtils.getConvertedStringValue(
240 facesContext, selectOne, converter, selectItem.getValue());
241 boolean itemChecked = (itemStrValue == null) ?
242 itemStrValue == currentValue :
243 "".equals(itemStrValue) ?
244 (currentValue == null || itemStrValue.equals(currentValue)) :
245 itemStrValue.equals(currentValue);
246
247
248
249
250
251 if (HtmlRendererUtils.isHideNoSelectionOption(uiComponent) && selectItem.isNoSelectionOption()
252 && currentValue != null && !"".equals(currentValue) && !itemChecked)
253 {
254
255 return itemNum;
256 }
257
258 writer.write("\t\t");
259 if (pageDirectionLayout)
260 {
261 writer.startElement(HTML.TR_ELEM, selectOne);
262 }
263 writer.startElement(HTML.TD_ELEM, selectOne);
264
265 boolean itemDisabled = selectItem.isDisabled();
266
267 String itemId = renderRadio(facesContext, selectOne, itemStrValue, itemDisabled,
268 itemChecked, false, itemNum);
269
270
271 boolean componentDisabled = isDisabled(facesContext, selectOne);
272 boolean disabled = (componentDisabled || itemDisabled);
273
274 HtmlRendererUtils.renderLabel(writer, selectOne, itemId, selectItem, disabled);
275
276 writer.endElement(HTML.TD_ELEM);
277 if (pageDirectionLayout)
278 {
279 writer.endElement(HTML.TR_ELEM);
280 }
281
282
283 itemNum++;
284 }
285 return itemNum;
286 }
287
288 @Deprecated
289 protected void renderRadio(FacesContext facesContext,
290 UIComponent uiComponent,
291 String value,
292 String label,
293 boolean disabled,
294 boolean checked, boolean renderId)
295 throws IOException
296 {
297 renderRadio(facesContext, (UIInput) uiComponent, value, disabled, checked, renderId, 0);
298 }
299
300
301
302
303
304 protected String renderRadio(FacesContext facesContext,
305 UIInput uiComponent,
306 String value,
307 boolean disabled,
308 boolean checked,
309 boolean renderId,
310 Integer itemNum)
311 throws IOException
312 {
313 String clientId = uiComponent.getClientId(facesContext);
314
315 String itemId = (itemNum == null)? null : clientId +
316 UINamingContainer.getSeparatorChar(facesContext) + itemNum;
317
318 ResponseWriter writer = facesContext.getResponseWriter();
319
320 writer.startElement(HTML.INPUT_ELEM, uiComponent);
321
322 if (itemId != null)
323 {
324 writer.writeAttribute(HTML.ID_ATTR, itemId, null);
325 }
326 else if (renderId)
327 {
328 writer.writeAttribute(HTML.ID_ATTR, clientId, null);
329 }
330 writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
331 writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
332
333 if (disabled)
334 {
335 writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
336 }
337
338 if (checked)
339 {
340 writer.writeAttribute(HTML.CHECKED_ATTR, HTML.CHECKED_ATTR, null);
341 }
342
343 if (value != null)
344 {
345 writer.writeAttribute(HTML.VALUE_ATTR, value, null);
346 }
347 else
348 {
349 writer.writeAttribute(HTML.VALUE_ATTR, "", null);
350 }
351
352 Map<String, List<ClientBehavior>> behaviors = null;
353 if (uiComponent instanceof ClientBehaviorHolder && JavascriptUtils.isJavascriptAllowed(
354 facesContext.getExternalContext()))
355 {
356 behaviors = ((ClientBehaviorHolder) uiComponent).getClientBehaviors();
357
358 long commonPropertiesMarked = 0L;
359 if (isCommonPropertiesOptimizationEnabled(facesContext))
360 {
361 commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
362 }
363 if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
364 {
365 CommonPropertyUtils.renderChangeEventProperty(writer,
366 commonPropertiesMarked, uiComponent);
367 CommonPropertyUtils.renderEventProperties(writer,
368 commonPropertiesMarked, uiComponent);
369 CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer,
370 commonPropertiesMarked, uiComponent);
371 }
372 else
373 {
374 HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
375 if (isCommonEventsOptimizationEnabled(facesContext))
376 {
377 Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
378 CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer,
379 commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
380 CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
381 facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
382 }
383 else
384 {
385 HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
386 HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
387 facesContext, writer, uiComponent, behaviors);
388 }
389 }
390 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
391 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE_AND_EVENTS);
392 }
393 else
394 {
395 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
396 HTML.INPUT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_STYLE);
397 }
398
399 if (isDisabled(facesContext, uiComponent))
400 {
401 writer.writeAttribute(org.apache.myfaces.shared.renderkit.html.HTML.DISABLED_ATTR, Boolean.TRUE, null);
402 }
403
404 writer.endElement(HTML.INPUT_ELEM);
405
406 return itemId;
407 }
408
409
410 protected boolean isDisabled(FacesContext facesContext, UIComponent uiComponent)
411 {
412
413 if (uiComponent instanceof HtmlSelectOneRadio)
414 {
415 return ((HtmlSelectOneRadio)uiComponent).isDisabled();
416 }
417
418 return org.apache.myfaces.shared.renderkit.RendererUtils.getBooleanAttribute(
419 uiComponent, HTML.DISABLED_ATTR, false);
420 }
421
422
423 public void decode(FacesContext facesContext, UIComponent uiComponent)
424 {
425 org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, uiComponent, null);
426 if (uiComponent instanceof UIInput)
427 {
428 HtmlRendererUtils.decodeUISelectOne(facesContext, uiComponent);
429 }
430 if (uiComponent instanceof ClientBehaviorHolder &&
431 !HtmlRendererUtils.isDisabled(uiComponent))
432 {
433 HtmlRendererUtils.decodeClientBehaviors(facesContext, uiComponent);
434 }
435 }
436
437
438 public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue)
439 throws ConverterException
440 {
441 RendererUtils.checkParamValidity(facesContext, uiComponent, UISelectOne.class);
442 return org.apache.myfaces.shared.renderkit.RendererUtils.getConvertedUISelectOneValue(facesContext,
443 (UISelectOne)uiComponent,
444 submittedValue);
445 }
446
447 }