voyent
How to use an ice:selectInputText to choose a value of an ice:selectOneMenu  XML
Forum Index -> Components
Author Message
Newlukai

Joined: 29/Nov/2006 00:00:00
Messages: 125
Offline


Hi there,

currently I try to find a way to get an ice:selectInputText to update the value of an ice:selectOneMenu. Why should I do such a thing? Because the user wants to have a comfortable way to select something from the ice:selectOneMenu.

The scenario is as follows: The user has a page to edit an entity or to be more specific, he has a page to edit one entity out of a list of entities. This page allows him to scroll/flick through this list of entities and editing the current one.
One attribute of those entities is represented by an ice:selectOneMenu where the user can choose an entry.
Now I had to add an ice:selectInputText accompanying this ice:selectOneMenu. This ice:selectInputText should set the value of the ice:selectOneMenu according to the user's input. E. g. if he enters "ba" and the first match is "banana", the ice:selectOneMenu should be set to "Banana".

The only way I could imagine to implement such a behaviour was to use a component binding and bind the ice:selectOneMenu to the backing bean of the ice:selectInputText:

Code:
<h:panelGroup>
   <ice:setEventPhase events="ValueChangeEvent" phase="INVOKE_APPLICATION">
     <ice:selectInputText id="devUsrID_AC"
                          rows="#{userAutoComplete.listLength}"
                          value="#{userAutoComplete.enteredUser}"
                          valueChangeListener="#{userAutoComplete.selectInputValueChanged}"
                          listVar="user"
                          listValue="#{userAutoComplete.matches}">
 
       <f:facet name="selectInputText">
         <ice:outputText value="#{user.ID} - #{user.name}"/>
       </f:facet>
     </ice:selectInputText>
   </ice:setEventPhase>
 
   <ice:setEventPhase events="ValueChangeEvent" phase="INVOKE_APPLICATION">
     <ice:selectOneMenu value="#{testaction.devUsrID}" binding="#{userAutoComplete.binding}" id="devUsrID" converter="view.converter.UserConverter" valueChangeListener="#{userAutoComplete.selectInputValueChanged}" partialSubmit="true">
       <s:selectItems value="#{mainSupplier.developers}" var="developer" label="#{developer.ID} - #{developer.name}" id="devUsrIDs" />
     </ice:selectOneMenu>
   </ice:setEventPhase>
 </h:panelGroup>


As you might guess, testaction stands for the current entity and userAutoComplete is the backing bean of the ice:selectInputText. Here is some code of this bean:

Code:
@AutoCreate
 @Stateful
 @Scope(ScopeType.SESSION)
 @Name("userAutoComplete")
 @Role(name = "userAutoComplete2", scope = ScopeType.SESSION)
 public class UserAutoComplete implements IUserAutoComplete, Serializable {
   private static final long serialVersionUID = 5406906545256206754L;
 
   private static int listLength = 20;
 
 
   @In
   private transient IUserSelector userSelector;
 
 
   private transient UIComponent binding;
 
   private String enteredUser;
   private List<SelectItem> matches;
 
 
   public void selectInputValueChanged(ValueChangeEvent event) {
     if (event.getComponent() instanceof SelectInputText) {
       SelectInputText autoComplete = (SelectInputText) event.getComponent();
 
       String newWord = (String) event.getNewValue();
 
       matches = generateMatches(newWord);
 
       User selectedUser = null;
       if (autoComplete.getSelectedItem() != null) {
         selectedUser = findUserMatch(autoComplete.getSelectedItem().getLabel());
       } else {
         selectedUser = findUserMatch(autoComplete.getValue().toString());
       }
 
       if (selectedUser != null && binding instanceof ValueHolder) {
         ((ValueHolder) binding).setValue(selectedUser);
       }
     } else {
       if (!(event.getNewValue() instanceof User)) {
         return;
       }
 
       User newUser = (User) event.getNewValue();
       enteredUser = newUser.getID();
     }
   }
   
   //some more getters/setters and private helper methods
 }


Every time the listener is invoked, whether from the ice:selectInputText or the ice:selectOneMenu, it sets a new value for the respective component. This is done by using the component binding or setting its own attribute.

All of this works fine as long as the user just edits the selected entity without scrolling/flicking to another one. Or with other words: The user enters a "b" in the ice:selectInputText on the first entity, which results in setting "banana" for the ice:selectOneMenu. Then he switches to the next entity which has an attribute of "apple" instead of "banana", the ice:selectInputText and the ice:selectOneMenu have their values still set to "banana". This would be OK and right for the ice:selectInputText. But in case of the ice:selectOneMenu I expect the value set to the attribute of the current displayed entity.
I think this behaviour is a result of the fact that I use value binding and component binding for the ice:selectOneMenu and ICEfaces confuses about the question which one to use. But I don't know a better idea on how to implement such a feature. I use the component binding because this backing bean userAutoComplete is used on more pages and the referenced entity attribute is not the same for every use.

What do you think about this? How could I handle this?

Thanks in advance
Jens
Newlukai

Joined: 29/Nov/2006 00:00:00
Messages: 125
Offline


I debugged into the ICEfaces and JSF API code in order to get a clue on this. I noticed that all ice:selectOneMenus in the form are re-instantiated between the apply request values and the render response phase as soon as the user scrolls through the entities. So they get their value from the current displayed entity.
All except for one. The one with the value and component binding stays the same object during the whole life cycle. Unfortunately I can't find out when and why this re-instantiation should happen but doesn't.

Additionally, I tested an h:inputTextarea with combined value and component binding and there was the same problem.

Is it a general issue with JSF that one can't use value and component binding at the same time or didn't I implement it the right way?

Thanks in advance
Jens
 
Forum Index -> Components
Go to:   
Powered by JForum 2.1.7ice © JForum Team