Time for action – partial processing on the user details form
In this section, we will demonstrate how to process only a subset of components based on the action performed.
- Create
userDetails.xhtml
with the User Details Form containing update and delete actions:<h:form id="userDetailsForm"> <p:panel header="User Details Form" style="width: 800px;"> <p:messages/> <h:panelGrid columns="3"> <p:outputLabel value="UserId:*"/> <p:inputText id="userId" value="#{userController.loginUser.id}" required="true" label="UserId" /> <p:message id="userIdMsg" for="userId"/> <p:outputLabel value="UserName:*"/> <p:inputText id="userName" value="#{userController.loginUser.userName}" required="true" label="UserName" /> <p:message id="userNameMsg" for="userName"/> <p:outputLabel value="Password:*"/> <p:password id="password" value="#{userController.loginUser.password}" required="true" label="Password"/> <p:message id="passwordMsg" for="password"/> <p:outputLabel value="FirstName:*"/> <p:inputText id="firstName" value="#{userController.loginUser.firstName}" required="true" label="FirstName"/> <p:message id="firstNameMsg" for="firstName"/> <p:commandButton value="Update" action="#{userController.updateUser()}" update="userDetailsForm"/> <p:commandButton value="Delete" action="#{userController.deleteUser()}" update="userDetailsForm"/> </h:panelGrid> </p:panel> </h:form>
- Create a managed bean
UserController.java
to perform update and delete actions:@ManagedBean @RequestScoped public class UserController { private User loginUser; public UserController() { this.loginUser = new User(); } public User getLoginUser() { return loginUser; } public void setLoginUser(User loginUser) { this.loginUser = loginUser; } public String updateUser() { System.out.println("Updating User Id: "+this.loginUser.getId()); String msg = "User updated Successfully"; FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg)); return "userDetails.jsf"; } public String deleteUser() { System.out.println("deleting User Id: "+this.loginUser.getId()); String msg = "User deleted Successfully"; FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg)); return "userDetails.jsf"; } }
- Run the application and point your browser to
http://localhost:8080/chapter01/userDetails.jsf
.
When you click on the Delete button, the whole form will be processed, and displays a form with error messages if any required fields are blank. To resolve this issue, we can use the process
attribute to specify only the UserId
field to be processed and invoke the deleteUser()
method:
<p:commandButton value="Delete"action="#{userController.deleteUser()}" process="@this,userId" update="userDetailsForm"/>
What just happened?
We have used the process
attribute to specify which components to be processed so that we can bypass the other fields' validations, which are irrelevant to the invoked action. Also note that <p:commandButton>
issues an AJAX request by default. So if you want to redirect to a different page after action logic is executed make it a non-AJAX request by setting ajax="false"
.
Submitting partial data to the server
Both JSF AJAX implementation and PrimeFaces serializes the whole form data, and post it to server even for AJAX requests that will process only partial components. In the case of forms with more number of input components, we will be sending huge payload even though only few specific components will be processed on server side. This process unnecessarily consumes server resources.
PrimeFaces provides partialSubmit
feature, which enables to serialize and send only the components data that will be processed on server side. By default partialSubmit
feature is disabled, and we can enable this feature globally by configuring the following context parameter in web.xml
:
<context-param> <param-name>primefaces.SUBMIT</param-name> <param-value>partial</param-value> </context-param>
The preceding configuration enables partialSubmit
feature globally. We can override this partialSubmit
behavior for specific command components or AJAX events as follows:
<p:commandButton value="Delete" action="#{userController.deleteUser()}" process="@this,userId" partialSubmit="true" update="userDetailsForm"/> <p:inputText id="userName" value="#{userController.registrationUser.userName}" required="true" label="UserName"> <p:ajax event="keyup" listener="#{userController.checkUserNamesExists()}" update="userNameMsg" partialSubmit="true"/> </p:inputText>
You can see the difference between payload data sending to server when partialSubmit
is enabled and disabled using firebug or chrome developer tools.