Francisco, I have found that there is a fundamental problem with how UINamingContainers are processed when row indexes are inserted into the ids of EditableValueHolders within the container rows.
Understanding The Problem: As you may already know, tables have only columns referenced in the page so it can handle an almost infinite number of rows. Well, because you have only specified an id for a component within the table column the component inserts a row index reference in the holders id (via getClientRowKey() in a table) for each row. This ensures that each iteration of that row has a unique id. The problem with this is that in some cases this breaks automatic setting of bean values (if they are value bound to an EditableValueHolder within a row). Another issue is that "selectOneChoice" components in particular do not have a mechanism in place to ensure that a submitted value that gets set on the component is one of the values within the internal "SelectItemList" so virtually any value can get set on it. If the submitted value is not in the list it adds a blank entry in the drop down menu- what? I have also noticed that selectOneChoice component does not handle value conversion like regular input text components do. Semi-primitive values such as Integers, Booleans, etc. are not converted automatically like they are for regular input text components. I had some of the same issues with the "detailStamp" so I created an extended table component that allows only one toggled "detailStamp" at a time and overrides the "getClientRowKey()" excluding row indexes for components within the "detailStamp". This solution works very well, but still does not address EditableValueHolders within the rows themselves. It seems to me that we need to reevaluate the usage of inserting row indexes into ids! Possible Solutions: The first thing I would check is that you have the valuePassThru="true" to ensure that its not trying to use the index as the passed value (not sure why anyone would want to be restricted to just an index). If want to ensure that your value is never set to a value that does not exist in the options you can use a value change listener: /** * Verifies that an editable value holder event components value is a valid * option. If it is not it sets it back to the old value. * * @see #getEditableValueHolderValue(EditableValueHolder) * @param event */ public final void verifyValueOption(ValueChangeEvent event) { try { if (event.getComponent() instanceof EditableValueHolder) { EditableValueHolder valueHolder = (EditableValueHolder) event .getComponent(); if (!isValidSelectOption(event.getComponent(), event.getNewValue())) { // invalid option- regress to old value valueHolder.setValue(event.getOldValue()); valueHolder.setSubmittedValue(event.getOldValue()); } } } catch (Throwable e) { log.warn("Unable to verify select value. " + e.getMessage() + " cause: " + e.getCause()); } } /** * Determines if the specified value is a valid selection option in the * specified select component. * * @param component * @param value * @return is the specified value a valid select option */ public static final boolean isValidSelectOption(UIComponent component, Object value) { try { List<SelectItem> items = SelectItemSupport.getSelectItems( component, SelectItemSupport.getConverter(component)); for (SelectItem item : items) { if (item.getValue() != null && item.getValue().equals(value)) { return true; } } } catch (Exception e) { _LOG.warning("Unable to determine if the specified value: " + value + " is valid for the select component: " + component); } return false; } Probably not the most elegant solution, but nonetheless an effective one is to manage the submitted row index problems yourself. If nothing else this will provide you with a debugging tool to determine if the row index references are preventing your values from getting set: /** * <p> * Gets a parameter value from the request scope by an editale value holder * components id. This method will set/return the holders submitted value * from the request. * </p> * <p> * The holders client id is checked against a possible matching id request * parameter. The client id of the holder and the request parameter matching * the hodler id may have their own row indexing (such is the case with a * select menu). * <ol> * <li>The client id against the request parameter</li> * <li>The client id w/o row index against the request parameter</li> * <li>The client id against the request parameter w/o row index</li> * </ol> * </p> * * @param context * @param holder * @return the parameter value */ @SuppressWarnings("unchecked") public static final Object getRequestParameterByHolderId( FacesContext context, EditableValueHolder holder) { if (log.isDebugEnabled()) log.debug("getRequestParameterForNamingContainer(" + context + ',' + holder + ")"); if (holder != null && holder instanceof UIComponent) { String clientId = ((UIComponent) holder).getClientId(context); String clientIdWithOutRowIds = removeRowIdReferences(clientId); String id = ((UIComponent) holder).getId(); Map<String, Object> map = context.getExternalContext() .getRequestParameterMap(); if (map != null && map.entrySet() != null) { for (Map.Entry<String, Object> entry : map.entrySet()) { if (entry.getKey().indexOf(id) >= 0) { if (entry.getKey().equalsIgnoreCase(clientId) || entry.getKey().equalsIgnoreCase( clientIdWithOutRowIds) || removeRowIdReferences( entry.getKey()).equalsIgnoreCase( clientId)) { try { setConvertedAndValidatedValue(context, holder, entry.getValue()); } catch (Exception e) { log.error("Unable to capture the converted " + "value for component(" + holder + ") value: " + entry.getValue(), e); } return holder.getSubmittedValue(); } } } } } return null; } /** * Removes any row id references that may exist within the specified client * id * * @param clientId * @return the client id */ public static final String removeRowIdReferences(String clientId) { if (log.isDebugEnabled()) log.debug("removeRowIdReferences(" + clientId + ')'); if (clientId != null) { String[] ids = clientId.split(String .valueOf(NamingContainer.SEPARATOR_CHAR)); for (String id : ids) { try { Integer.parseInt(id); } catch (Exception e) { continue; } clientId = clientId.replace(NamingContainer.SEPARATOR_CHAR + id + NamingContainer.SEPARATOR_CHAR, String .valueOf(NamingContainer.SEPARATOR_CHAR)); } } return clientId; } /** * Invokes the internal converter/validators(s) for an editable value holder * and returns the converted value * * @param context * @param holder * @param value * @return the converted value * @throws ValidatorException * @throws EvaluationException * @throws MethodNotFoundException */ public static final Object setConvertedAndValidatedValue(FacesContext context, EditableValueHolder holder, Object value) throws ValidatorException, EvaluationException, MethodNotFoundException { if (holder != null) { if (holder.getConverter() != null) { value = holder.getConverter().getAsObject(context, (UIComponent) holder, value != null ? value.toString() : null); } if (holder instanceof UIComponent) { if (holder.getValidators() != null) { for (Validator v : holder.getValidators()) { v.validate(context, (UIComponent) holder, value); } } } if (holder.getValidator() != null) { holder.getValidator().invoke(context, new Object[] { value }); } holder.setSubmittedValue(value); return value; } return null; } -----Original Message----- From: Francisco Passos [mailto:[EMAIL PROTECTED] Sent: Monday, April 09, 2007 11:17 AM To: William Hoover Subject: RE: Keeping selectOneChoice selection No, it is in a facet for a panelPage. In it, I have a panelGroupLayout, then a panelHorizontalLayout and finally in it the panelPage. If you feel it's best, I can attach the code or paste it in the mail body. Either way, if the selectOneChoice were in a table (something I will surely need), what would the solution be? Thank you, Francisco > Francisco, > > Is your selectOneChoice in a table? > > -----Original Message----- > From: Francisco Passos [mailto:[EMAIL PROTECTED] > Sent: Monday, April 09, 2007 10:55 AM > To: adffaces-user@incubator.apache.org > Subject: Keeping selectOneChoice selection > > > Hello there. > > I'm new to JSF and Trinidad, so please bear with my simplistic doubts. > > I'm struggling to keep a selectOneChoice selection upon a postback using a > request-scoped bean. > > At first I couldn't even maintain the values in the list, but I found that > placing a h:inputHidden on the page and declaring its value to be > #{myBean.valueList}, they could be kept. Furthermore I've tested the seme > using pageFlow and it worked. > > However, I cannot keep the selected value in the dropdown list, it just > resets. > > What is the correct way to do this simple task without using session > beans? > > Thank you for your time and attention, > > Francisco Passos > > > Francisco Passos Opensoft - Soluções Informáticas, Lda Telemóvel: +351 91 238 52 76 Escritório: +351 21 380 44 10 Email: [EMAIL PROTECTED]