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