1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.myfaces.tobago.internal.renderkit.renderer;
21
22 import org.apache.myfaces.tobago.context.Markup;
23 import org.apache.myfaces.tobago.internal.component.AbstractUISelectOneRadio;
24 import org.apache.myfaces.tobago.internal.component.AbstractUISelectReference;
25 import org.apache.myfaces.tobago.internal.util.ArrayUtils;
26 import org.apache.myfaces.tobago.internal.util.HtmlRendererUtils;
27 import org.apache.myfaces.tobago.internal.util.ObjectUtils;
28 import org.apache.myfaces.tobago.internal.util.SelectItemUtils;
29 import org.apache.myfaces.tobago.internal.util.StringUtils;
30 import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
31 import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
32 import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
33 import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
34 import org.apache.myfaces.tobago.util.ComponentUtils;
35 import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
36
37 import javax.faces.context.FacesContext;
38 import javax.faces.model.SelectItem;
39 import java.io.IOException;
40
41 public class SelectOneRadioRenderer<T extends AbstractUISelectOneRadio> extends SelectOneRendererBase<T> {
42
43 @Override
44 public HtmlElements getComponentTag() {
45 return HtmlElements.TOBAGO_SELECT_ONE_RADIO;
46 }
47
48 @Override
49 protected void encodeBeginField(final FacesContext facesContext, final T component) throws IOException {
50 final AbstractUISelectReference reference = component.getRenderRangeReference();
51 final TobagoResponseWriter writer = getResponseWriter(facesContext);
52
53 final String id = component.getClientId(facesContext);
54
55 final Iterable<SelectItem> items = SelectItemUtils.getItemIterator(facesContext, component);
56 final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, component);
57 final boolean disabled = component.isDisabled();
58 final boolean readonly = component.isReadonly();
59 final boolean required = component.isRequired();
60 final boolean inline = component.isInline();
61 final Markup markup = component.getMarkup();
62 final boolean isInsideCommand = isInside(facesContext, HtmlElements.COMMAND);
63
64 writer.startElement(getTag(facesContext));
65 writer.writeClassAttribute(
66 inline ? BootstrapClass.FORM_CHECK_INLINE : null,
67 component.getCustomClass());
68 HtmlRendererUtils.writeDataAttributes(facesContext, writer, component);
69 writer.writeAttribute(HtmlAttributes.TITLE, title, true);
70 boolean first = true;
71 final Object value = component.getValue();
72 final String submittedValue = (String) component.getSubmittedValue();
73 int i = 0;
74 final int[] renderRange = getRenderRangeList(component, reference);
75 for (final SelectItem item : items) {
76 if (renderRange == null || ArrayUtils.contains(renderRange, i)) {
77 final boolean itemDisabled = item.isDisabled() || disabled;
78 final String itemId = id + ComponentUtils.SUB_SEPARATOR + i;
79 writer.startElement(HtmlElements.DIV);
80 writer.writeClassAttribute(
81 BootstrapClass.FORM_CHECK,
82 inline ? BootstrapClass.FORM_CHECK_INLINE : null,
83 isInsideCommand ? BootstrapClass.DROPDOWN_ITEM : null);
84 writer.startElement(HtmlElements.INPUT);
85 writer.writeClassAttribute(BootstrapClass.FORM_CHECK_INPUT);
86 writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.RADIO);
87 final String formattedValue = ComponentUtils.getFormattedValue(facesContext, component, item.getValue());
88 final boolean checked;
89 if (submittedValue == null) {
90 checked = ObjectUtils.equals(item.getValue(), value);
91 } else {
92 checked = ObjectUtils.equals(formattedValue, submittedValue);
93 }
94 writer.writeAttribute(HtmlAttributes.CHECKED, checked);
95 writer.writeNameAttribute(id);
96 writer.writeIdAttribute(itemId);
97 writer.writeAttribute(HtmlAttributes.VALUE, formattedValue, true);
98 writer.writeAttribute(HtmlAttributes.DISABLED, itemDisabled);
99 writer.writeAttribute(HtmlAttributes.READONLY, readonly);
100 writer.writeAttribute(HtmlAttributes.REQUIRED, required);
101 if (first) {
102 renderFocus(id, component.isFocus(), component.isError(), facesContext, writer);
103 first = false;
104 }
105 writer.writeAttribute(HtmlAttributes.TABINDEX, component.getTabIndex());
106 writer.endElement(HtmlElements.INPUT);
107
108 writer.startElement(HtmlElements.LABEL);
109 writer.writeClassAttribute(BootstrapClass.FORM_CHECK_LABEL);
110 writer.writeAttribute(HtmlAttributes.FOR, itemId, false);
111 if (item instanceof org.apache.myfaces.tobago.model.SelectItem) {
112 final org.apache.myfaces.tobago.model.SelectItem tobagoItem =
113 (org.apache.myfaces.tobago.model.SelectItem) item;
114 final String image = tobagoItem.getImage();
115 if (image != null) {
116 writer.startElement(HtmlElements.IMG);
117 writer.writeAttribute(HtmlAttributes.SRC, image, true);
118 writer.writeAttribute(HtmlAttributes.ALT, "", false);
119 writer.endElement(HtmlElements.IMG);
120 }
121 }
122
123 final String label = item.getLabel();
124 if (label != null) {
125 writer.writeText(label);
126 }
127
128 writer.endElement(HtmlElements.LABEL);
129 writer.endElement(HtmlElements.DIV);
130 }
131 i++;
132 }
133 }
134
135 private int[] getRenderRangeList(AbstractUISelectOneRadio select, AbstractUISelectReference reference) {
136 final int[] indices
137 = StringUtils.getIndices(reference != null ? reference.getRenderRange() : select.getRenderRange());
138 return indices.length > 0 ? indices : null;
139 }
140
141 @Override
142 protected void encodeEndField(final FacesContext facesContext, final T component) throws IOException {
143 final TobagoResponseWriter writer = getResponseWriter(facesContext);
144
145 writer.endElement(getTag(facesContext));
146
147 encodeBehavior(writer, facesContext, component);
148 }
149
150 private HtmlElements getTag(final FacesContext facesContext) {
151 if (isInside(facesContext, HtmlElements.COMMAND)) {
152 return HtmlElements.TOBAGO_SELECT_ONE_RADIO;
153 } else {
154 return HtmlElements.DIV;
155 }
156 }
157
158 @Override
159 protected String getFieldId(final FacesContext facesContext, final T component) {
160 return null;
161 }
162 }