4 Replies Latest reply on Feb 17, 2009 6:13 AM by abelevich

    HtmlPickList convert submittedValue to Object

    nkr1pt

      Hi,

      I have a HtmlPickList that is bound to a List object called users, and it is filled with selectitems like this programmatically:

      for (User user : userManager.createDummyUsers()) {
       SelectItem item = new SelectItem(user, user.getUsername());
       users.add(item);
       }
      


      the value is the user object, and the label is user.getUsername()

      Also, a converter is registered on the picklist because it only accepts String objects:

      <rich:pickList id="usersPickList" showButtonsLabel="false" rendered="false">
       <f:selectItems value="#{selectUsersModule.users}" />
       <f:converter converterId="UserConverter" />
       </rich:pickList>
      


      The code for the UserConverter looks like this:

      public class UserConverter implements Converter {
      
       @Override
       public Object getAsObject(FacesContext context, UIComponent component, String string) throws ConverterException {
       if (string == null || string.trim().equals("")) {
       return string;
       }
      
       User user = new User();
      
       StringTokenizer hyphenTokenizer = new StringTokenizer(string, "-");
       int hyphenCount = 0;
       while (hyphenTokenizer.hasMoreTokens()) {
       String token = hyphenTokenizer.nextToken();
       if (hyphenCount == 0) {
       user.setUsername(token);
       }
       if (hyphenCount == 1) {
       user.setEmail(token);
       }
      
       hyphenCount++;
       }
      
       return user;
       }
      
       @Override
       public String getAsString(FacesContext context, UIComponent component, Object object) throws ConverterException {
       User user = null;
      
       if (object instanceof User) {
       user = (User)object;
       return user.getUsername() + "-" + user.getEmail();
       }
      
       return "";
       }
      


      basically, the getAsString() method takes the username and email fields from the user object and creates a String from it in the format username-email, while the getAsObject() method does the exact opposite.
      This seems to work fine when debugging.

      Th eproblem is that a have a commandButton on the page whose action is not being called after the getAsObject() method from the converter completes.
      When I leave the converter out of it or when setting immediate=true on the commandButton, the action method is being called just fine.

      But in that case, I'm getting the submiitedValue from the picklist but the conversion didn't happen so it returns the value as a String instead of as a User object.

      FacesContext context = FacesContext.getCurrentInstance();
       UIViewRoot viewRoot = context.getViewRoot();
       UIComponent form = viewRoot.findComponent("form");
       UIComponent selectUsersContainer = form.findComponent("selectUsersModule");
       HtmlPickList pickList = (HtmlPickList)selectUsersContainer.findComponent("usersPickList");
       pickList.setConverter(new UserConverter());
       Object submittedValue = pickList.getSubmittedValue();
      


      Here I would like submittedValue to be of type User instead of String.

      What am I doing wrong?

      Thx

        • 1. Re: HtmlPickList convert submittedValue to Object
          nbelaevski

          Hello,

          If you need value to be converted when using immediate command link, then set immediate="true" for picklist itself. If you want to know why action is not working, please start with adding rich:messages component to the page.

          • 2. Re: HtmlPickList convert submittedValue to Object
            nkr1pt

            thx.

            now when the send action is invoked, the converter is called first, and it converts the String perfectly a User object in the getAsObject() method.
            After that the send action is called, in which the submittedValue is searched, but here the value is still of type String instead of type User:

            FacesContext context = FacesContext.getCurrentInstance();
             UIViewRoot viewRoot = context.getViewRoot();
             UIComponent form = viewRoot.findComponent("form");
             UIComponent selectUsersContainer = form.findComponent("selectUsersModule");
             HtmlPickList pickList = (HtmlPickList)selectUsersContainer.findComponent("usersPickList");
             Object submittedValue = pickList.getSubmittedValue();
            


            submittedValue is type String instead of User.

            Any ideas?

            • 3. Re: HtmlPickList convert submittedValue to Object
              nkr1pt

              when not using the immediate attribute on the commandButton and the HtmlPickList, the converter is called, but afterwards the picklist is completely empty and the following error message is provided:

              form:selectUsersModule:usersPickList: Validation Error: Value is not valid
              


              after some googling it seemed that I needed to override the equals method in the User class, so I provided this one:

              @Override
               public boolean equals(Object o) {
               if (o instanceof User) {
               User user = (User)o;
               if (this.username.equals(user.getUsername()) && this.email.equals(user.getEmail())) {
               return true;
               }
               }
              
               return false;
               }
              


              But the same error keeps occuring

              • 4. Re: HtmlPickList convert submittedValue to Object
                abelevich

                hi,

                After that the send action is called, in which the submittedValue is searched, but here the value is still of type String instead of type User:


                submittedValue is a value which comes from client. It's type is String, if you need converted object use pickList.getValue() instead of pickList.getSubmittedValue() in your code.


                after some googling it seemed that I needed to override the equals method in the User class, so I provided this one:


                Try to overide hashCode method too