You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2017/05/04 22:16:56 UTC
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/
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