View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
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.AbstractUISelectManyCheckbox;
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.SelectItemUtils;
28  import org.apache.myfaces.tobago.internal.util.StringUtils;
29  import org.apache.myfaces.tobago.renderkit.css.BootstrapClass;
30  import org.apache.myfaces.tobago.renderkit.html.HtmlAttributes;
31  import org.apache.myfaces.tobago.renderkit.html.HtmlElements;
32  import org.apache.myfaces.tobago.renderkit.html.HtmlInputTypes;
33  import org.apache.myfaces.tobago.util.ComponentUtils;
34  import org.apache.myfaces.tobago.webapp.TobagoResponseWriter;
35  
36  import javax.faces.context.FacesContext;
37  import javax.faces.model.SelectItem;
38  import java.io.IOException;
39  
40  public class SelectManyCheckboxRenderer<T extends AbstractUISelectManyCheckbox> extends SelectManyRendererBase<T> {
41  
42    @Override
43    public HtmlElements getComponentTag() {
44      return HtmlElements.TOBAGO_SELECT_MANY_CHECKBOX;
45    }
46  
47    @Override
48    public void encodeBeginField(final FacesContext facesContext, final T component) throws IOException {
49      final AbstractUISelectReference reference = component.getRenderRangeReference();
50      final TobagoResponseWriter writer = getResponseWriter(facesContext);
51  
52      final String id = component.getClientId(facesContext);
53  //    final String referenceId = reference != null ? reference.getClientId(facesContext) : id;
54      final String title = HtmlRendererUtils.getTitleFromTipAndMessages(facesContext, component);
55      final boolean disabled = component.isDisabled();
56      final boolean readonly = component.isReadonly();
57      final boolean required = component.isRequired();
58      final boolean inline = component.isInline();
59      final Markup markup = component.getMarkup();
60      final boolean isInsideCommand = isInside(facesContext, HtmlElements.COMMAND);
61  
62      writer.startElement(HtmlElements.TOBAGO_SELECT_MANY_CHECKBOX);
63      writer.writeClassAttribute(
64          inline ? BootstrapClass.FORM_CHECK_INLINE : null,
65          component.getCustomClass());
66      HtmlRendererUtils.writeDataAttributes(facesContext, writer, component);
67      if (title != null) {
68        writer.writeAttribute(HtmlAttributes.TITLE, title, true);
69      }
70      boolean first = true;
71      final Object[] values = component.getSelectedValues();
72      final String[] submittedValues = getSubmittedValues(component);
73      int i = 0;
74      final int[] renderRange = getRenderRangeList(component, reference);
75      for (final SelectItem item : SelectItemUtils.getItemIterator(facesContext, component)) {
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.CHECKBOX);
87          final String formattedValue = ComponentUtils.getFormattedValue(facesContext, component, item.getValue());
88          final boolean checked;
89          if (submittedValues == null) {
90            checked = ArrayUtils.contains(values, item.getValue());
91          } else {
92            checked = ArrayUtils.contains(submittedValues, formattedValue);
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 
112         if (item instanceof org.apache.myfaces.tobago.model.SelectItem) {
113           final org.apache.myfaces.tobago.model.SelectItem tobagoItem =
114               (org.apache.myfaces.tobago.model.SelectItem) item;
115           final String image = tobagoItem.getImage();
116           if (image != null) {
117             writer.startElement(HtmlElements.IMG);
118             writer.writeAttribute(HtmlAttributes.SRC, image, true);
119             writer.writeAttribute(HtmlAttributes.ALT, "", false);
120             writer.endElement(HtmlElements.IMG);
121           }
122         }
123 
124         final String label = item.getLabel();
125         if (label != null) {
126           writer.writeText(label);
127         }
128 
129         writer.endElement(HtmlElements.LABEL);
130         writer.endElement(HtmlElements.DIV);
131       }
132       i++;
133     }
134   }
135 
136   private int[] getRenderRangeList(AbstractUISelectManyCheckbox select, AbstractUISelectReference reference) {
137     final int[] indices
138         = StringUtils.getIndices(reference != null ? reference.getRenderRange() : select.getRenderRange());
139     return indices.length > 0 ? indices : null;
140   }
141 
142   @Override
143   protected void encodeEndField(final FacesContext facesContext, final T component) throws IOException {
144     final TobagoResponseWriter writer = getResponseWriter(facesContext);
145 
146     writer.endElement(HtmlElements.TOBAGO_SELECT_MANY_CHECKBOX);
147 
148     encodeBehavior(writer, facesContext, component);
149   }
150 
151   @Override
152   protected String getFieldId(final FacesContext facesContext, final T component) {
153     return component.getClientId(facesContext);
154   }
155 }