You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by Apache Wiki <wi...@apache.org> on 2007/05/23 19:51:07 UTC

[Myfaces Wiki] Update of "FAQ" by AndrewRobinson

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Myfaces Wiki" for change notification.

The following page has been changed by AndrewRobinson:
http://wiki.apache.org/myfaces/FAQ

The comment on the change is:
Add q&a about select items no longer working in 1.1.5

------------------------------------------------------------------------------
  
  Thanks to Murray Brandon for the initial contribution.
  
+ === Select Items stop working in MyFaces 1.1.5 ===
+ 
+ MyFaces 1.1.4 and earlier did not correctly implement the select components. Although the behavior was nice, the components were not supposed to convert the values from the UISelectItems. For example, in 1.1.4 this would have worked:
+ 
+ {{{<f:selectOneMenu value="#{bean.intValue}"><f:selectItem itemValue="1" /></selectOneMenu>}}}
+ 
+ The reason this used to work is that the code in the past used the converter on the select one menu component to convert the value from the select item. According to the JSF specification, this is not supposed to be done. Therefore, it is important that the converted value from the selectOneMenu is identical (passes the equals function test) to the itemValue from one of the select items. Therefore, for the example above, itemValue must be an integer value, not a string with a number in it. 
+ 
+ If you want the old behavior, I suggest creating a custom selectItem component that converts the value using the converter from the input control. Here is the code:
+ 
+ {{{public class UISelectItem
+   extends javax.faces.component.UISelectItem
+ {
+   public final static String COMPONENT_TYPE = "org.apache.myfaces.wiki.SelectItem";
+   private Boolean convertValue;
+ 
+   /**
+    * @return the convertValue
+    */
+   public boolean getConvertValue()
+   {
+     if (this.convertValue != null) return this.convertValue;
+     ValueBinding vb = getValueBinding("convertValue");
+     return (vb == null) ? true : (Boolean) vb.getValue(getFacesContext());
+   }
+ 
+   /**
+    * @param convertValue the convertValue to set
+    */
+   public void setConvertValue(boolean convertValue)
+   {
+     this.convertValue = convertValue;
+   }
+ 
+   /**
+    * @see javax.faces.component.UISelectItem#getItemValue()
+    */
+   @Override
+   public Object getItemValue()
+   {
+     Object value = super.getItemValue();
+     
+     if (getConvertValue())
+     {
+       UIInput parent = null;
+       for (UIComponent comp = getParent(); comp != null; comp = comp.getParent())
+       {
+         if (comp instanceof UIInput)
+         {
+           parent = (UIInput)comp;
+           break;
+         }
+       }
+       if (parent != null)
+         value = getConvertedValue(getFacesContext(), parent, value);
+     }
+     return value;
+   }
+ 
+   /**
+    * @see javax.faces.component.UISelectItem#saveState(javax.faces.context.FacesContext)
+    */
+   @Override
+   public Object saveState(FacesContext context)
+   {
+     return new Object[] {
+       super.saveState(context), convertValue, };
+   }
+ 
+   /**
+    * @see javax.faces.component.UISelectItem#restoreState(javax.faces.context.FacesContext, java.lang.Object)
+    */
+   @Override
+   public void restoreState(FacesContext context, Object state)
+   {
+     Object[] arr = (Object[]) state;
+     int index = -1;
+     super.restoreState(context, arr[++index]);
+     this.convertValue = (Boolean) arr[++index];
+   }
+ 
+   private Object getConvertedValue(FacesContext context, UIInput input, Object value)
+     throws ConverterException
+   {
+     Renderer renderer = getRenderer(context);
+     if (renderer != null)
+       return renderer.getConvertedValue(context, this, value);
+     else if (value instanceof String)
+     {
+       Converter converter = RendererUtils.findUIOutputConverter(
+         context, input);
+       if (converter != null)
+         return converter.getAsObject(context, this, (String)value);
+     }
+     return value;
+   }
+ }}}}
+ 
+ Then just register this new component in the standard JSF way.
+