p:commandButton action not invoked after and ajax update - ajax

I have a JSF page which has a p:commandButton which has ajax=true and renders a p:panel which is wrapped in p:outputPanel when clicked. When this button is clicked the action method will set showCreateUser value in ManagedBean to true and this is used to render the Panel. This works fine - on button click the panel is rendered properly. Inside the p:panel there is another p:commandButton. This commanButton is not working as nothing happens when I click on it. The action method is never invoked. When I debug I realised that even though the ajax action sets showCreateUser to true but when I click on second button the showCreateUser value is false. So, the panel panel rendered=false and so the action is never invoked. Following are the xhtml and managedbean class. How can I resolve this? Thanks for your help!
registration.xhtml
<h:form id="userForm" style="background-color:white;border:0px; width:90%;">
<p:messages id="messagesForDebugging"
showDetail="true"
autoUpdate="true" />
<ui:debug hotkey="x"/>
<div style="margin-bottom: 10px;">
<p:commandButton id="btnConfirmYes" value="Yes" ajax="true" update="userRegOutPanel"
action="#{regBean.confirmYes}" styleClass="button" style="height:35px;">
<!-- <f:ajax render="userRegOutPanel" execute="userRegOutPanel"/> -->
</p:commandButton>
<p:commandButton id="btnConfirmNo" value="No" ajax="false"
action="#{regBean.confirmNo}" styleClass="button" style="height:35px;"/>
</div>
<p:outputPanel id="userRegOutPanel">
<p:panel id="userRegPanel" rendered="#{regBean.showCreateUser}">
<p:panelGrid id="userRegPanelGrid">
<p:row>
<p:column style="width:40%;background-color:#00a5b6;-moz-border-radius: 10px;-webkit-border-radius: 10px;-khtml-border-radius: 10px;border-radius: 10px;text-align:left;">
<h:inputHidden id="ssn" value="#{regBean.ssn}"/>
<p:panelGrid>
<p:row>
<p:column>
<p:commandButton value="Submit" ajax="true" action="#{regBean.submitRegistration}"
styleClass="button" style="width:140px;height:35px;" type="submit"/>
</p:column>
</p:row>
</p:panelGrid>
</p:column>
</p:row>
</p:panelGrid>
</p:panel>
</p:outputPanel>
</h:form>
Managed Bean
#ManagedBean
#ViewScoped
public class RegBean implements Serializable{
private static final long serialVersionUID = 1L;
static Logger log = LoggerFactory.getLogger(RegBean.class);
private String ssn;
private boolean showCreateUser = false;
public void confirmYes(){
setShowCreateUser(true);
}
public String confirmNo(){
log.info("In retrieveRegistration");
FacesContext fc = FacesContext.getCurrentInstance();
fc.addMessage("registrationError", new FacesMessage(
FacesMessage.SEVERITY_ERROR,
"Error. Contact customer service",
"Error. Contact customer service"));
return "/registration/registrationError";
}
public String submitRegistration() {
log.info("In submitRegistration");
FacesContext fc = FacesContext.getCurrentInstance();
return "/secured/home";
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
public boolean isShowCreateUser() {
return showCreateUser;
}
public void setShowCreateUser(boolean showCreateUser) {
this.showCreateUser = showCreateUser;
}
}

<p:commandButton id="btnConfirmNo" value="No" ajax="false"
action="#{regBean.ConfirmNo}"
styleClass="button" style="height:35px;"/>
In above code ,you've set action to be "ConfirmNo". I don't see any method as such.
Change above code as :
<p:commandButton id="btnConfirmNo" value="No" ajax="false"
action="#{regBean.agentConfirmNo}"
styleClass="button" style="height:35px;"/>
Now, it will invoke the method agentConfirmNo from your registration bean.
I hope that helps.

Related

Modal edit dialog on Primefaces with JSF

I'm trying to create some CRUD JSF application with edit/new screen implemented as a modal dialog. The problem is that I can't find a way how to make new and edit operation done by this dialog performed with ajax. With delete all was very simple (just ajax="true" option).
Here is a code of button which is used to show the dialog
<h:form id="dataForm">
<div class="ui-g">
<div class="ui-g-12 ui-md-9">
<p:dataGrid var="product" value="#{products.productList}" columns="3" layout="grid"
rows="12" paginator="true" id="products"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="6,12,16">
<f:event type="preRenderView" listener="#{products.preloadProductList}" />
<f:facet name="header">
Products
</f:facet>
<p:panel header="#{product.name}" style="text-align:center">
<h:panelGrid columns="1" style="width:100%">
<h:outputText value="#{product.name}"/>
<h:outputText value="#{product.price}"/>
<%-- Here new/edit dialog window is opened --%>
<p:commandLink update=":dataForm:productDetail" oncomplete="PF('productDialog').show()">
Edit
<f:setPropertyActionListener value="#{product}" target="#{products.product}"/>
</p:commandLink>
<p:commandLink update=":dataForm" action="#{products.deleteAction(product)}" ajax="true">
Delete
</p:commandLink>
</h:panelGrid>
</p:panel>
</p:dataGrid>
<ui:include src="WEB-INF/dialogs/edit_product.xhtml"/>
</div>
</div>
</h:form>
Here is dialog window which is moved to separete file edit_product.xhtml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<p:dialog header="Product Info" widgetVar="productDialog" modal="true" showEffect="fade"
hideEffect="fade"
resizable="false">
<p:outputPanel id="productDetail" style="text-align:center;">
<p:panelGrid columns="2" rendered="#{not empty products.product}"
columnClasses="label,value">
<h:outputText value="Id:"/>
<h:outputText value="#{products.id}"/>
<h:outputText value="Name"/>
<h:inputText value="#{products.name}"/>
<h:outputText value="Price"/>
<h:inputText value="#{products.price}"/>
</p:panelGrid>
<h:commandButton value="Save" action="#{products.saveProduct}"/>
</p:outputPanel>
</p:dialog>
</ui:composition>
Here is Managed bean which is used by the Product dataGrid and dialog window.
#ManagedBean(name = "products")
#SessionScoped
public class ProductsBean {
private static final Logger logger = LoggerFactory.getLogger(ProductsBean.class);
#Inject
private ProductRepository productRepository;
private Product product;
private Collection<Product> productList;
public void preloadProductList(ComponentSystemEvent event) throws AbortProcessingException {
productList = productRepository.getAll();
}
public String getId() {
return String.valueOf(product.getId());
}
public void setId(String id) {
product.setId(Long.valueOf(id));
}
public String getName() {
return product.getName();
}
public void setName(String name) {
product.setName(name);
}
public int getPrice() {
return product.getPrice();
}
public void setPrice(int price) {
product.setPrice(price);
}
public Product getProduct() {
return this.product;
}
public void setProduct(Product product) {
this.product = product;
}
public Collection<Product> getProductList() {
logger.info("Get product list");
return productList;
}
public void newProductAction() {
this.product = new Product();
}
public void deleteAction(Product product) {
logger.info("Delete product");
productRepository.remove(product);
}
public void saveProduct() {
productRepository.merge(product);
}
}
No matter if I add ajax option or not the whole window is reloaded after Save button is pressed. Could you show me the right direction for the implementation, please?
P.S. If you need more code to answer you can find it here:
Main page with Product table https://github.com/usharik/GeekBrainsJavaEE/blob/master/lesson5-jpa/src/main/webapp/index.xhtml
Edit/New dialog https://github.com/usharik/GeekBrainsJavaEE/blob/master/lesson5-jpa/src/main/webapp/WEB-INF/dialogs/edit_product.xhtml

jsf inputText don't execute change listener event

i have two .xhtml pages with two similar inputText elements ("customer id" and "customer name"), in both pages the inputText for "customer id" launch a request ajax event to looking for the name of the customer and to put it in the inputText for "customer name".
when i run the web application and use the first pages everything work fine, but if i don't use the first page and go to the second page (via commandlink in first page) without use the first page then the inputText for search the customer name don't work, indeed not enter to the testBean2.searchCustId method.
the code:
first page
<h:form>
<h:commandLink action="page2">PAGE 2</h:commandLink><br/>
<h:outputText value="customer id: "/>
<h:inputText id="custoId" label="CUSTOMER_ID" value="#{testBean.custId}" required="true">
<a4j:ajax event="change" listener="#{testBean.searchCustId(testBean.custId)}" render="custoName"/>
<f:validateLength minimum="1" maximum="12"/>
</h:inputText>
<rich:message for="custoID" ajaxRendered="true"/>
<h:outputText value="Customer name: "/>
<h:inputText id="custoName" label="CUSTOMER_NAME" value="#{testBean.custName}"/>
<rich:message for="custoName" ajaxRendered="true"/>
</h:form>
second page
<h:form>
<h:outputText value="customer id: "/>
<h:inputText id="custoId2" label="CUSTOMER_ID2" value="#{testBean2.custId}" required="true">
<a4j:ajax event="change" listener="#{testBean2.searchCustId(testBean2.custId, 0)}" render="custoName2"/>
<f:validateLength minimum="1" maximum="12"/>
</h:inputText>
<rich:message for="custoId2" ajaxRendered="true"/>
<h:outputText value="customer name: "/>
<h:inputText id="custoName2" label="CUSTOMER_NAME2" value="#{testBean2.custName}"/>
<rich:message for="custoName2" ajaxRendered="true"/>
</h:form>
now jsf managed bean
testBean
public class TestBean {
private String custId;
private String custName;
public TestBean() {
}
//getter and setter
public void searchCustId(String ced){
custName = ced + "- SOME CUSTOMER NAME"; //THIS IS FOR TESTING
}
}
testBean2
public class TestBean2 {
private String custId;
private String custName;
public TestBean2() {
}
//getter and setter
public void searchCustId(String ced, int que){
custName = ced + " - " + que; //THIS IS FOR TESTING
}
}
what may be happening?
i'm new on this and my english is not good :)
You can use f:setPropertyActionListener.
<a4j:ajax event="change" listener="#{myBean.listener}">
<f:setPropertyActionListener target="#{myBean.someProperty}" value="your_value_here"/>
</a4j:ajax>
But from your code it looks like you are trying to pass the very one value that's used on h:inputText, that's not necessary:
<h:inputText id="custoId" label="CUSTOMER_ID" value="#{testBean.custId}" required="true">
<a4j:ajax event="change" listener="#{testBean.searchCustId}" render="custoName"/>
<f:validateLength minimum="1" maximum="12"/>
</h:inputText>
After Ajax event the values testBean.searchCustId will automatically be updated on Managed bean after passing the validation, so your listener could be:
public class TestBean {
private String custId;
private String custName;
public TestBean() {
}
//getter and setter
public void searchCustId(){
custName = custId + "- SOME CUSTOMER NAME"; //THIS IS FOR TESTING
}
}

Primefaces ajax pagination not working

I have following jsf page, in which datatable is populated via ajax request from database. Problem is, after pushing another page button on pagination bar, table shows no results. Changing scope of backing bean to session helps, but it is not a solution. Why it is happening?
<h:form>
<h:panelGrid columns="2" cellpadding="8" style="width: 545px">
<h:panelGroup>
<p:outputLabel value="Client name: " for="searchString" />
<br />
<p:inputText id="searchString" title="searchString" value="#{findClientBean.searchString}" />
</h:panelGroup>
<h:panelGroup>
<br />
<p:message for="searchString" />
</h:panelGroup>
<p:commandButton value="Search" styleClass="pCommandButton" >
<f:ajax execute="searchString" listener="#{findClientBean.findClient}" render=":resultTable" />
</p:commandButton>
</h:panelGrid>
</h:form>
<br />
<p:dataTable id="resultTable" var="client" value="#{findClientBean.resultList}" paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" paginatorPosition="bottom">
<p:column headerText="Search results">
<h:outputLink value="../temp.xhtml?id=#{client.id}">#{client.firstName} #{client.lastName}</h:outputLink>
</p:column>
</p:dataTable>
<h:form>
Backing bean code:
#Named
#RequestScoped
public class FindClientBean implements Serializable {
#Inject
private ClientDAO clientDAO;
#NotNull(message="Search string cannot be empty")
private String searchString;
private List<Client> resultList;
public void findClient() {
resultList = clientDAO.findClientByNameOrLastnamePart(searchString);
}
public void setResultList(List<Client> resultList) {
this.resultList = resultList;
}
public List<Client> getResultList() {
return resultList;
}
public String getSearchString() {
return searchString;
}
public void setSearchString(String searchString) {
this.searchString = searchString;
}
}
Your Client resultList is being populated whenever the user presses the Search button.
As the collection is inside a RequestScoped bean, the resultList will be erased as soon as it is sent back to the View (along with the entire bean).
As a result, when the user tries to navigate to another page (thus making a second request) the component won't find a populated resultList anymore and a "No records found" message will be displayed.
"Promote" you bean to ViewScoped (or any scope that would make your bean live longer).
#Named
#ViewScoped
public class FindClientBean implements Serializable{
(...)
}

primefaces dialog disappears when commandButton is submitted

I have a proble with dialog, here is my add.xhtml :
when I click "Envoyer demande" I'm displaying a message of confirmation "Demande d'inscription envoyée" in the dialog but dialog disappears after clicking button "Envoyer demande" .
here is add.xhtm :
<h:form>
<h:commandLink value="Créer un compte" onclick="dlg3.show();return false;"/>
</h:form>
<p:dialog id="modalDialoog" widgetVar="dlg3" draggable="false" resizable="false"
dynamic="true" header="Inscription">
<center>
<p:panel id="xyzBody">
<h:form id="inscri-f">
<h:panelGrid id="loginPan" columns="2" bgcolor="White">
<h:outputText value="Nom d'utilisateur :" />
<p:inputText id="username" value="#{demandeBean.login}"></p:inputText>
<h:outputText value="Mot de passe :" />
<p:password id="pwd" value="#{demandeBean.pwd}"/>
<h:commandButton value="Envoyer demande" update=":inscri-f:cr"
actionListener="#{demandeBean.envoi_dde}"></h:commandButton>
<h:commandButton value="Retour" action="page1?faces-redirect=true"></h:commandButton>
<p:outputPanel id="cr">
<h:outputText rendered="#{demandeBean.saved}" value="#{demandeBean.message}"/>
</p:outputPanel>
</h:panelGrid>
</h:form>
</p:panel>
</center>
</p:dialog>
my addBean.java :
#ViewScoped
public class DemandeBean implements Serializable{
private static final long serialVersionUID = 1L;
DdeDAO ndao = new DdeDaoImpl();
private String login;
private String pwd;
private String message = "";
private boolean saved = false;
//getters and setters of all attributes
public void envoi_dde(){
Demande d = new Demande();
d.setNom_ut(this.login);
d.setPwd(this.pwd);
ndao.nouvelle_dde(d);
saved = true;
this.setMessage("Demande d'inscription envoyée");
}
I want dialog not to disappear after clicking button "Envoyer demande" .
1) change the h:commandButton to p:commandButton
2) set the ajax attribute of p:commandButton to true
this must work perfectly

Reloading div using Ajax

I have found this topic, where's a bit of code to reload a div using Ajax.
I've tried creating such example, but not successfully.
Here's my code:
index.xhtml
<h:form>
<f:ajax render=":content">
<h:commandButton value="News" action="#{navigationBean.requestPage}">
<f:param name="requestedPage" value="news.xhtml"/>
</h:commandButton>
</f:ajax>
<br/><br/>
<f:ajax render=":content">
<h:commandButton value="News" action="#{navigationBean.requestPage}">
<f:param name="requestedPage" value="games.xhtml"/>
</h:commandButton>
</f:ajax>
</h:form>
</h:panelGroup>
<h:panelGroup id="content" layout="block">
<ui:include src="#{navigationBean.viewedPage}"/>
</h:panelGroup>
backing bean
#ManagedBean
#ViewScoped
public class NavigationBean
{
private String viewedPage;
public NavigationBean()
{
viewedPage = "news.xhtml";
}
public String getViewedPage()
{
return viewedPage;
}
public void setViewedPage(String viewedPage)
{
this.viewedPage = viewedPage;
}
public void requestPage()
{
Map<String,String> map = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
viewedPage = map.get("requestedPage");
}
}
how it looks:
So what am I missing? Variable viewedPage is updated, normal labels/texts etc. are updated, but can't get this div working.
Found the solution:
<h:commandButton value="Games" action="#{navigationBean.requestPage}">
<f:param name="requestedPage" value="games.xhtml"/>
<f:ajax execute="#this" render="#none" />
<f:ajax render=":content"/>
</h:commandButton>
plus changing #ViewScoped to #SessionScoped.

Resources