Why after selecting an item in this code, the cities component does not get rendered?
<h:form prependId="false">
<h:panelGrid columns="1">
<h:selectOneMenu value="#{enumBeanStatus.selectedRegion}">
<f:selectItems id="selectItem" value="#{enumBean.regions}" var="region" itemLabel="#{region.label}"/>
<f:ajax listener="#{enumBean.loadCities}" render="cities"/>
</h:selectOneMenu>
<h:outputText id="cities" value="#{enumBean.cities}"/>
</h:panelGrid>
</h:form>
It does send a POST with the selected Region, model gets updated correctly, but the <h:outputText> Component is not rendered.
One of the backing beans:
#Named
public class EnumBean {
private List<Region> regions;
private List<City> cities;
#Inject
EnumBeanStatus enumBeanStatus; //This one is CDI #ApplicationScoped & #Named
// Code...
public void loadCities(){
setCities(City.getCitiesByRegion(enumBeanStatus.getSelectedRegion()));
}
// Getters and Setters
}
Remove prependId="false" from the <h:form>. It prevents <f:ajax> from resolving the right component based on a relative client ID.
See also:
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
UIForm with prependId="false" breaks <f:ajax render>
Related
I'm using PrimeFaces' p:fieldset component and I want to control, from my bean, either or not it's collapsed. I expected the collpased property to do this job, but this is not working.
On the other hand, a "binding" seems to correctly mirror the component's state:
My Bean
#Named
#RequestScoped
public class TestBean {
//with get/set
private boolean collapsed;
//with get/set
private Fieldset fieldset;
}
My page:
<h:form>
<p:fieldset
id="togglebleFieldset"
legend="Toggleable Fieldset"
toggleable="true"
binding="#{testBean.fieldset}"
collapsed="#{testBean.collapsed}">
fieldset content
<p:ajax event="toggle" update="#form"/>
</p:fieldset>
<h:outputText value="Value is never updated: #{testBean.collapsed}" />
<br/><h:outputText value="Binding correctly reflects the state: #{testBean.fieldset.collapsed}" />
</h:form>
For reasons beyond the scope of this question, using the binding solution will be a little bit more complicated to me.
Why isn't #{testBean.collapsed} being update with the component's collapsed value?
(Using versions 6.0 and 6.2 of PrimeFaces)
I don't know if there's a solved question for that. If so, I wasn't able to find it.
I'm creating a composite component with two SelectOneMenu that fires an event.
The thing is that this component works in one jsf but doesn't in others.
The component is inside three different xhtml. In all of them the event is fired when I change the value of the first SelectOneMenu, but only in one of the xhtml the value of the SelectItem is not null. In the rest of them, the retrieved value is "null"
//In p001DatosNotificacion.xhtml, it retrieves the selected value of the selectonemenu (b, for example)
//In the others it retrieves null
UISelectOne oneVoewl = (UISelectOne)event.getSource();
System.out.println("One Voewl > " + oneVoewl.getValue());
Can anyone help me and tell me where I'm making the mistake(s)?
Thanks in advance!
The code
Component backing bean
#FacesComponent(value="letterExample")
public class LetterExample extends UINamingContainer{
public void voewlAjaxListener(AjaxBehaviorEvent event){
UISelectOne oneVoewl = (UISelectOne)event.getSource();
System.out.println("One Voewl > " + oneVoewl.getValue());
}
Composite component (Note: I'm using an existing bean for testing)
<cc:interface componentType="letterExample" >
<cc:attribute name="bean" type="es.ccasa.sgnx.business.bean.Direccion" />
</cc:interface>
<cc:implementation>
<p:selectOneMenu id="oneMenuVoewl" value="#{cc.attrs.bean.codigoPais}"
binding="#{cc.uiSelectOneVoewl}" >
<f:selectItem itemLabel="Aaaa" itemValue="a" />
<f:selectItem itemLabel="Eeee" itemValue="e" />
<f:selectItem itemLabel="Iiii" itemValue="i" />
<f:selectItem itemLabel="Oooo" itemValue="o" />
<f:selectItem itemLabel="Uuuu" itemValue="u" />
<p:ajax event="change" listener="#{cc.voewlAjaxListener}" update="consonantWrapper" />
</p:selectOneMenu>
<h:panelGroup id="consonantWrapper" layout="block">
<p:selectOneMenu id="oneMenuConsonant" value="#{cc.attrs.bean.codigoProvincia}"
binding="#{cc.uiSelectOneConsonant}">
<f:selectItem itemLabel="Bbbb" itemValue="b" />
<f:selectItem itemLabel="Cccc" itemValue="c" />
<f:selectItem itemLabel="Dddd" itemValue="d" />
</p:selectOneMenu>
</h:panelGroup>
</cc:implementation>
Bean
public class Direccion implements Serializable {
private String codigoPais; /* with its getter and setter*/
private String codigoProvincia; /* with its getter and setter*/
}
XHTML
This is the way I use inside the xhtml pages: (The name of the controller changes depends on the current controller)
<sgnx:letter-example bean="#{controller.direccion}" />
The #Named beans
#Named
#ViewScoped
public class P001DatosNotificacionController
private Direccion direccion; /* with its getter and setter*/
#Named
#ViewScoped
public class P001GestionNotificacionesController
private Direccion direccion; /* with its getter and setter*/
#Named
#ViewScoped
public class P002BandejaProvisionalNotificacionesController
private Direccion direccion; /* with its getter and setter*/
After a few weeks I went back to the problem.
I decided to start again from scratch.
When I started to write the controller code and annotated it with #ViewScoped I realize about javax.faces.bean and javax.faces.view packages
And that was the mistake. I was using a wrong combination:
import javax.inject.Named;
import javax.faces.bean.ViewScoped;
So, the solution is as easy as using the proper combination of packages:
import javax.inject.Named;
import javax.faces.view.ViewScoped;
In these posts are the answer and the explanation:
#ViewScoped bean recreated on every postback request when using JSF 2.2
ManagedProperty in CDI #Named bean returns null
Inject CDI bean into JSF #ViewScoped bean
i have a problem with my primefaces datatable, rows are empty.
<h:body>
<ui:composition template="../shared/commonLayout.xhtml">
<ui:define name="content">
<h:form>
<p:dataTable id="users" var="user" value="#{UserManagedBean.userList}" style="width: 40%">
<p:column>
<f:facet name="header">
<h:outputText value="FirstName" />
</f:facet>
<h:outputText value="#{user.firstname}" />
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
</h:body>
#ManagedBean(name = "UserManagedBean")
#SessionScoped
public class UserManagedBean {
//..
/**
* Get Users List.
*
* #return List - User List
*/
public final List<User> getUserList() {
userList = new ArrayList<User>();
userList.addAll(getUserService().getItems());
return userList;
}
}
i'm using spring, hibernate, jsf managed beans.
can somebody help me please?
The code you have posted should work if:
getUserList() returns some rows, filled with some data
User class has a field firstname with getter and setter (note the case, n is lowercase in your column)
That firstname field is populated (not empty)
Can you verify the above?
A few things to correct in your code:
Don't do business logic in the getter; move that code into a #PostConstruct
Don't back a page with a #SessionScoped bean; it's a design-smell and almost never ends well. Use the #RequestScoped or #ViewScoped instead.
Everything outside a <ui:composition/> is ignored by the facelets engine. What that means is that all the tags you've defined outside it will have no effect (the <h:body/>) for example
Related Reading:
Why JSF calls getters multiple times
Request parameter is null during postback
I am seeing different behaviors of and in a page containing multiple forms.
Here is my backing bean:
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class MultiFormBean
{
String inputText1 = "";
String inputText2 = "";
#PostConstruct
public void initializeBean(){
System.out.println("PostConstruct Called ------------------");
}
public String getInputText1()
{
return inputText1;
}
public void setInputText1(String inputText1)
{
this.inputText1 = inputText1;
}
public String getInputText2()
{
return inputText2;
}
public void setInputText2(String inputText2)
{
this.inputText2 = inputText2;
}
public void doSubmit1() {
inputText2 = inputText1;
}
public void doSubmit2() {
inputText1 = inputText2;
}
}
When i use the following xhtml , clicking Submit1 and Submit2 any number of times won't call #PostConstruct more than once:
<h:body>
<h:form id="firstForm" prependId="false">
<h:panelGroup layout="block" id="renderTarget1"/>
<h:inputText id="first_input" value="#{multiFormBean.inputText1}"/>
<h:commandButton id="click1" action="#{multiFormBean.doSubmit1}" value="submit1" type="submit"
onclick="javascript:jsf.ajax.request(this, event, {execute:'firstForm', render:'renderTarget1 secondForm'}); return false;">
</h:commandButton>
</h:form>
<h:form id="secondForm" prependId="false">
<h:panelGroup layout="block" id="renderTarget2"/>
<h:inputText id="second_input" value="#{multiFormBean.inputText2}"/>
<h:commandButton id="click2" action="#{multiFormBean.doSubmit2}" value="submit2" type="submit"
onclick="javascript:jsf.ajax.request(this, event, {execute:'secondForm', render:'renderTarget2 firstForm'}); return false;">
</h:commandButton>
</h:form>
</h:body>
But the following xhtml would call #PostConstruct more than once:
<h:body>
<h:form id="firstForm" prependId="false">
<h:panelGroup layout="block" id="renderTarget1"/>
<h:inputText id="first_input" value="#{multiFormBean.inputText1}"/>
<a4j:commandButton id="click1" action="#{multiFormBean.doSubmit1}" value="submit1" type="submit" execute="#form" render="renderTarget1,secondForm"/>
</h:form>
<h:form id="secondForm" prependId="false">
<h:panelGroup layout="block" id="renderTarget2"/>
<h:inputText id="second_input" value="#{multiFormBean.inputText2}"/>
<a4j:commandButton id="click2" action="#{multiFormBean.doSubmit2}" value="submit2" type="submit" execute="#form" render="renderTarget2,firstForm"/>
</h:form>
</h:body>
Please can anyone help me use the <a4j:commandButton> instead of <h:commandButton>
Also i see that i cannot call the method doSubmit2() with a4j commandButton
I think that problem here is in bug inside JSF2 and Richfaces4. From 4 version Richfaces started using JSF embedded ajax capabilities. And There is a bug with using multiple forms on page with ajax requests. The problem there that richfaces renders special hidden input with the id of currently rendered view state. This id is changed when new view is rendered. And it is also submitted with every request to show that it belongs to some specific view. So when you have multiple forms on the same page after first ajax request the view state is getting the wrong place and it can be not submitted again second time. Sometimes behavior looks like very very wierd with no logical description.
PostConstruct is called twice because server thinks that two requests belong to different views(view state is not sumbitted) and as far as bean is view scoped it is created twice. After clicking aroung ajax can completelly stop working with this because server woukd not recognize the view(probably what you see when you can not click second submit button).
In the first place I recommend you to use latest available version of JSF and Richfaces. This bug (and many more) may be already fixed there.
I have a JSF composite component which includes as a root an h:form. The form has many components among of which are selectOneMenu and a h:inputFile. When I set enctype="multipart/form-data" on the form, the valuechangelistener of the selectOneMenu is invoked ONLY for two value-changing events. Later, however I interact with the menu, the value change listener is not invoked at all. However, if I remove the enctype="multipart/form-data" every thing works fine. I have to keep enctype="multipart/form-data" because I have a file upload component.
Here is my Bean :
#Model
#ViewScoped
public class TransactionBean implements Serializable {
private Part inReceiptFilePart;
/*setter and getter*/
private TransactionType transactionType;
/*setter and getter*/
private final TransactionType transTypeList[] = {
TransactionType.COMPLETE,TransactionType.TECHNICAL,TransactionType.SUBMUNICIPALITY_TECHNICAL, TransactionType.COMPLAINT, TransactionType.FOLLOWUP_COUNCIL, TransactionType.FOLLOWUP_MANAGEMENT
};
public TransactionType[] getTransTypeList() {
return transTypeList;
}
public void transactionTypeChanged(ValueChangeEvent event) {
... /// some code
}
}
And here is the JSF composite component :
<h:form id="entryForm" enctype="multipart/form-data">
<p:selectOneMenu id="transType" value="#{transactionBean.transactionType}" style="direction: ltr" valueChangeListener="#{transactionBean.transactionTypeChanged}">
<f:ajax execute="transType" render="#form" > </f:ajax>
<f:selectItems value="#{transactionBean.transTypeList}" var="tt" itemLabel="#{tt.arName}">
</f:selectItems>
</p:selectOneMenu>
<h:inputFile value="#{transactionBean.inReceiptFilePart}" > </h:inputFile>
<p:commandButton id="insertTrans" value="أدخل المعاملة" action="#{transactionBean.insertTransaction}" ajax="false">
</p:commandButton>
</h:form>
The environment is JSF 2.2, Glassfish 4.0 and primefaces 3.5.
Please help me. I am stuck for three days on this problem.
Thanks
This is very strange behavior!
Try changing valueChangeListener event to an AJAX call.
<p:selectOneMenu id="transType" value="#{transactionBean.transactionType}" style="direction: ltr" >
<p:ajax event="change" partialSubmit="true" update="#form" listener="#{transactionBean.transactionTypeChanged}"/>
<f:selectItems value="#{transactionBean.transTypeList}" var="tt" itemLabel="#{tt.arName}" />
</p:selectOneMenu>
Primefaces's AJAX component is behavior component that extends JSF AJAX.
It adds and manages new events (e.g. valueChange); it also reattach javascript events to DOM element automatically.
Your case is that jsf's ajax does not rebind the valueChange Listener to "transType" selectOneMenu when the form is mutipart! (It's very strange, because the behavior should be the same of those ajax event, weather the form is mutipart or www-form-encoded!