0 Replies Latest reply on Nov 27, 2008 2:25 PM by Jens Weintraut

    One Component - multiple instances?

    Jens Weintraut Apprentice

      Hi there,


      I've a problem with ICEfaces' selectInputText. It's this funny auto-complete component every user is so keen on. I've a page like this:



      <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>
      
      <s:decorate id="decorate_devUsrID" template="inc/decorateField.xhtml">
        <ice:selectOneMenu value="#{requestToCreate.devUsrID}"
          binding="#{componentBinder}"
          id="devUsrID"
          converter="com.idsscheer.ares.view.converter.UserConverter">
          
          <s:selectItems value="#{mainSupplier.developers}" var="developer" label="#{developer.ID} - #{developer.name}" noSelectionLabel="#{ares_messages.filter_not_specified}" />
        </ice:selectOneMenu>
      </s:decorate>



      If I remember right, it's the way ICEfaces proposes to use this component. At least, it works ;)
      This is the userAutoComplete component:



      @AutoCreate
      @Stateful
      @Scope(ScopeType.SESSION)
      @Name("userAutoComplete")
      public class UserAutoComplete implements IUserAutoComplete, Serializable {
        private static int listLength = 20;
      
        @In
        private IUserSelector userSelector;
      
        @In(required=false)
        private UIComponent componentBinder;
      
        private String enteredUser;
        private List<SelectItem> matches;
      
      
        public void selectInputValueChanged(ValueChangeEvent event) {
          //some code here
          
          if(selectedUser != null) {
            if(componentBinder != null && componentBinder instanceof ValueHolder) {
              ((ValueHolder) componentBinder).setValue(selectedUser);
            }
          }
                       
          //further code
        }
      
        public String getEnteredUser() {
          return enteredUser;
        }
      
        public void setEnteredUser(String enteredUser) {
          this.enteredUser = enteredUser;
        }
      
        public List<SelectItem> getMatches() {
          return matches;
        }
      
        public void setMatches(List<SelectItem> matches) {
          this.matches = matches;
        }
      
        public int getListLength() {
          return listLength;
        }
      
        private List<SelectItem> generateMatches(String enteredUserID) {
          // some code there
        }
      
      
        @Remove @Destroy
        public void destroy() {
        }
      }



      As you can see, this autocomplete field not only makes proposals, it additionally sets another component's value. Here the componentBinder:


      @Name("componentBinder")
      @Scope(ScopeType.EVENT)
      public class ComponentBinder implements Serializable {
        private static final long serialVersionUID = 4459076739298933657L;
        
        private UIComponent boundComponent;
        
        
        @Unwrap
        public UIComponent getBoundComponent() {
          return boundComponent;
        }
        
        public void setBoundComponent(UIComponent boundComponent) {
          this.boundComponent = boundComponent;
        }
      }



      OK. This works fine. But now the user wants to have multiple selectInputTexts on one page. And I'm wondering how I could realize this.


      One option was to use to get rid of the componentBinder and introduce a member for the refered UIComponent. And then add @Role(name="userAutoComplete2") to introduce an additional component. But it seems that @Role doesn't instantiate a further component, it's just a renaming? Is this right? Is there a possibility to have multiple instances of one component?


      I'm pretty sure that this design isn't the best for the requirements. Has anybody implemented something like this before or does anyone have an idea?


      Thanks in advance
      Jens