Wednesday, June 30, 2010

RichFaces StateManager API



JSF has an advanced navigation mechanism that lets you define navigation from view to view. In a web application, navigation occurs when a user changes from one page to another by clicking on a button, a hyperlink, or another command component. There is no switch mechanism between some logical states of the same view. For example, inLogin/Register dialog, an existing user signs in with his user name and password, but if a new user attempts to register, an additional field (Confirm) is displayed, and button labels and methods are changed when the user clicks the To register link:

RichFaces State API lets you easily define a set of states for pages, and properties for these states.

The States class interfaces with a map, where the keySet defines the State name and the entrySet is a Statemap. The State map defines the properties, method bindings, or constant state variables of a key or object, where these values may change depending on the active State.


One of the most convenient features of the RichFaces State API is the ability to navigate between States. The API implements changes in State through standard JSF navigation. When the action component returns an outcome, the JSF navigation handler (extended through the RichFaces State API) checks whether the outcome is registered as aState change outcome. If true, the corresponding State is activated. If false, standard navigation handling is called.

Implement the RichFaces State API like so:

Register the State Navigation Handler and the EL Resolver in your faces-config.xml file:

org.richfaces.ui.application.StateNavigationHandler

org.richfaces.el.StateELResolver

Register an additional application factory in the faces-config.xml:

org.richfaces.ui.application.StateApplicationFactory

Register two managed beans in the faces-config.xml:

state

org.richfaces.ui.model.States

request

states

org.richfaces.ui.model.States

#{config.states}

config

org.richfaces.demo.stateApi.Config

none

One bean (config) defines and stores State as seen in the following example:

public class Config {

/**

* @return States

*/

public States getStates() {

FacesContext facesContext = FacesContext.getCurrentInstance();

States states = new States();

// Registering new User State definition

states.setCurrentState("register"); // Name of the new state

// Text labels, properties and Labels for controls in "register" state

states.put("showConfirm", Boolean.TRUE); // confirm field rendering

states.put("link", "(To login)"); // Switch State link label

states.put("okBtn", "Register"); // Login/Register button label

states.put("stateTitle", "Register New User"); // Panel title

ExpressionFactory expressionFactory = facesContext.getApplication()

.getExpressionFactory();

// Define "registerbean" available under "bean" EL binding on the page

ValueExpression beanExpression = expressionFactory

.createValueExpression(facesContext.getELContext(),

"#{registerbean}", Bean.class);

states.put("bean", beanExpression);

// Define "registeraction" available under "action" EL binding on the

// page

beanExpression = expressionFactory.createValueExpression(facesContext .getELContext(), "#{registeraction}", RegisterAction.class);

states.put("action", beanExpression);

// Define method expression inside registeraction binding for this state

MethodExpression methodExpression = expressionFactory.createMethodExpression(

facesContext.getELContext(), "#{registeraction.ok}",

String.class, new Class[] {});

states.put("ok", methodExpression);

// Outcome for switching to login state definition states.setNavigation("switch", "login");

// Login Existent User State analogous definition

states.setCurrentState("login");

states.put("showConfirm", Boolean.FALSE);

states.put("link", "(To register)");

states.put("okBtn", "Login");

states.put("stateTitle", "Login Existing User");

beanExpression = expressionFactory.createValueExpression(facesContext

.getELContext(), "#{loginbean}", Bean.class);

states.put("bean", beanExpression);

beanExpression = expressionFactory.createValueExpression(facesContext

.getELContext(), "#{loginaction}", LoginAction.class);

states.put("action", beanExpression);

methodExpression = expressionFactory.createMethodExpression(

facesContext.getELContext(), "#{loginaction.ok}",

String.class, new Class[] {});

states.put("ok", methodExpression);

states.setNavigation("switch", "register");

return states;

}

}

The second bean, with the org.richfaces.ui.model.States type (state), contains the managed propertystates, which is bound to the first config bean.

Next, use state bindings on the page, as in the following example:

Code for the JSP Page is:

No comments:

Post a Comment