5 Replies Latest reply on Oct 31, 2007 12:17 PM by Pete Muir

    EnumConverter for multi-select lists

    Joshua Davis Expert

      Hi everyone. I'd like to contribute the following converter. It allows you to use a multi-select list with enum values. I just took the existing EnumConverter and added come code to look for the s:selectItems control that has a value which is a list or array of enums.

      I put something up on my own wiki about it here:
      http://shrubbery.mynetgear.net/wiki/Select_lists_with_Seam#Multi-select_from_an_enum

      And here's the code:

      package eg;
      
      import javax.faces.component.*;
      import javax.faces.context.*;
      import javax.faces.convert.*;
      import javax.faces.el.ValueBinding;
      import java.util.List;
      import java.util.Collection;
      
      /**
       * Converter for enum multi-selects.
       * <br>User: Joshua Davis
       * Date: May 16, 2007
       * Time: 7:25:58 AM
       */
      public class EnumListConverter implements Converter
      {
       @SuppressWarnings({"unchecked"})
       public Object getAsObject(FacesContext context,
       UIComponent comp,
       String value)
       throws ConverterException
       {
       ValueBinding binding = comp.getValueBinding("value");
       Class enumType = binding.getType(context);
       if (enumType.isEnum()) // Single enum?
       return Enum.valueOf(enumType, value);
       else // List of enums.
       {
       // Find the s:selectItems so we can get the enum.
       List children = comp.getChildren();
       for (Object child : children)
       {
       if (child instanceof UIComponent)
       {
       UIComponent c = (UIComponent) child;
       ValueBinding b = c.getValueBinding("value");
       Class t = b.getType(context);
       // Array of enums: use the component type.
       if (t.isArray() && t.getComponentType().isEnum())
       {
       t = t.getComponentType();
       return Enum.valueOf(t,value);
       }
       else
       {
       Object v = b.getValue(context);
       // Collection of enum values, get the type of the first element.
       if (v instanceof Collection)
       {
       t = ((Collection) v).iterator().next().getClass();
       return Enum.valueOf(t,value);
       }
       }
       }
       }
       throw new ConverterException("Unable to find selectItems with enum values!");
       }
       }
      
       public String getAsString(FacesContext context,
       UIComponent component,
       Object object)
       throws ConverterException
       {
       if (object == null) {
       return null;
       }
      
       return ((Enum) object).name();
       }
      
      }
      


      After registering it with facelets, it can be used like this:
      <h:selectManyCheckbox id="roles"
       layout="pageDirection" value="#{person.roles}"
       required="true">
       <s:selectItems value="#{enumLists.roleArray}" var="role"
       label="#{role}"/>
       <s:convertEnum/>
      </h:selectManyCheckbox>