Tuesday, July 3, 2012

How to use <rich:listShuttle> component














In 'ListShuttle' component you have two lists.
The left hand side list is the Source list.Right hand side list is the Target list. When moving an item between two lists, it is passed as a String. So you have to write a converter class to convert this String again to the object. So in order to do this correctly you may need to override the 'toString' method of the class
which you are using as the list item.

In this example I am using following 'UserData' calss to represent an item in the list. So my source list and
target lists has the type of 'UserData'.
Note that 'toString' method in 'UserData' has been overridden.

public class UserData {
String userName;
Integer userId;
public String getUserName() {
  return userName;
  }
public void setUserName(String userName) {
  this.userName = userName;
  }
public Integer getUserId() {
  return userId;
  }
public void setUserId(Integer userId) {
  this.userId = userId;
  }
  @Override
  public String toString() {
    return this.userId + "," + this.userName;
  }
}


My converter class is as below. It can convert a 'UserData' object to a String and, a String representation of 'UserData' object back to a 'UserData' object.
Following three annotations are must
@Name("userDataConverter") - This indicates the converter Id()
@Converter - This registers this class as a converter
@BypassInterceptors - Disabling interceptors.


import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.faces.Converter;
import org.jboss.seam.annotations.intercept.BypassInterceptors;


@Name("userDataConverter")
@Converter
@BypassInterceptors
public class UserDataConverter implements javax.faces.convert.Converter {


  public Object getAsObject(FacesContext fContext, UIComponent uiComp, String value) {
UserData userData = new UserData();
String[] parts = value.split(",");
userData.setUserId(Integer.valueOf(parts[0]));
userData.setUserName(parts[1]);
return userData;
  }


  public String getAsString(FacesContext fContext, UIComponent uiComp, Object obj) {
UserData userData = (UserData) obj;
return userData.toString();
  }
}

My seam class which is bound to the page is as below.

import java.util.ArrayList;
import java.util.List;
import org.jboss.seam.annotations.Name;


@Name("myBean")
public class MyBean {
List<UserData> sourceData;
List<UserData> targetData = new ArrayList<UserData>();

public MyBean() {
sourceData = new ArrayList<UserData>();
UserData u = new UserData();
u.setUserId(100);
u.setUserName("John");
sourceData.add(u);
UserData u2 = new UserData();
u2.setUserId(101);
u2.setUserName("Kate");
sourceData.add(u2);
}

public List<UserData> getSourceData() {
return sourceData;
}

public List<UserData> getTargetData() {
return targetData;
}
}

Finally the ListShuttle component in my xhtml page is this.

    <rich:listShuttle sourceCaptionLabel="All users" targetCaptionLabel="Selected users"  orderControlsVisible="true"  sourceValue="#{myBean.sourceData}" var="userData" 
   targetValue="#{myBean.targetData}" converter="userDataConverter">
      <rich:column width="60px">
        <f:facet name="header">
          <h:outputText value="Username"/>
        </f:facet>
        <h:outputText style="cursor:pointer;" value="#{userData.userName}" />
      </rich:column>
      <rich:column width="60px">
        <f:facet name="header">
          <h:outputText value="Id" />
        </f:facet>
        <h:outputText style="cursor:pointer;" value="#{userData.userId}" />
      </rich:column>
    </rich:listShuttle>

No comments:

Post a Comment