This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 6 years ago.
I'm new to JSF and Primefaces and wanted to know what the best solution is to render a component according to radio selection (hiding and showing again)? I posted my ManagedBean and my JSF-Page-Excerpt. Thanks in advance.
My JSF-Page:
<p:dialog widgetVar="komponentErstellenDialogWV" modal="true"
id="komponentErstellenDialog" header="Komponente erstellen">
<h:form>
<p:wizard flowListener="#{userWizard.onFlowProcess}">
<p:tab id="produktAuswahlTab" title="Produkt auswählen">
<p:panel>
<h:panelGrid columns="2" columnClasses="label, value">
<h:outputText value="Produkt:" />
<p:selectOneRadio id="produktAERadio"
value="#{komponenteErstellenWizardController.produktAuswahl}">
<f:selectItem itemValue="1" itemLabel="Neu erstellen" />
<f:selectItem itemValue="2" itemLabel="Aus Liste auswählen" />
<p:ajax event="click" update="produktSelect" />
</p:selectOneRadio>
<p:selectOneMenu id="produktSelect"
rendered="#{komponenteErstellenWizardController.shouldRenderProduktSelect()}"
value="#{komponenteErstellenWizardController.komponente.produkt}">
<f:selectItems
value="#{komponenteErstellenWizardController.findAllProdukt()}"
var="currentProdukt"
itemLabel="#{currentProdukt.hersteller.concat(' ').concat(currentProdukt.name)}"
itemValue="#{currentProdukt.id}" />
</p:selectOneMenu>
</h:panelGrid>
</p:panel>
</p:tab>
</p:wizard>
</h:form>
</p:dialog>
My ManagedBean:
#ManagedBean
#SessionScoped
public class KomponenteErstellenWizardController implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
// Properties
private Komponente komponente = new Komponente();
private String produktAuswahl;
#PostConstruct
public void init() {
produktAuswahl = "1";
}
public String getProduktAuswahl() {
System.out.println("GetProduktAuswahl invoked with returning value: " + produktAuswahl);
return produktAuswahl;
}
public void setProduktAuswahl(String produktAuswahl) {
System.out.println("SetProduktAuswahl invoked with Value: " + produktAuswahl);
this.produktAuswahl = produktAuswahl;
}
public Komponente getKomponente() {
return komponente;
}
public void setKomponente(Komponente komponente) {
this.komponente = komponente;
}
// EJBs
#EJB
KomponenteFacade komponenteFacade;
#EJB
ProduktFacade produktFacade;
#EJB
ProduktArtFacade produktArtFacade;
public List<Produkt> findAllProdukt() {
return produktFacade.findAll();
}
public Boolean shouldRenderProduktSelect() {
System.out.println("Wizard Produktauswahl: " + produktAuswahl);
return "2".equals(produktAuswahl);
}
}
I updated my code according to suggestions:
Replaced faces components by primefaces components
Added a new action method "shouldRenderProduktSelect"
Still not working...
Few things..
1) Add this method to your controller:
public boolean shouldRenderSelect(){
return "2".equals(produktAuswahl);
}
2) Change the rendered attribute:
<h:selectOneMenu id="produktSelect"
rendered="#{komponenteErstellenWizardController.shouldRenderSelect()}"
3) update your html:
<p:selectOneRadio id="produktAERadio"
value="#{komponenteErstellenWizardController.produktAuswahl}">
<f:selectItem itemValue="1" itemLabel="Neu erstellen" />
<f:selectItem itemValue="2" itemLabel="Aus Liste auswählen" />
<p:ajax event="click" update="panelSelect" />
</p:selectOneRadio>
<h:panelGroup id="panelSelect">
<p:selectOneMenu id="produktSelect"
rendered="#{komponenteErstellenWizardController.shouldRenderProduktSelect()}"
...
</p:selectOneMenu>
</h:panelGroup>
The key is to wrap the selectOneMenu within and from ajax update the panelGroup, not the menu.
Related
I want to call Java method from Primefaces dialog. I tested this code:
<h:form>
<p:dialog header="New Sensor" widgetVar="dlg" focus="name" modal="true" showEffect="fade">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="name" value="Name" />
........
<p:inputText id="enabled" label="enabled" value="#{newSensor.sensor.enabled}" />
</h:panelGrid>
<f:facet name="footer">
<p:commandButton id="ajax" value="Create Sensor" styleClass="ui-priority-primary" type="button" actionListener="#{newSensor.saveRecord()}"/>
</f:facet>
</p:dialog>
</h:form>
Java bean:
#Named
#RequestScoped
public class NewSensor implements Serializable
{
private SensorObj sensor = new SensorObj();
public SensorObj getSensor()
{
return sensor;
}
public void setSensor(SensorObj sensor)
{
this.sensor = sensor;
}
public void saveRecord(){
System.out.println(">>>>>>>!!!!!! " + sensor.getName());
}
}
Wehn I click the button nothing happens. Can you give some advice how I can fix this issue?
You should remove type="button" in your commandButton because it will prevent the button from sending a request.
Additionally, you are using actionListener in your commandButton.
Your method in the bean should have ActionEvent as its parameter.
public void saveRecord(ActionEvent actionEvent) {
System.out.println(">>>>>>>!!!!!! " + sensor.getName());
}
Please refer here for additional information.
I have a simple form, with some input and a selectonemenu:
<h:panelGroup id="Client">
<h:form id="formClient">
<p:panelGrid columns="3" layout="grid"
columnClasses="labelWidth, ui-grid-col-3">
<p:outputLabel value="CIN:" for="txtCin" />
<h:panelGrid columns="2">
<p:inputText value="#{clientBean.client.identifiant}" id="txtCin"></p:inputText>
<p:commandButton value="Search" process="#parent"
styleClass="orangeButton" update="formClient"
style="margin-top: -10px;" action="#{clientBean.rechercher()}"></p:commandButton>
</h:panelGrid>
<p:message for="txtCin" />
<p:outputLabel value="Nom:" for="txtNom" />
<p:inputText id="txtNom" styleClass="form-control"
value="#{clientBean.client.nomClient}" required="true"
requiredMessage="Le nom est obligatoire" />
<p:message for="txtNom" />
<p:outputLabel value="Type de voie:" for="txtVoie" />
<p:selectOneMenu styleClass="form-control"
value="#{clientBean.client.typeVoie}" id="txtVoie">
<f:selectItem itemLabel="Selectionnez voie..." itemValue="" />
<f:selectItems value="#{clientBean.typeVoies}" var="typeVoie" itemLabel="#{typeVoie.libelle}" itemValue="#{typeVoie}" />
</p:selectOneMenu>
<p:message for="txtVoie" />
<p:outputPanel></p:outputPanel>
<p:outputPanel>
<p:commandButton value="Annuler" update="formClient"
styleClass="redButton" process="#this"
actionListener="#{clientBean.cancel()}" />
<p:commandButton ajax="false" value="Suivant"
styleClass="greenButton" action="Devis?faces-redirect=true"></p:commandButton>
</p:outputPanel>
</p:panelGrid>
</h:form>
</h:panelGroup>
As you see here i have some fields that are a required, and a button to cancel (empties) the form:
#ManagedBean(name = "clientBean")
#SessionScoped
public class ClientBean implements Serializable {
#EJB
private IClientDAO clientDAO;
#EJB
private ITypeVoieDAO typeVoieDAO;
private List<TypeVoie> typeVoies;
private static final long serialVersionUID = -3324864097586374969L;
private Client client = new Client();
#PostConstruct
public void init(){
typeVoies = typeVoieDAO.findAll();
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public void rechercher(){
if(client != null && client.getIdentifiant() != null){
System.out.println(client.getIdentifiant());
client = clientDAO.findByIdentifiant(client.getIdentifiant());
if(client == null){
cancel();
}
}
}
public void cancel(){
client = new Client();
System.out.println(typeVoies);
}
public String navigateToClientPage(){
rechercher();
return "client?faces-redirect=true";
}
public List<TypeVoie> getTypeVoies() {
return typeVoies;
}
public void setTypeVoies(List<TypeVoie> typeVoies) {
this.typeVoies = typeVoies;
}
}
At the page loads, the selectonemenu loads perfectly, but when i click cancel, the selectonemenu gets emptied, even when i "search" for a client, and updates the form, all the other fields are filled properly, but the selectonemenu gets completely empty.
Using JSF 2.1 and primefaces 6.0
UPDATE:
Added a converter, but nothing change ...
Make sure you dont empty typeVoies list at some point on your backingbean. And if you can share your full java class, you might get more accurate help.
I have a datatable on a page with columns Unit/Set, Vehicle, Next Maintenance, Day 1,...,Day 7. I have two radio buttons also to change the sorting of the data, when I change to the other radio button which sorts by Date instead of Unit/Set the columns should change to Date, A Exams, B Exams, C Exams,...
I assume I need to create two datatables and then use the rendered attribute to decide which table is shown depending on which sort is selected.
<p:dataTable id="dataTableEnquiryNextDue" styleClass="editable-datatable"
rows="20"
scrollable="true"
frozenColumns="2"
rendered=>
<p:column headerText="Unit/Set" />
<p:column headerText="Vehicle" />
<p:column headerText="Next Maintenance" />
<p:column headerText="Day 1" />
<p:column headerText="Day 2" />
<p:column headerText="Day 3" />
<p:column headerText="Day 4" />
<p:column headerText="Day 5" />
<p:column headerText="Day 6" />
<p:column headerText="Day 7" />|
</p:dataTable>
This is my code for the datatable, except I have left the rendered blank at the minute, I believe I'll have to make some kind of bean, I think it will get the value of the radio buttons then I will have something like
rendered="#{Bean.searchSort == Unit}
or
rendered="#{Bean.searchSort == Date}
I have created a bean with the following code
#ManagedBean
#ViewScoped
public class DepotWorkloadBean implements Serializable {
public enum Sort {
UNIT, DATE
}
private Sort sortMode = Sort.UNIT;
public Sort getSortMode() {
return sortMode;
}
public void enterUnitSort() {
sortMode = Sort.UNIT;
}
public void enterDateSort() {
sortMode = Sort.DATE;
}
}
And in my table added the line
rendered="#{depotWorkloadBean.sortMode == 'UNIT'}"
I have also created my other table the same way but with
rendered="#{depotWorkloadBean.sortMode == 'DATE'}"
and different columns.
For my radio buttons I have written
<p:radioButton id="UnitSetNumber" for="customRadio3" itemIndex="0"
onchange="#{depotWorkloadBean.enterUnitSort}" update="dataTableDaySortUnit dataTableDaySortDate"/>
<p:radioButton id="DateDue" for="customRadio3" itemIndex="1"
onchange="#{depotWorkloadBean.enterDateSort}" update="dataTableDaySortUnit dataTableDaySortDate"/>
At the moment I am getting an error saying
The class 'DepotWorkloadBean' does not have the property 'enterUnitSort'.
This is quite confusing as it clearly does and as far as I can tell I have spelt everything correctly. I'm still not sure if my approach is actually correct though, so again any advice will be appreciated.
Here is my selectOneRadio
<p:selectOneRadio id="customRadio3" layout="custom">
<f:selectItem itemLabel="UnitSetNumber" itemValue="1" binding="{depotWorkloadBean.enterUnitSort}"
update=":mainForm"/>
<!-- <f:ajax listener="#{depotWorkloadBean.enterUnitSort}" render="#all"/> -->
<f:selectItem itemLabel="DateDue" itemValue="2" binding="{depotWorkloadBean.enterDateSort}"
update=":mainForm"/>
<!-- <f:ajax listener="#{depotWorkloadBean.enterDateSort}" render="#all"/> -->
<f:selectItem itemLabel="DueInValue" itemValue="3" />
</p:selectOneRadio>
EDIT: Here is my updated selectOneRadio
<p:selectOneRadio id="customRadio3" layout="custom"
value="#{depotWorkloadBean.sortMode}"
update=":mainForm">
<f:selectItem itemLabel="UNIT.name" itemValue="UNIT" value="#{depotWorkloadBean.sortMode}"
var="UNIT"/>
<!-- <f:ajax listener="#{depotWorkloadBean.enterUnitSort}" render="#all"/> -->
<f:selectItem itemLabel="DATE.name" itemValue="DATE" value="#{depotWorkloadBean.sortMode}"
var="DATE"/>
<!-- <f:ajax listener="#{depotWorkloadBean.enterDateSort}" render="#all"/> -->
<f:selectItem itemLabel="DueInValue" itemValue="3" />
</p:selectOneRadio>
And here is my updated bean
#ManagedBean
#ViewScoped
public class DepotWorkloadBean implements Serializable {
public enum Sort {
UNIT, DATE
}
private Sort sortMode = Sort.UNIT;
public Sort getSortMode() {
return sortMode;
}
public Sort[] getSortValues() {
return Sort.values();
}
public void setSortMode(Sort sortMode) {
this.sortMode = sortMode;
}
}
EDIT: After a bit of thinking I have taken a new approach, so now my radio button group is like so:
<!-- <f:facet name="actions"> -->
<p:selectOneRadio id="customRadio3" layout="custom"
partialSubmit="true"
value="#{depotWorkloadBean.selectSort}">
<p:ajax update="mainForm" listener="#{depotWorkloadBean.updateSortMode}"/>
<f:selectItem itemLabel="UnitSet" itemValue="UnitSet"/>
<f:selectItem itemLabel="DateDue" itemValue="DateDue"/>
<f:selectItem itemLabel="DueInValue" itemValue="DueInValue"/>
</p:selectOneRadio>
<!-- </f:facet> -->
I have commented out the facet tag as it causes the error
"javax.servlet.ServletException" and I have no idea why.
My tables are as they were before except the rendered line is now
rendered="#{depotWorkloadBean.sortMode == 'UnitSet'}">
and similar for 'DateDue'. And my bean is as follows:
#ManagedBean
#ViewScoped
public class DepotWorkloadBean implements Serializable {
private static final Log log = LogFactory.getLog(DepotWorkloadBean.class);
/*public enum Sort {
UNIT, DATE
}
private Sort sortMode = Sort.UNIT;*/
private String sortMode = "UnitSet";
private String selectSort = "UnitSet";
public void updateSortMode () {
log.info("In updateSortMode " + " State [" + selectSort + "]");
sortMode = selectSort;
}
public String getSortMode() {
return sortMode;
}
public void setSortMode(String sortMode) {
this.sortMode = sortMode;
}
public String getSelectSort() {
return selectSort;
}
public void setSelectSort(String selectSort) {
log.info("Setting selectSort to [" + selectSort + "]");
this.selectSort = selectSort;
sortMode = selectSort;
}
I have only just found out about the log and it seems very useful. When my page builds and I click between the radio buttons my log records 'In updateSortMode State []' "Setting selectSort to State []" so there is clearly something going wrong in the method. The other thing I should mention is my radio buttons are actually displayed further down in the same panelGrid, like so..
<p:row>
<p:column>
<p:radioButton id="UnitSetNumber" for="customRadio3" itemIndex="0"/>
</p:column>
<p:column>
<h:outputLabel for="UnitSetNumber" value="Unit/set number" />
</p:column>
</p:row>
<p:row>
<p:column>
<p:radioButton id="DateDue" for="customRadio3" itemIndex="1"/>
</p:column>
<p:column>
<h:outputLabel for="DateDue" value="Date due" />
</p:column>
</p:row>
<p:row>
<p:column>
<p:radioButton id="DueInValue" for="customRadio3" itemIndex="2" />
</p:column>
<p:column>
<h:outputLabel for="DueInValue" value="Due in value" />
</p:column>
</p:row>
Not sure if that would affect the ajax listener?
Thanks
You don't need an onchange listener, the update= attribute will do the job.
Use a <p:selectOneRadio> with a nested <f:selectitems> that will set the sortMode value of your bean (you might need a converter). Then ensure the parent component of both tables is updated upon selection. This will re-evaluate the rendered= attributes of your tables with the newly set sortMode valule.
Example:
The view:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>TEST</title>
</h:head>
<h:body>
<h:form>
<p:selectOneRadio id="radiogroup"
value="#{testController.selectedValue}">
<f:ajax render=":content"/>
<f:selectItems value="#{testController.valuesTypes}"
var="val"
itemLabel="#{val.name()}"
itemValue="#{val}"/>
</p:selectOneRadio>
</h:form>
<h:form id="content">
<p:outputPanel rendered="#{testController.selectedValue eq 'VALUEA'}">
Value A panel
</p:outputPanel>
<p:outputPanel rendered="#{testController.selectedValue eq 'VALUEB'}">
Value B panel
</p:outputPanel>
<p:outputPanel rendered="#{testController.selectedValue eq 'VALUEC'}">
Value C panel
</p:outputPanel>
</h:form>
</h:body>
</html>
And the bean:
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class TestController {
public enum ValueTypes {
VALUEA,
VALUEB,
VALUEC
}
private ValueTypes selectedValue;
public ValueTypes getSelectedValue() {
return selectedValue;
}
public void setSelectedValue(ValueTypes selectedValue) {
this.selectedValue = selectedValue;
}
#PostConstruct
public void init() {
selectedValue = ValueTypes.VALUEA;
}
public ValueTypes[] getValuesTypes() {
return ValueTypes.values();
}
}
I'm a beginner in primefaces framework, I want that my commandButton verify if the selected item is "All" to call a specific method allBooks() , and if another item is choosen: to call another method : loadBook()
<p:selectOneMenu value="#{bookBean.selectedBook.id}">
<f:selectItem itemLabel="Select a book :" itemValue="" />
<f:selectItem itemLabel="All" />
<f:selectItems value="#{bookBean.selectedBooksItems}" />
<p:ajax execute="bookSelect" event="change" listener="#{bookBean.loadBook}" />
</p:selectOneMenu>
<p:commandButton id="validate" action="#{bookBean.requestBook}" value="Validate"/>
Do it in your actionListener method
<p:selectOneMenu value="#{bookBean.selection}">
<f:selectItem itemLabel="Select a book :" itemValue="#{null}" />
<f:selectItem itemLabel="All" itemValue="#{'ALL'}" />
<f:selectItems value="#{bookBean.options}" />
<p:ajax/>
</p:selectOneMenu>
<p:commandButton actionListener="#{bookBean.loadButtonActionListener}" value="Load"/>
public void loadButtonActionListener(ActionEvent event){
if(this.selection.equals("ALL")) {
this.allBooks();
} else {
this.loadBook(this.selection);
}
}
commandButton ajaxified by default so this snippet work as you expect:
<h:form>
<p:selectOneMenu value="#{myBean.selected}">
<f:selectItem itemLabel="ALL" itemValue="ALL" />
<f:selectItem itemLabel="NONE" itemValue="NONE" />
</p:selectOneMenu>
<p:commandButton value="Validate" actionListener="#{myBean.doAction}" />
</h:form>
here is declared bean:
#Named
#RequestScoped
public class MyBean {
private String selected;
public MyBean() {
}
public String getSelected() {
return selected;
}
public void setSelected(String selected) {
this.selected = selected;
}
public void doAction() {
if (selected.equals("ALL")) {
System.out.println("ALL Called!");
} else if (selected.equals("NONE")) {
System.out.println("NONE Called");
}
}
}
UPDATE:
if you want to add ajax change event to selectOneMenu just nest this line in selectOneMenu element
<p:ajax listener="#{myBean.doAction}" />
In p:selectOneMenu loginbranchName value is not set in bean.In selectItems having list of branchName.I'm using listener to select value from list but value not set in getLoginBranchId method....
<h:outputLabel value="Branch Name:*" style="text-align: left;display: block;" rendered="#{loginBean.userLoggedIn}"/>
<p:selectOneMenu value="#{loginBean.loginbranchName}"
rendered="#{loginBean.userLoggedIn}"
style="width:175px;">
<f:selectItem itemLabel="Select" itemValue="0" />
<f:selectItems value="#{loginBean.branchName}" />
<p:ajax event="change" listener="#{loginBean.getLoginBranchId}"/>
</p:selectOneMenu>
login.java
public String getLoginbranchName() {
return loginbranchName;
}
public void setLoginbranchName(String loginbranchName) {
System.out.println("loginbranchName"+loginbranchName);
this.loginbranchName = loginbranchName;
}
public void getLoginBranchId()
{
System.out.println("enter into getloginbranchid");
System.out.println("loginbranchName"+loginbranchName);
int unitId=loginDAO.getLoginBranchId(loginbranchName);
System.out.println("unitId"+unitId);
}
#BalusC was correct regarding the above discussion where, JSF2 can work with List and SelectItem https://stackoverflow.com/tags/selectonemenu/info I think you might be missing
<h:form>
</h:form>
tag.