myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lu4...@apache.org
Subject svn commit: r1793913 - in /myfaces/core/branches/2.3.x: api/src/main/java/javax/faces/component/ shared/src/main/java/org/apache/myfaces/shared/renderkit/html/
Date Thu, 04 May 2017 22:16:56 GMT
Author: lu4242
Date: Thu May  4 22:16:56 2017
New Revision: 1793913

URL: http://svn.apache.org/viewvc?rev=1793913&view=rev
Log:
MYFACES-4115 Implement h:selectOneRadio "group" (distributed radio button)

Modified:
    myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/UISelectOne.java
    myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/_ComponentUtils.java
    myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java
    myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java

Modified: myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/UISelectOne.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/UISelectOne.java?rev=1793913&r1=1793912&r2=1793913&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/UISelectOne.java (original)
+++ myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/UISelectOne.java Thu
May  4 22:16:56 2017
@@ -21,10 +21,13 @@ package javax.faces.component;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import javax.el.ValueExpression;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitResult;
 import javax.faces.context.FacesContext;
 import javax.faces.convert.Converter;
 import javax.faces.model.SelectItem;
-
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
 
@@ -102,4 +105,20 @@ public class UISelectOne extends UIInput
                 new Object[] {_MessageUtils.getLabel(context, this) });
         setValid(false);
     }
+
+    public String getGroup()
+    {
+        return (String) getStateHelper().eval(PropertyKeys.group);
+    }
+    
+    public void setGroup(String group)
+    {
+        getStateHelper().put(PropertyKeys.group, group ); 
+    }
+    
+    enum PropertyKeys
+    {
+        group
+    }
+    
 }

Modified: myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/_ComponentUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/_ComponentUtils.java?rev=1793913&r1=1793912&r2=1793913&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/_ComponentUtils.java
(original)
+++ myfaces/core/branches/2.3.x/api/src/main/java/javax/faces/component/_ComponentUtils.java
Thu May  4 22:16:56 2017
@@ -92,6 +92,21 @@ class _ComponentUtils
         }
         return null;
     }
+    
+    static UIForm findParentUIForm(UIComponent component)
+    {
+        UIComponent parent = component.getParent();
+
+        while (parent != null)
+        {
+            if (parent instanceof UIForm)
+            {
+                return (UIForm) parent;
+            }
+            parent = parent.getParent();
+        }
+        return null;
+    }
 
     static UniqueIdVendor findParentUniqueIdVendor(UIComponent component)
     {

Modified: myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java?rev=1793913&r1=1793912&r2=1793913&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java
(original)
+++ myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRadioRendererBase.java
Thu May  4 22:16:56 2017
@@ -19,10 +19,14 @@
 package org.apache.myfaces.shared.renderkit.html;
 
 import java.io.IOException;
+import java.util.Collections;
+import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Logger;
+import javax.el.ValueExpression;
 
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIInput;
@@ -30,6 +34,10 @@ import javax.faces.component.UISelectOne
 import javax.faces.component.behavior.ClientBehavior;
 import javax.faces.component.behavior.ClientBehaviorHolder;
 import javax.faces.component.html.HtmlSelectOneRadio;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
+import javax.faces.component.visit.VisitResult;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.convert.Converter;
@@ -39,6 +47,7 @@ import javax.faces.model.SelectItemGroup
 
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
 
 public class HtmlRadioRendererBase
@@ -49,7 +58,10 @@ public class HtmlRadioRendererBase
 
     private static final String PAGE_DIRECTION = "pageDirection";
     private static final String LINE_DIRECTION = "lineDirection";
-
+    
+    private static final  Set<VisitHint> FIND_SELECT_LIST_HINTS = 
+            Collections.unmodifiableSet(EnumSet.of(VisitHint.SKIP_UNRENDERED));
+    
     public void encodeEnd(FacesContext facesContext, UIComponent uiComponent) throws IOException
     {
         org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(
@@ -90,49 +102,142 @@ public class HtmlRadioRendererBase
             }
         }
         
-        writer.startElement(HTML.TABLE_ELEM, selectOne);
-        HtmlRendererUtils.renderHTMLAttributes(writer, selectOne,
-                                               HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
-        
-        if (behaviors != null && !behaviors.isEmpty())
+        String group = null;
+        if (uiComponent instanceof HtmlSelectOneRadio)
         {
-            writer.writeAttribute(HTML.ID_ATTR, selectOne.getClientId(facesContext), null);
+            group = ((HtmlSelectOneRadio)uiComponent).getGroup();
         }
-        else
+        if (group != null && group.length() > 0)
         {
-            HtmlRendererUtils.writeIdIfNecessary(writer, selectOne, facesContext); 
-        }        
+            // NEW JSF 2.3: Render as distributed component
+            String id = uiComponent.getId();
+            if (id != null && HtmlRendererUtils.GROUP_INDEXED_ID_CHECKER.matcher(id).matches())
+            {
+                // The id has a number/index at the end, use it to take the value. It means
the selectItemList
+                // is not in the current component and needs to be grabbed from some other
component to
+                // get the right one.
+                
+                int i = id.length() - 1;
+                while (i > 0 && Character.isDigit(id.charAt(i)))
+                {
+                    i--;
+                }
+                Integer itemNum = Integer.valueOf(id.substring(i+1));
+                
+                Converter converter;
+                List selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
+                        selectOne, facesContext);
+                converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext,
selectOne);
+                ValueExpression ve = selectOne.getValueExpression("value");
+                Object currentValue = null;
+                boolean currentValueSet = false;
+                if (ve != null || (selectItemList != null && selectItemList.size()
> 0))
+                {
+                    // No-op
+                }
+                else
+                {
+                    //Deferred, find Real Component and retrieve the selectItemList
+                    FormInfo formInfo = RendererUtils.findNestingForm(uiComponent, facesContext);
+                    GetSelectItemListCallback callback = new GetSelectItemListCallback(group);
+                    formInfo.getForm().visitTree(
+                            VisitContext.createVisitContext(facesContext, null, FIND_SELECT_LIST_HINTS),
callback);
+                    selectItemList = callback.getSelectItemList();
+                    converter = callback.getConverter();
+                    currentValueSet = true;
+                    currentValue = callback.getCurrentValue();
+                }
+                
+                if (selectItemList != null && selectItemList.size() > 0)
+                {
+                    if (!currentValueSet)
+                    {
+                        currentValue = 
+                            org.apache.myfaces.shared.renderkit.RendererUtils.
+                                    getStringFromSubmittedValueOrLocalValueReturnNull(
+                                    facesContext, selectOne);
+                    }
+
+                    SelectItem selectItem = (SelectItem) selectItemList.get(itemNum);
+                    renderGroupOrItemRadio(facesContext, selectOne,
+                                                         selectItem, currentValue,
+                                                         converter, pageDirectionLayout,
group, itemNum);
+                }
+            }
+            else
+            {
+                // The id is not set or is an id without index, which means the index will
be set by the clientId
+                // like for example inside a dataTable. The important thing here is do not
encapsulate the radio
+                // inside a <table> tag, because it is not necessary. 
+                
+                Converter converter;
+                List selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
+                        selectOne, facesContext);
+                converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext,
selectOne);
+
+                Object currentValue = 
+                    org.apache.myfaces.shared.renderkit.RendererUtils.getStringFromSubmittedValueOrLocalValueReturnNull(
+                            facesContext, selectOne);
 
-        if (!pageDirectionLayout)
-        {
-            writer.startElement(HTML.TR_ELEM, null); // selectOne);
+                int itemNum = 0;
+
+                for (Iterator it = selectItemList.iterator(); it.hasNext(); )
+                {
+                    SelectItem selectItem = (SelectItem)it.next();
+
+                    itemNum = renderGroupOrItemRadio(facesContext, selectOne,
+                                                     selectItem, currentValue,
+                                                     converter, pageDirectionLayout, group,
itemNum);
+                }
+            }
         }
+        else
+        {
+            // Render as single component
+            writer.startElement(HTML.TABLE_ELEM, selectOne);
+            HtmlRendererUtils.renderHTMLAttributes(writer, selectOne,
+                                                   HTML.SELECT_TABLE_PASSTHROUGH_ATTRIBUTES);
 
-        Converter converter;
-        List selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
-                selectOne, facesContext);
-        converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, selectOne);
-        
-        Object currentValue = 
-            org.apache.myfaces.shared.renderkit.RendererUtils.getStringFromSubmittedValueOrLocalValueReturnNull(
-                    facesContext, selectOne);
+            if (behaviors != null && !behaviors.isEmpty())
+            {
+                writer.writeAttribute(HTML.ID_ATTR, selectOne.getClientId(facesContext),
null);
+            }
+            else
+            {
+                HtmlRendererUtils.writeIdIfNecessary(writer, selectOne, facesContext); 
+            }        
+
+            if (!pageDirectionLayout)
+            {
+                writer.startElement(HTML.TR_ELEM, null); // selectOne);
+            }
 
-        int itemNum = 0;
+            Converter converter;
+            List selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
+                    selectOne, facesContext);
+            converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext, selectOne);
 
-        for (Iterator it = selectItemList.iterator(); it.hasNext(); )
-        {
-            SelectItem selectItem = (SelectItem)it.next();
+            Object currentValue = 
+                org.apache.myfaces.shared.renderkit.RendererUtils.getStringFromSubmittedValueOrLocalValueReturnNull(
+                        facesContext, selectOne);
 
-            itemNum = renderGroupOrItemRadio(facesContext, selectOne,
-                                             selectItem, currentValue,
-                                             converter, pageDirectionLayout, itemNum);
-        }
+            int itemNum = 0;
 
-        if (!pageDirectionLayout)
-        {
-            writer.endElement(HTML.TR_ELEM);
+            for (Iterator it = selectItemList.iterator(); it.hasNext(); )
+            {
+                SelectItem selectItem = (SelectItem)it.next();
+
+                itemNum = renderGroupOrItemRadio(facesContext, selectOne,
+                                                 selectItem, currentValue,
+                                                 converter, pageDirectionLayout, itemNum);
+            }
+
+            if (!pageDirectionLayout)
+            {
+                writer.endElement(HTML.TR_ELEM);
+            }
+            writer.endElement(HTML.TABLE_ELEM);            
         }
-        writer.endElement(HTML.TABLE_ELEM);
     }
 
 
@@ -157,6 +262,15 @@ public class HtmlRadioRendererBase
          return (String)selectOne.getAttributes().get(JSFAttr.STYLE_CLASS_ATTR);
      }
 
+    protected int renderGroupOrItemRadio(FacesContext facesContext,
+                                         UIComponent uiComponent, SelectItem selectItem,
+                                         Object currentValue,
+                                         Converter converter, boolean pageDirectionLayout,
+                                         Integer itemNum) throws IOException
+    {
+        return renderGroupOrItemRadio(facesContext, uiComponent, selectItem, 
+                currentValue,converter, pageDirectionLayout, null, itemNum);
+    }
 
     /**
      * Renders the given SelectItem(Group)
@@ -165,7 +279,7 @@ public class HtmlRadioRendererBase
     protected int renderGroupOrItemRadio(FacesContext facesContext,
                                          UIComponent uiComponent, SelectItem selectItem,
                                          Object currentValue,
-                                         Converter converter, boolean pageDirectionLayout,
+                                         Converter converter, boolean pageDirectionLayout,
String group,
                                          Integer itemNum) throws IOException
     {
 
@@ -212,8 +326,8 @@ public class HtmlRadioRendererBase
                 writer.startElement(HTML.TR_ELEM, null); // selectOne);
             }
 
-            SelectItemGroup group = (SelectItemGroup) selectItem;
-            SelectItem[] selectItems = group.getSelectItems();
+            SelectItemGroup selectItemGroup = (SelectItemGroup) selectItem;
+            SelectItem[] selectItems = selectItemGroup.getSelectItems();
 
             for (SelectItem groupSelectItem : selectItems)
             { 
@@ -255,28 +369,44 @@ public class HtmlRadioRendererBase
                 return itemNum;
             }
             
-            writer.write("\t\t");
-            if (pageDirectionLayout)
+            //writer.write("\t\t");
+            boolean renderGroupId = false;
+            if (group != null && group.length() > 0)
             {
-                writer.startElement(HTML.TR_ELEM, null); // selectOne);
+                //no op
+                renderGroupId = true;
+            }
+            else
+            {
+                if (pageDirectionLayout)
+                {
+                    writer.startElement(HTML.TR_ELEM, null); // selectOne);
+                }
+                writer.startElement(HTML.TD_ELEM, null); // selectOne);
             }
-            writer.startElement(HTML.TD_ELEM, null); // selectOne);
     
             boolean itemDisabled = selectItem.isDisabled();
     
             String itemId = renderRadio(facesContext, selectOne, itemStrValue, itemDisabled,

-                    itemChecked, false, itemNum);
+                    itemChecked, renderGroupId ? true : false, renderGroupId ? null : itemNum);
     
             // label element after the input
             boolean componentDisabled = isDisabled(facesContext, selectOne);
             boolean disabled = (componentDisabled || itemDisabled);
     
             HtmlRendererUtils.renderLabel(writer, selectOne, itemId, selectItem, disabled);
-    
-            writer.endElement(HTML.TD_ELEM);
-            if (pageDirectionLayout)
+
+            if (group != null && group.length() > 0)
             {
-                writer.endElement(HTML.TR_ELEM);
+                //no op
+            }
+            else
+            {
+                writer.endElement(HTML.TD_ELEM);
+                if (pageDirectionLayout)
+                {
+                    writer.endElement(HTML.TR_ELEM);
+                }
             }
             
             // we rendered one radio --> increment itemNum
@@ -328,7 +458,22 @@ public class HtmlRadioRendererBase
             writer.writeAttribute(HTML.ID_ATTR, clientId, null);
         }
         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_RADIO, null);
-        writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
+        
+        String group = null;
+        if (uiComponent instanceof HtmlSelectOneRadio)
+        {
+            group = ((HtmlSelectOneRadio)uiComponent).getGroup();
+        }
+        if (group != null && group.length() > 0)
+        {
+            FormInfo formInfo = RendererUtils.findNestingForm(uiComponent, facesContext);
+            writer.writeAttribute(HTML.NAME_ATTR, formInfo.getFormName()+
+                    facesContext.getNamingContainerSeparatorChar() + group, null);
+        }
+        else
+        {
+            writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
+        }
 
         if (disabled)
         {
@@ -340,13 +485,29 @@ public class HtmlRadioRendererBase
             writer.writeAttribute(HTML.CHECKED_ATTR, HTML.CHECKED_ATTR, null);
         }
 
-        if (value != null)
+        if (group != null && group.length() > 0)
         {
-            writer.writeAttribute(HTML.VALUE_ATTR, value, null);
+            if (value != null)
+            {
+                writer.writeAttribute(HTML.VALUE_ATTR, 
+                        clientId + facesContext.getNamingContainerSeparatorChar() +value,
null);
+            }
+            else
+            {
+                writer.writeAttribute(HTML.VALUE_ATTR, 
+                        clientId + facesContext.getNamingContainerSeparatorChar() + "", null);
+            }
         }
         else
         {
-            writer.writeAttribute(HTML.VALUE_ATTR, "", null);
+            if (value != null)
+            {
+                writer.writeAttribute(HTML.VALUE_ATTR, value, null);
+            }
+            else
+            {
+                writer.writeAttribute(HTML.VALUE_ATTR, "", null);
+            }
         }
         
         Map<String, List<ClientBehavior>> behaviors = null;
@@ -447,5 +608,73 @@ public class HtmlRadioRendererBase
                                                                                         
      (UISelectOne)uiComponent,
                                                                                         
      submittedValue);
     }
+    
+    private static class GetSelectItemListCallback implements VisitCallback
+    {
+        private String group;
+        private List selectItemList;
+        private Converter converter;
+        private Object currentValue;
+
+        public GetSelectItemListCallback(String group)
+        {
+            this.group = group;
+        }
+
+        @Override
+        public VisitResult visit(VisitContext context, UIComponent target)
+        {
+            if (target instanceof UISelectOne)
+            {
+                String targetGroup = ((UISelectOne)target).getGroup();
+                if (getGroup().equals(targetGroup))
+                {
+                    ValueExpression value = target.getValueExpression("value");
+                    if (value != null)
+                    {
+                        UISelectOne selectOne = (UISelectOne) target;
+                        FacesContext facesContext = context.getFacesContext();
+                        selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils.getSelectItemList(
+                            selectOne, facesContext);
+                        converter = HtmlRendererUtils.findUIOutputConverterFailSafe(facesContext,
selectOne);
+                        
+                        if (selectItemList != null && selectItemList.size() >
0)
+                        {
+                            currentValue = 
+                                org.apache.myfaces.shared.renderkit.RendererUtils.
+                                        getStringFromSubmittedValueOrLocalValueReturnNull(
+                                        context.getFacesContext(), selectOne);
+                        }
+                        return VisitResult.COMPLETE;
+                    }
+                }
+                else
+                {
+                    return VisitResult.REJECT;
+                }
+            }
+            return VisitResult.ACCEPT;
+        }
+
+        public String getGroup()
+        {
+            return group;
+        }
+
+        public List getSelectItemList()
+        {
+            return selectItemList;
+        }
+
+        public Converter getConverter()
+        {
+            return converter;
+        }
+
+        public Object getCurrentValue()
+        {
+            return currentValue;
+        }
+    }
 
 }

Modified: myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java?rev=1793913&r1=1793912&r2=1793913&view=diff
==============================================================================
--- myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
(original)
+++ myfaces/core/branches/2.3.x/shared/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlRendererUtils.java
Thu May  4 22:16:56 2017
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -32,6 +33,7 @@ import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.regex.Pattern;
 
 import javax.faces.FacesException;
 import javax.faces.component.EditableValueHolder;
@@ -51,6 +53,10 @@ import javax.faces.component.behavior.Cl
 import javax.faces.component.html.HtmlDataTable;
 import javax.faces.component.html.HtmlMessages;
 import javax.faces.component.html.HtmlPanelGrid;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
+import javax.faces.component.visit.VisitResult;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.PartialViewContext;
@@ -92,6 +98,7 @@ public final class HtmlRendererUtils
             + "  Consider setting read-only to true instead"
             + " or resetting the disabled value back to false prior to form submission.";
     public static final String STR_EMPTY = "";
+    public static final Pattern GROUP_INDEXED_ID_CHECKER = Pattern.compile("^.*\\d$");
 
     private HtmlRendererUtils()
     {
@@ -256,7 +263,37 @@ public final class HtmlRendererUtils
         {
             return;
         }
+        
         Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
+        if (component instanceof UISelectOne)
+        {
+            String group = ((UISelectOne) component).getGroup();
+            if (group != null && group.length() > 0)
+            {
+                FormInfo formInfo = RendererUtils.findNestingForm(component, facesContext);
+                String fullGroupId = formInfo.getFormName()+
+                        facesContext.getNamingContainerSeparatorChar()+group;
+                if (paramMap.containsKey(fullGroupId))
+                {
+                    String submittedValue = (String) paramMap.get(fullGroupId);
+                    String expectedStart = component.getClientId(facesContext)+
+                            facesContext.getNamingContainerSeparatorChar();
+                    if (submittedValue.startsWith(expectedStart))
+                    {
+                        SelectOneGroupSetSubmittedValueCallback callback = 
+                                new SelectOneGroupSetSubmittedValueCallback(group,
+                                        submittedValue.substring(expectedStart.length()),
+                                        component.getClientId(facesContext),
+                                        component.getValueExpression("value") != null);
+                        formInfo.getForm().visitTree(
+                                VisitContext.createVisitContext(facesContext, null, FIND_SELECT_LIST_HINTS),
callback);
+                        //((EditableValueHolder) component).setSubmittedValue(
+                        //        submittedValue.substring(expectedStart.length()));
+                    }
+                }
+                return;
+            }
+        }
         String clientId = component.getClientId(facesContext);
         if (paramMap.containsKey(clientId))
         {
@@ -269,6 +306,77 @@ public final class HtmlRendererUtils
             ((EditableValueHolder) component).setSubmittedValue(STR_EMPTY);
         }
     }
+    
+    private static final  Set<VisitHint> FIND_SELECT_LIST_HINTS = 
+        Collections.unmodifiableSet(EnumSet.of(VisitHint.SKIP_UNRENDERED));
+    
+    private static class SelectOneGroupSetSubmittedValueCallback implements VisitCallback
+    {
+        private String group;
+        private String submittedValue;
+        private String submittedClientId;
+        private boolean sourceComponentHasValueVE;
+        private boolean submittedValueSet;
+
+        public SelectOneGroupSetSubmittedValueCallback(String group, String submittedValue,
String submittedClientId,
+                boolean sourceComponentHasValueVE)
+        {
+            this.group = group;
+            this.submittedValue = submittedValue;
+            this.submittedClientId = submittedClientId;
+            this.sourceComponentHasValueVE = sourceComponentHasValueVE;
+            this.submittedValueSet = false;
+        }
+
+        @Override
+        public VisitResult visit(VisitContext context, UIComponent target)
+        {
+            if (target instanceof UISelectOne)
+            {
+                UISelectOne component = (UISelectOne) target;
+                String targetGroup = component.getGroup();
+                if (group.equals(targetGroup))
+                {
+                    if (this.sourceComponentHasValueVE)
+                    {
+                        // dataTable case or original case. Set submittedValue on that component
and
+                        // in the others ones of the group empty.
+                        if (submittedClientId.equals(component.getClientId(context.getFacesContext())))
+                        {
+                            component.setSubmittedValue(submittedValue);
+                        }
+                        else
+                        {
+                            component.resetValue();
+                        }
+                    }
+                    else
+                    {
+                        // Find the first component with "value" VE set and set the submitted
value there.
+                        // For all other components set as submitted value empty.
+                        if (!this.submittedValueSet)
+                        {
+                            if (component.getValueExpression("value") != null)
+                            {
+                                component.setSubmittedValue(submittedValue);
+                                this.submittedValueSet = true;
+                            }
+                            else
+                            {
+                                component.resetValue();
+                            }
+                        }
+                        else
+                        {
+                            component.resetValue();
+                        }
+                    }
+                    return VisitResult.REJECT;
+                }
+            }
+            return VisitResult.ACCEPT;
+        }
+    }
 
     /**
      * @since 4.0.0



Mime
View raw message