Fix for Tomahawk checkbox with disabled SelectItems


Today I will publish a little bugfix for tomahawk <t:checkbox/> issue  1436.

I’m using tomahawk 1.1.7 the current development version is 1.1.9, the  issue „t:checkbox disregards disabled property“ is still unresolved.

So here is the solution …

I wrote my own HtmlCheckboxRenderer:

/**
 * Fix for issue https://issues.apache.org/jira/browse/TOMAHAWK-1436.
 * The renderer should evaluate the "disabled" state for a each {@link SelectItem} too.
 */
public class HtmlCheckboxRendererFix1436 extends HtmlCheckboxRenderer {

 @Override
 protected void renderSingleCheckbox(final FacesContext facesContext,
                                     final HtmlCheckbox checkbox) throws IOException {
   // copied from original
   final String forAttr = checkbox.getFor();
   if (forAttr == null) {
      throw new IllegalStateException("mandatory attribute 'for'");
   }
   final int index = checkbox.getIndex();
   if (index < 0) {
      throw new IllegalStateException("positive index must be given");
   }
   final UIComponent uiComponent = checkbox.findComponent(forAttr);
   if (uiComponent == null) {
      throw new IllegalStateException("Could not find component '" + forAttr
      + "' (calling findComponent on component '"
      + checkbox.getClientId(facesContext) + "')");
   }
   if (!(uiComponent instanceof UISelectMany)) {
      throw new IllegalStateException("UISelectMany expected");
   }
   final UISelectMany uiSelectMany = (UISelectMany) uiComponent;
   final Converter converter = getConverter(facesContext, uiSelectMany);
   final List selectItemList = RendererUtils.getSelectItemList(uiSelectMany);
   if (index >= selectItemList.size()) {
     throw new IndexOutOfBoundsException("index " + index + " >= " + selectItemList.size());
   }
   final SelectItem selectItem = (SelectItem) selectItemList.get(index);
   final Object itemValue = selectItem.getValue();
   final String itemStrValue = getItemStringValue(facesContext, uiSelectMany, converter, itemValue);
   final Set lookupSet = RendererUtils.getSelectedValuesAsSet(facesContext, uiComponent, converter, uiSelectMany);
   final ResponseWriter writer = facesContext.getResponseWriter();
   writer.startElement(HTML.LABEL_ELEM, uiSelectMany);

   // FIX 1436 isDisabled should check selectitem too!
   //          || selectItem.isDisabled()
   renderCheckbox(facesContext, uiSelectMany, itemStrValue, selectItem.getLabel(),
                  isDisabled(facesContext, uiSelectMany) || selectItem.isDisabled(),
                  lookupSet.contains(itemStrValue), false, index);
   // FIX 1436 isDisabled should check selectitem too!

   writer.endElement(HTML.LABEL_ELEM);
 }
}

and put it in my faces-config.xml:

<render-kit>
  <render-kit-id>HTML_BASIC</render-kit-id>
  <renderer>
    <!-- fixed org.apache.myfaces.renderkit.html.ext.HtmlCheckboxRenderer issue 1436 -->
    <component-family>org.apache.myfaces.Checkbox</component-family>
    <renderer-type>org.apache.myfaces.Checkbox</renderer-type>
    <renderer-class>org.apache.myfaces.renderkit.html.ext.HtmlCheckboxRendererFix1436</renderer-class>
  </renderer>
</render-kit>

With this changes the following example will work:

<a4j:form>
 <t:selectManyCheckbox id="name" layout="spread">
   <f:selectItem itemValue="0" itemLabel="foo"        itemDisabled="true"/>
   <f:selectItem itemValue="1" itemLabel="bar"        />
   <f:selectItem itemValue="2" itemLabel="hustensaft" />
 </t:selectManyCheckbox>
 <h:panelGrid>
   <t:checkbox for="name" index="0"  />
   <t:checkbox for="name" index="1"  />
   <t:checkbox for="name" index="2"  />
 </h:panelGrid>
</a4j:form>

The first checkbox should be disabled:

That’s it😀