Reputation: 31
I'm new to JSF, Primefaces and Ajax, so what i'm trying to do is update one panel if a validation on my back bean is true and update another panel when it's false.
<h:panelGroup id="panel1">
...
<h:commandButton id="btn1" action="#{bean.validate}">
<p:ajax process="panel1" update="panel1"/>
</h:commandButton>
</h:panelGroup>
<h:panelGroup id="panel2">
...
</h:panelGroup>
Back Bean:
public void validate() {
...
if(validatecondition) {
// Update panel 1
} else {
// update panel 2
}
}
So is it possible to do this using ajax? Thanks in advance!!
Upvotes: 3
Views: 23663
Reputation: 20691
Sure, two ways. Since you're using primefaces, the easier of two options would be
Use the RequestContext object to update the panels selectively. Your code will look like this:
public void validate() {
RequestContext context = RequestContext.getCurrentInstance();
if(validatecondition) {
context.update("panel1");
} else {
context.update("panel2");
}
}
JSF PartialViewContext
can do the same job, with just a little more typing
FacesContext ctxt = FacesContext.getCurrentInstance(); //get your hands on the current request context
if(validatecondition) {
ctxt.getPartialViewContext().getRenderIds().add("panel1");
} else {
ctxt.getPartialViewContext().getRenderIds().add("panel2");
}
The getRenderIds()
call returns a list of component Ids that JSF will update via ajax on completion of the response. This is basically what RequestContext
in primefaces will do under the hood.
Upvotes: 8
Reputation: 436
JSF page code will be following in the backing bean the contents in a input will check and enable the correct panel accordingly. enter 1 in the input will activate panel 1, enter 2 for panel 2 and leave blank for both panels.
JSF is an excellent specification for enterprise application development it provides greater flexibility and separation of concern. Where you need to leave the user interface elements away from your business logic components. My solution is adheres to that principal by not referencing to UI element ids in the backing bean.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
Hello from Facelets
<h:form id="frm" >
<h:commandButton value="click me" action="#{test2.aa()}">
<f:ajax execute="@form" render=":mainpanel" ></f:ajax>
</h:commandButton>
<h:inputText id="intest" value="#{test2.selection}"></h:inputText>
</h:form>
<h:panelGroup id="mainpanel">
<h:panelGroup id="panel1" rendered="#{test2.prop1=='v'}">panel1
<h:outputLabel id="lbl1" value="#{test2.prop1}" ></h:outputLabel>
</h:panelGroup>
<h:panelGroup id="panel2" rendered="#{test2.prop2=='v'}">panel2
<h:outputLabel id="lbl2" value="#{test2.prop2}"></h:outputLabel>
</h:panelGroup>
</h:panelGroup>
</h:body>
</html>
Backing bean code simple as possible I have used session scope also possible in request scope.
package test;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
@Named(value = "test2")
@SessionScoped
public class test2 implements Serializable {
String prop1;
String prop2;
String selection;
public String getProp1() {
return prop1;
}
public void setProp1(String prop1) {
this.prop1 = prop1;
}
public String getProp2() {
return prop2;
}
public void setProp2(String prop2) {
this.prop2 = prop2;
}
public test2() {
prop1 = "v";
prop2 = "v";
selection = "";
}
public String getSelection() {
return selection;
}
public void setSelection(String selection) {
this.selection = selection;
}
public String aa() {
if ("".equals(selection)) {
prop1 = "v";
prop2 = "v";
return "";
} else if ("1".equals(selection)) {
prop1 = "v";
prop2 = "h";
return "";
} else if ("2".equals(selection)) {
prop1 = "h";
prop2 = "v";
return "";
}
return "";
}
}
Upvotes: 0
Reputation: 14277
This is possible, and it is also easy if you are using PrimeFaces. But first I suggest you to make your button little more "primefaces like". Reorganize it to something like this:
<p:commandButton id="btn1" action="#{bean.validate}" process="panel1"/>
PrimeFaces button is AJAX enabled by default, so there is no need for additional tags. Remove update attribute (as we will do that in backing bean).
Now, your method in backing bean:
public void validate() {
// ...
if(validatecondition) {
RequestContext.getCurrentInstance().update("panel1");
} else {
RequestContext.getCurrentInstance().update("panel2");
}
}
RequestContext
is one very useful class which you can use to update, reset fields or to execute some JavaScript after AJAX requests. In this example it is used just to conditionally update panel1 or panel2.
Upvotes: 4