JSF : dynamically loaded page commandButton not working - ajax

I have a page that contains a PrimeFaces accordion panel, in each panel is a PrimeFaces datatable. Below the datatable is a button "Add study" for example and when this button is click I want to dynamically load a page into a <h:panelGroup> using a <ui:include>. When the button is being click I want to dynamically change the src value from the <ui:include> so that my page is loaded in the <h:panelGroup>. Now the problem is the following:
My managed bean is set to #RequestScoped and when I click on my button nothing is being rendered.
If I set my managed bean to #SessionScoped the <h:panelGroup> is filled after the second click on the button, the first click doesn't do anything.
Used technologies : JSF2.0, PrimeFaces, Facelets
Here are some code snippets :
Main Page
<h:panelGroup id="content" layout="block">
<ui:include src="#{studyBean.includePage}"/>
</h:panelGroup>
<div id="dashboard">
<h:form id="form" prependId="false">
<h:outputText value="Welkom #{loginBean.username}"/>
<p:accordionPanel autoHeight="true" effect="bounceslide">
<p:tab title="My studies">
<p:dataTable var="study" value="#{studyBean.studiesByUser}" id="studyTable"
emptyMessage="No studies found for given user" paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" rowSelectListener="#{studyBean.onRowSelect}"
selectionMode="single">
<p:column headerText="StartDate" sortBy="#{study.startDate}"
filterBy="#{study.startDate}"
filterMatchMode="contains" style="width: 100px;">
<h:outputText value="#{study.startDate}">
<f:convertDateTime pattern="dd/MM/yyyy" type="date" timeZone="CET"/>
</h:outputText>
</p:column>
<p:column headerText="EndDate" sortBy="#{study.endDate}"
filterBy="#{study.endDate}}"
filterMatchMode="contains" style="width: 100px;">
<h:outputText value="#{study.endDate}">
<f:convertDateTime pattern="dd/MM/yyyy" type="date" timeZone="CET"/>
</h:outputText>
</p:column>
<p:column headerText="School" sortBy="#{study.school}" filterBy="#{study.school}}"
filterMatchMode="contains" style="width: 100px;">
<h:outputText value="#{study.school}"/>
</p:column>
<p:column headerText="Specialization" sortBy="#{study.specialization}"
filterBy="#{study.specialization}}" filterMatchMode="contains"
style="width: 100px;">
<h:outputText value="#{study.specialization}"/>
</p:column>
<p:column headerText="Remarks" sortBy="#{study.remarks}"
filterBy="#{study.remarks}}"
filterMatchMode="contains" style="width: 100px;">
<h:outputText value="#{study.remarks}"/>
</p:column>
</p:dataTable>
<h:commandButton id="btnAddStudy" title="Add Study" value="Add Study">
<f:ajax render=":content" execute="form" listener="# {studyBean.navigate}"/>
<f:param name="action" value="add"/>
</h:commandButton>
</p:tab>
</p:accordionPanel>
</h:form>
So as you can see is my <h:panelGroup> outside my form.
This is the included page (as example)
<h:body>
<ui:composition template="../template/template.xhtml">
<ui:define name="body">
<f:view contentType="text/html">
<ui:composition>
<h:form id="studyForm" prependId="false">
<p:messages />
<h:message for="startDate"/>
<h:message for="endDate"/>
<h:message for="school"/>
<h:message for="diploma1"/>
<h:message for="diploma2"/>
<h:message for="diploma3"/>
<h:message for="specialization1"/>
<h:message for="specialization2"/>
<h:message for="specialization3"/>
<h:message for="remarks1"/>
<h:message for="remarks2"/>
<h:message for="remarks3"/>
<h:outputText class="label" value="Start date: "/>
<h:inputText id="startDate" styleClass="inputtext validate[required,custom[date]]"
value="#{studyBean.startDate}">
<f:convertDateTime pattern="dd/MM/yyyy" timeZone="CET"/>
</h:inputText>
<h:outputText class="label" value="End date: "/>
<h:inputText id="endDate" styleClass="inputtext validate[required,custom[date]]"
value="#{studyBean.endDate}">
<f:convertDateTime pattern="dd/MM/yyyy" timeZone="CET"/>
</h:inputText>
<h:outputText class="label" value="school: "/>
<h:inputText id="school" styleClass="inputtext validate[required, maxSize[5]]"
value="#{studyBean.school}"/>
<h:outputText class="label" value="Specialization: "/>
<h:inputText id="specialization1" styleClass="inputtext validate[maxSize[50]]"
value="#{studyBean.specialization[0]}"/>
<h:inputText id="specialization2" styleClass="inputtext validate[maxSize[50]]"
value="#{studyBean.specialization[1]}"/>
<h:inputText id="specialization3" styleClass="inputtext validate[maxSize[50]]"
value="#{studyBean.specialization[2]}"/>
<h:outputText class="label" value="Diploma: "/>
<h:inputText id="diploma1" styleClass="inputtext validate[maxSize[50]]"
value="#{studyBean.diploma[0]}"/>
<h:inputText id="diploma2" styleClass="inputtext validate[maxSize[50]]"
value="#{studyBean.diploma[1]}"/>
<h:inputText id="diploma3" styleClass="inputtext validate[maxSize[50]]"
value="#{studyBean.diploma[2]}"/>
<h:outputText class="label" value="remarks: "/>
<h:inputText id="remarks1" styleClass="inputtext validate[maxSize[200]]"
value="#{studyBean.remarks[0]}"/>
<h:inputText id="remarks2" styleClass="inputtext validate[maxSize[200]]"
value="#{studyBean.remarks[1]}"/>
<h:inputText id="remarks3" styleClass="inputtext validate[maxSize[200]]"
value="#{studyBean.remarks[2]}"/>
<h:commandButton action="cancel" value="cancel" immediate="true"/>
<p:commandButton id="btnAddStudyDetail" value="add study" actionListener="#{studyBean.addStudy}"
update="studyTable" oncomplete="clearAddStudy()"/>
</h:form>
</ui:composition>
</f:view>
</ui:define>
</ui:composition>
</h:body>
Managed Bean #RequestScoped
#ManagedBean
#RequestScoped
public class StudyBean {
public String navigate() {
FacesContext facesContext = FacesContext.getCurrentInstance();
try {
action = (((HttpServletRequest) facesContext.getExternalContext().getRequest()).getParameter("action"));
if (action.equals("add")) {
//vull de velden
includePage = "studyDetail.xhtml";
}
facesContext = FacesContext.getCurrentInstance();
UIViewRoot root = facesContext.getViewRoot();
UIComponent form = root.findComponent("form");
dataTable = form.findComponent("studyTable");
System.out.println(dataTable);
System.out.println(root);
} catch (Exception e) {
facesContext.addMessage("form", new FacesMessage("You must select a study."));
}
return null;
}
}
Thanks in advance.
UPDATE
Now I am able to dynamically load the page in my <ui:include> but I have another problem now, when the page is loaded and I want to click on my button in the loaded page the action to which it is bound doesn't execute. So I don't get into my backing bean, I already tried to put the scope of my bean to #ViewScoped but no success.
Please help me as I am getting desperate.

Related

primefaces ui is not rendering properly

I'm having a problem with primefaces ui. It doesnt render icon that it was supposed to be rendered when I use and the problem is not happening only on this but also on many other pages. I haven't used jquery.
I dont know what's wrong. Googled it but didnt find an answer.
Here is my code
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="/WEB-INF/faces/template.xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:jsf="http://xmlns.jcp.org/jsf" xmlns:p="http://primefaces.org/ui"
xmlns:prettyfaces="http://ocpsoft.com/prettyfaces">
<ui:param name="title" value="List of Employee"/>
<ui:define name="breadcrum1">
<li><h:link value="Employee Management" outcome="pretty:home"/></li>
<li><h:link value="List Employee Record" outcome="pretty:list_employee"/></li>
</ui:define>
<ui:define name="content">
<div class="container">
<div class="row">
<div class="col-xs-10 col-md-10 span3">
<p:messages id="messages" autoUpdate="true" closable="true" globalOnly="true" style="text-align: center;"/>
<h:form id="form">
<p:dataTable
class="panel-primary table table-condensed"
var="employee" value="#{dtLazyView.lazyModel}" paginator="true" rows="10"
emptyMessage="No Employee found with given criteria"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15" selectionMode="single" selection="#{dtLazyView.selectedEmployee}" widgetVar="employeeTable" lazy="true">
<f:facet name="header">
Employee Information
<h:outputText value="Search all fields:" />
<p:inputText id="globalFilter" onkeyup="PF('employeeTable').filter()" style="width:150px" placeholder="Enter keyword"/>
</f:facet>
<p:column headerText="Id">
<h:outputText value="#{employee.employeeCode}" />
</p:column>
<p:column headerText="Employee Name">
<h:outputText value="#{employee.employeeName}" />
</p:column>
<p:column headerText="Employee Mobile Number">
<h:outputText value="#{employee.contact.mobileNumber}" />
</p:column>
<p:column headerText="Employee Role" >
<h:outputText value="#{employee.detail.employeeRole}" />
</p:column>
<p:column headerText="Option">
<h:commandButton action="#{employeeEditController.loadData(employee)}" value="Edit" class="btn btn-primary" style="margin-left: 40px;"> <f:ajax execute="#form"/></h:commandButton>
<p:commandButton update=":form:employeeDetail" oncomplete="PF('employeeDialog').show()" icon="ui-icon-search" title="View">
<f:setPropertyActionListener value="#{employee}" target="#{dtLazyView.selectedEmployee}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog header="Employee Info" widgetVar="employeeDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false" styleClass="">
<p:outputPanel id="employeeDetail" style="text-align:center;">
<p:panelGrid columns="2" rendered="#{not empty dtLazyView.selectedEmployee}" columnClasses="label,value">
<f:facet name="header">
<img src="../../imageshandler/#{dtLazyView.selectedEmployee.employeePicture}" class="img-responsive" style="width:200px;height: 200px;margin-left: 100px;border-radius: 50%"/>
</f:facet>
<h:outputText value="Name :" style="color: black"/>
<h:outputText value="#{dtLazyView.selectedEmployee.employeeName}" />
<h:outputText value="DOB :" style="color: black"/>
<h:outputText value="#{dtLazyView.selectedEmployee.employeeDob}" />
<h:outputText value="Gender :" style="color: black"/>
<h:outputText value="#{dtLazyView.selectedEmployee.sex}" style="color:#{dtSelectionView.selectedCar.color}"/>
<h:outputText value="Salary : " style="color: black" />
<h:outputText value="Rs : #{dtLazyView.selectedEmployee.salary.basicSalary}" />
<h:outputText value="Working date :" style="color: black"/>
<h:outputText value="#{dtLazyView.selectedEmployee.employeeDateOfCommencement}"/>
<h:outputText value="Employee Job Specification :" style="color: black"/>
<h:inputTextarea value="#{dtLazyView.selectedEmployee.detail.jobSpecification}" readonly="true"/>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
</div>
</div>
</div>
</ui:define>
According to Primefaces, you can use Font Awesome for the icons, so try replacing
icon="ui-icon-search"
with
icon="fa fa-search"
Keep in mind
Font Awesome icons are provided out of the box within PrimeFaces. In
order to enable Font Awesome support, enable primefaces.FONT_AWESOME
setting as true via a context param.

Method in actionListener is not invoked after validation failed

I have a command Button that calls a method from the Session Scoped Bean if the inputs are valid.
<h:form id="mainform">
<p:panel id="panelform" header="Email Extractor" >
<h:panelGrid id="formulaire" columns="2">
<h:panelGroup id="formblock" layout="block" >
<p:panelGrid columns="2">
<p:outputLabel for="Keyword" value="Keyword: " />
<p:inputText id="Keyword" type="search" requiredMessage="Keyword is required"
value="#{mailMB.keyword}" required="true" label="Keyword">
</p:inputText>
<p:outputLabel for="Emailsnbr" value="Enter the emails'number:" />
<p:inputText id="Emailsnbr" type="number" requiredMessage="Emails number is required" validatorMessage="Enter a number"
value="#{mailMB.number}" required="true" label="Emailsnbr">
<f:validateDoubleRange minimum="1" maximum="53500" />
</p:inputText>
</p:panelGrid>
</h:panelGroup>
</h:panelGrid>
<p:commandButton value="Extract" style="width: 12%;height: 100%" update="tableemails, :confirmPurchaseTest, :mainform" id="extractbutton" ajax="true" widgetVar="ButtonExtract"
actionListener="#{mailMB.searchEmails()}" onstart="blockUIWidget1.show();" oncomplete=" blockUIWidget1.hide(); if (args && !args.validationFailed) confirmDialog.show();" />
<p:dialog widgetVar="blockUIWidget1" modal="true" closable="false" resizable="false" >
<h:panelGrid columns="2">
<div>
<p:graphicImage url="pictures/loading81.gif" width="200" height="200" alt="animated-loading-bar"/>
<h:outputLabel value="Please wait..."/>
</div>
<div>
<p:button outcome="home" icon="ui-icon-arrowthick-1-w" title="Back To Home" style="margin-right: 5px;white-space: nowrap" />
</div>
</h:panelGrid>
</p:dialog>
</p:panel>
<p:dataTable rowIndexVar="rowIndex" id="tableemails" value="#{mailMB.mails}" var="item" rowsPerPageTemplate="5,10,15" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
paginator="true" rows="5" styleClass="case-table" emptyMessage="No records found with given criteria" paginatorPosition="bottom"
filteredValue="#{mailMB.filteredMails}" rowKey="#{item.id}"
selection="#{mailMB.selectedMail}" selectionMode="single" >
<p:ajax event="rowSelect" update=":mainform"/>
<p:column styleClass="blockable">
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{item.email}"/>
</p:column>
</p:dataTable>
</h:form>
<p:confirmDialog closable="false" style="position: absolute; width: 50px; border-color: blue" id="confirmPurchaseTest" message="Your Database was successfully created. It contains #{mailMB.number} Emails "
appendToBody="true"
header="Get Emails List" severity="info" widgetVar="confirmDialog">
<h:form>
<p:commandButton id="getEmails" style="width: 35%;height: 100%" value="Get Emails" oncomplete="window.location.href = '/Hitonclick/emailsList.xhtml'" >
<f:event type="preRenderView" listener="#{mailMB.preRender}"/>
</p:commandButton>
<p:commandButton id="declineTest" style="width: 35%;height: 100%" value="Decline" onclick="deleteDialog.show();" />
</h:form>
</p:confirmDialog>
My SessionScoped Bean is
#ManagedBean(name = "mailMB")
#SessionScoped
public class MailManagedBean implements Serializable {
#Inject
private MailBusinessLocal mailmanagerLocal;
#Inject
private DataBusinessLocal dataBusinessLocal;
#Inject
private CustomerBusinessLocal customerBusinessLocal;
.....
#PostConstruct
public void init() {
mails = new ArrayList<>();
}
public void searchEmails() throws Exception {
idCustomer = (String) session.getAttribute("idCustomer");
System.out.println(idCustomer + " this is it");
Customer customer = customerBusinessLocal.findById(idCustomer);
data = dataBusinessLocal.createData(new Date(), number, keyword, moteur, customer, State.REJECTED);
mails = mailBusinessLocal.createEmails(keyword, number, moteur, data);
System.out.println("Method was invoked");
}
}
if i enter 0 in the emails's number input for exemple and submit with Extract command Button for the first time i get the validatorMessage So i enter a valid number and submit again. And here comes the problem, the dialog in the oncomplete is shown without invoking the method in the actionListener. I mean i get the confirm dialog of persisted object without invoking the method that persists the object. Am i missing something??
How could i fix that?

PrimeFaces dialog is validated only the first time it appears

JSF 2.2, PrimeFaces 3.5.
home.xhtml contains a tabview with nested dataTables and add/edit/delete buttons. Each button is supposed to call a dialog with a form and submit/cancel buttons.
The problem is that validation is processed only once (see screenshot) and if I press "Add" / "Cancel" the dialog just hides and no validation is made. And if I try to reopen it once again and input values and hit "Add" - it just skips validation and renders response. So, basically, it just makes a initial request (if I guessed right).
Console output for pressing "Add" with empty values 3 times. First click has been processed the way I want it, but the next ones are just hiding the dialog without any validation:
2014-01-24 17:56:09,590 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1
2014-01-24 17:56:09,628 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: APPLY_REQUEST_VALUES 2
2014-01-24 17:56:09,633 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: PROCESS_VALIDATIONS 3
2014-01-24 17:56:09,645 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6
2014-01-24 17:56:13,127 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1
2014-01-24 17:56:13,128 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6
2014-01-24 17:56:16,557 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RESTORE_VIEW 1
2014-01-24 17:56:16,558 DEBUG [RequestLoggingPhaseListener] Entering JSF Phase: RENDER_RESPONSE 6
home.xhtml (dialogs are at the bottom of a page):
<?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">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ex="http://java.sun.com/jsf/composite/nsobchuk">
<h:head>
<title>Home page</title>
<link rel="stylesheet" href="../css/style.css"/>
</h:head>
<h:body>
<h:form id="logout" class="logout" >
<h:commandButton action="#{loginBean.logout()}" value="logout"/>
</h:form>
<p:tabView id="tab" orientation="left">
<p:tab title="Users">
<h:form id="form1">
<h:panelGrid columns="9">
<p:commandButton type="button" value="Add" onclick="dlg1.show()" />
<p:commandButton id="editUser" type="button" value="Edit" onclick="dlg2.show()" disabled="#{homeBean.selectedUser == null}"/>
<p:dialog id="editUserDialogerDialog" widgetVar="dlg2" header="Sorry" >
<h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
</p:dialog>
<p:commandButton id="deleteUser" type="button" onclick="confirmation1.show()" value="Delete" disabled="#{homeBean.selectedUser == null}"/>
<p:confirmDialog message="Are you sure you want to delete user?" header="Confirmation"
severity="alert" widgetVar="confirmation1">
<p:commandButton value="Yes" update=":tab:users" process="#this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
oncomplete="confirmation1.hide()" action="#{homeBean.deleteUser}" />
<p:commandButton value="No" onclick="confirmation1.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
</p:confirmDialog>
</h:panelGrid>
</h:form>
<p:dataTable id="users" var="user" value="#{homeBean.users}"
scrollable="true" scrollHeight="250" selectionMode="single"
selection="#{homeBean.selectedUser}" rowKey="#{user.userId}"
sortMode="single">
<p:ajax event="rowSelect" listener="#{homeBean.onUserRowSelect}" update=":tab:form1:deleteUser, :tab:form1:editUser"/>
<p:ajax event="rowUnselect" listener="#{homeBean.onUserRowUnselect}" update=":tab:form1:deleteUser, :tab:form1:editUser"/>
<p:column headerText="Login" sortBy="#{user.login}">
<h:outputText value="#{user.login}"/>
</p:column>
<p:column headerText="Password" sortBy="#{user.password}">
<h:outputText value="#{user.password}"/>
</p:column>
<p:column headerText="Role" sortBy="#{user.role}">
<h:outputText value="#{user.role}"/>
</p:column>
<p:column headerText="Name" sortBy="#{user.firstName}">
<h:outputText value="#{user.firstName}"/>
</p:column>
<p:column headerText="Surname" sortBy="#{user.lastName}">
<h:outputText value="#{user.lastName}"/>
</p:column>
</p:dataTable>
<ex:exporter target=":tab:users" fileName="Users"/>
</p:tab>
<p:tab title="Computers">
<h:form id="form2">
<h:panelGrid columns="9">
<p:commandButton type="button" value="Add" onclick="dlg3.show()"/>
<p:commandButton id="editComp" type="button" value="Edit" onclick="dlg4.show()" disabled="#{homeBean.selectedComputer == null}"/>
<p:dialog id="editCompDialog" widgetVar="dlg4" header="Sorry" >
<h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
</p:dialog>
<p:commandButton id="deleteComp" type="button" onclick="confirmation2.show()" value="Delete" disabled="#{homeBean.selectedComputer == null}"/>
<p:confirmDialog message="Are you sure you want to delete this computer?" header="Confirmation"
severity="alert" widgetVar="confirmation2">
<p:commandButton value="Yes" update=":tab:computers" process="#this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
oncomplete="confirmation2.hide()" action="#{homeBean.deleteComputer}"/>
<p:commandButton value="No" onclick="confirmation2.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
</p:confirmDialog>
</h:panelGrid>
</h:form>
<p:dataTable id="computers" var="computer" value="#{homeBean.computers}"
scrollable="true" scrollHeight="250" selectionMode="single"
selection="#{homeBean.selectedComputer}" rowKey="#{computer.computerId}"
sortMode="single" >
<p:ajax event="rowSelect" listener="#{homeBean.onCompRowSelect}" update=":tab:form2:editComp, :tab:form2:deleteComp"/>
<p:column headerText="Login" sortBy="#{computer.login}">
<h:outputText value="#{computer.login}"/>
</p:column>
<p:column headerText="Password" sortBy="#{computer.password}">
<h:outputText value="#{computer.password}"/>
</p:column>
<p:column headerText="Name" sortBy="#{computer.computerName}" >
<h:outputText value="#{computer.computerName}"/>
</p:column>
<p:column headerText="IP address" sortBy="#{computer.ipAddress}">
<h:outputText value="#{computer.ipAddress}"/>
</p:column>
</p:dataTable>
<ex:exporter target=":tab:computers" fileName="Computers"/>
</p:tab>
<p:tab title="Applications">
<h:form id="form3">
<h:panelGrid columns="9">
<p:commandButton type="button" value="Add" onclick="dlg5.show()"/>
<p:commandButton id="editApp" type="button" value="Edit" onclick="dlg6.show()" disabled="#{homeBean.selectedApplication == null}"/>
<p:dialog id="editAppDialog" widgetVar="dlg6" header="Sorry" >
<h:outputText value="I didn't have enogh time to finish this functionality. Feel free to test other buttons."/>
</p:dialog>
<p:commandButton id="deleteApp" type="button" onclick="confirmation3.show()" value="Delete" disabled="#{homeBean.selectedApplication == null}"/>
<p:confirmDialog message="Are you sure you want to delete this application?" header="Confirmation"
severity="alert" widgetVar="confirmation3">
<p:commandButton value="Yes" update=":tab:applications" process="#this" styleClass="ui-confirmdialog-yes" icon="ui-icon-check"
oncomplete="confirmation3.hide()" action="#{homeBean.deleteApplication}"/>
<p:commandButton value="No" onclick="confirmation3.hide()" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close"/>
</p:confirmDialog>
</h:panelGrid>
</h:form>
<p:dataTable id="applications" var="app" value="#{homeBean.applications}"
scrollable="true" scrollHeight="250" selectionMode="single"
selection="#{homeBean.selectedApplication}" rowKey="#{app.appId}"
sortMode="single" >
<p:ajax event="rowSelect" listener="#{homeBean.onAppRowSelect}" update=":tab:form3:editApp, :tab:form3:deleteApp"/>
<p:column headerText="Name" sortBy="#{app.appName}">
<h:outputText value="#{app.appName}"/>
</p:column>
<p:column headerText="Vendor" sortBy="#{app.vendorName}" >
<h:outputText value="#{app.vendorName}"/>
</p:column>
<p:column headerText="License required" sortBy="#{app.licenseRequired}">
<h:outputText value="#{app.licenseRequired}"/>
</p:column>
</p:dataTable>
<ex:exporter target=":tab:applications" fileName="Applications" />
</p:tab>
</p:tabView>
<p:dialog id="addUserDialog" header="Add Dialog" modal="true" closable="false"
widgetVar="dlg1" width="620" >
<h:form id="dlg1form">
<h:panelGrid columns="3">
<h:outputLabel for="login" value="Login: "/>
<p:inputText id="login" required="true"
label="Login: " maxlength="20" >
</p:inputText>
<p:message for="login" />
<h:outputLabel for="password" value="Password: "/>
<p:password id="password" required="true"
feedback="true" label="Password: " maxlength="32"/>
<p:message for="password" />
<h:outputLabel for="firstName" value="First Name: "/>
<p:inputText id="firstName"
label="First Name: " maxlength="20"/>
<p:message for="firstName"/>
<h:outputLabel for="lastName" value="Last Name: "/>
<p:inputText id="lastName"
label="Last Name: " maxlength="20"/>
<p:message for="lastName"/>
<h:outputLabel for="role" value="Role: "/>
<p:selectOneMenu id="role" required="true" style="width: 80px;" >
<f:selectItem itemLabel="user" itemValue="ROLE_USER" />
<f:selectItem itemLabel="admin" itemValue="ROLE_ADMIN" />
</p:selectOneMenu>
<p:message for="role"/>
</h:panelGrid>
<p:commandButton value="Cancel" onclick="dlg1.hide()" update="#form">
<p:resetInput target="addUserDialog" />
</p:commandButton>
<p:commandButton value="Add" update="#form" immediate="false"
oncomplete="if (args && !args.validationFailed) dlg1.hide()" />
</h:form>
</p:dialog>
<p:dialog id="addCompDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
widgetVar="dlg3" width="600">
<h:form id="dlg3form">
<h:panelGrid columns="3">
<h:outputLabel for="pclogin" value="Login: "/>
<p:inputText id="pclogin" required="true"
label="Login: " maxlength="20">
</p:inputText>
<p:message for="pclogin"/>
<h:outputLabel for="pcpassword" value="Password: "/>
<p:password id="pcpassword" required="true"
feedback="true" label="Password: " maxlength="32"/>
<p:message for="pcpassword" />
<h:outputLabel for="compName" value="Computer Name: "/>
<p:inputText id="compName" required="true"
label="Computer Name: " maxlength="20"/>
<p:message for="compName"/>
<h:outputLabel for="ipaddress" value="IP address: "/>
<p:inputText id="ipaddress" required="true"
label="IP address: " maxlength="20"/>
<p:message for="ipaddress"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg3.hide()" process="#this" update="#form">
<p:resetInput target="addCompDialog" />
</p:commandButton>
<p:commandButton value="Add" update="#form"
oncomplete="if (args && !args.validationFailed) dlg3.hide()" />
</h:form>
</p:dialog>
<p:dialog id="addAppDialog" header="Add Dialog" draggable="true" closable="false" modal="true"
widgetVar="dlg5" width="600" >
<h:form id="dlg5form">
<h:panelGrid columns="3">
<h:outputLabel for="appName" value="Name: "/>
<p:inputText id="appName" required="true"
label="Name: "/>
<p:message for="appName"/>
<h:outputLabel for="vendorName" value="Vendor: "/>
<p:inputText id="vendorName"
label="Vendor: " required="true" />
<p:message for="vendorName"/>
<h:outputLabel for="appLicense" value="Requires license: "/>
<p:selectOneMenu id="appLicense" required="true" style="width: 80px;" >
<f:selectItem itemLabel="True" itemValue="#{true}" />
<f:selectItem itemLabel="False" itemValue="#{false}" />
</p:selectOneMenu>
<p:message for="appLicense"/>
</h:panelGrid>
<p:commandButton value="Cancel" immediate="true" onclick="dlg5.hide()" update="#form" process="#this">
<p:resetInput target="addAppDialog" />
</p:commandButton>
<p:commandButton value="Add" update="#form"
oncomplete="if (args && !args.validationFailed) dlg5.hide()"/>
</h:form>
</p:dialog>
</h:body>
</ui:component>
HomeBean:
#Component
#Scope("session")
public class HomeBean extends BaseBean {
private static final String editUserBtn = "tab:form1:editUser";
private static final String deleteUserBtn = "tab:form1:deleteUser";
private static final String editCompBtn = "tab:form2:editComp";
private static final String deleteCompBtn = "tab:form2:deleteComp";
private static final String editAppBtn = "tab:form3:editApp";
private static final String deleteAppBtn = "tab:form3:deleteApp";
#Autowired
private HibernateDBManager hibernateDBManager;
private List<User> users;
private List<Computer> computers;
private List<Application> applications;
private User selectedUser, newUser;
private Computer selectedComputer, newComputer;
private Application selectedApplication, newApplication;
private RequestContext rc;
#Override
public void init() {
setUsers(hibernateDBManager.getAllUsers());
setComputers(hibernateDBManager.getAllComputers());
setApplications(hibernateDBManager.getAllApplications());
newUser = new User();
newComputer = new Computer();
newApplication = new Application();
rc = RequestContext.getCurrentInstance();
}
public void addUser() throws NoSuchAlgorithmException {
if (newUser != null && newUser.getPassword() != null) {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(newUser.getPassword().getBytes());
String hash = new BigInteger(1, md.digest()).toString(16);
newUser.setPassword(hash);
if (hibernateDBManager.insertUser(newUser)) {
users.add(newUser);
}
}
}
public void editUser() {
if (selectedUser != null) {
hibernateDBManager.updateUser(selectedUser);
users.set(users.indexOf(selectedUser), selectedUser);
selectedUser = null;
rc.update(deleteUserBtn);
rc.update(editUserBtn);
}
}
public void deleteUser() throws IOException {
if (selectedUser != null) {
if (hibernateDBManager.deleteUserById(selectedUser.getUserId()) > 0) {
users.remove(selectedUser);
selectedUser = null;
rc.update(deleteUserBtn);
rc.update(editUserBtn);
}
}
}
public void addComputer() {
if (newComputer != null && hibernateDBManager.insertComputer(newComputer)) {
computers.add(newComputer);
}
}
public void deleteComputer() {
if (selectedComputer != null) {
if (hibernateDBManager.deleteComputerById(selectedComputer.getComputerId()) > 0) {
computers.remove(selectedComputer);
selectedComputer = null;
rc.update(editCompBtn);
rc.update(deleteCompBtn);
}
}
}
public void addApplication() {
if (newApplication != null && hibernateDBManager.insertApplication(newApplication)) {
applications.add(newApplication);
}
}
public void deleteApplication() {
if (selectedApplication != null) {
if (hibernateDBManager.deleteApplicationById(selectedApplication.getAppId()) > 0) {
applications.remove(selectedApplication);
selectedApplication = null;
rc.update(editAppBtn);
rc.update(deleteAppBtn);
}
}
}
public void onUserRowSelect(SelectEvent event) {
setSelectedUser((User) event.getObject());
}
public void onUserRowUnselect(UnselectEvent event) {
setSelectedUser(null);
}
public void onCompRowSelect(SelectEvent event) {
setSelectedComputer((Computer) event.getObject());
}
public void onAppRowSelect(SelectEvent event) {
setSelectedApplication((Application) event.getObject());
}
//Getters etc.
}
I'd like to keep the dialog opened and validated each time user presses "Add" and not only once. Can anybody help me achieve this with my code or point me to the solution? (similar answered question with rating -1 didn't help me) Every answer is highly appreciated.
Thank you all.
Ok, guys. I found a solution by myself. What I did to make it work was giving a panelGrid element inside a form an id an updating panelGrid instead of a whole form.
So, "Add" button was changed to:
<p:commandButton value="Add"
update=":dlg1form:dt, :tab:users"
action="#{homeBean.addUser}"
oncomplete="if (!args.validationFailed) dlg1.hide()" />
and panelGrid, which contains input fields:
<h:form id="dlg1form">
<h:panelGrid columns="3" id="dt">
This helped me to validate input fields on every click and not just once.
Sincerely hope that this will help someone.
Cheers!
I had the same problem : having a update="#form" or update="yourFormName" inside my <p:commandButton> prevented the dialog from being kept when a validation error occured.
This might be due to the fact that including the update form command regenerate the whole dialog but doesn't trigger the dialogWidgetVar.show() js command.
I solved the issue by nesting a <p:fragment autoUpdate="true"> inside the dialog. Then, you can remove the update keyword inside the triggering commandButton since every component inside the fragment will be updated. The result is that the <p:dialog> and </p:dialog> tags are not replaced when the client receives the Ajax response. My working code is as follows :
<h:form id="locations_editer_creer">
<p:dialog id="location_dlg" widgetVar="locationDlg" header="#{msgs.LocationCreerNouvelle}" width="600" dynamic="false" closeOnEscape="true"
minimizable="true" maximizable="true" modal="true" >
<p:fragment autoUpdate="true">
your form inputs e.g. <p:inputText .../>
<p:commandButton id="OK" value="OK"
actionListener="#{locationsControleur.confirmer()}"
oncomplete="traiteRequeteCreationLoc(xhr, status, args)"
styleClass="ui-confirmdialog-yes" icon="ui-icon-check"/>
</p:fragment>
</p:dialog>
</h:form>
This technique is described inside the excellent PrimeFaces Beginner's Guide book by K. Siva Prasad Reddy (Packt Publishing), p. 54 : Partial Processing and Rendering using the Fragment component.
Hope this can help others.

JSF PrimeFaces / Ajax rendering to Datable fails to add items to the list

I am trying to user a form in 'panelGrid' to render values in a dataTable using <f:ajax>. However, when submitting using the <h:commandButton> the values sent are not displayed in the dataTable. I am not getting a stack or any console errors in the browsers.
This is the my xhtml (Simplified):
Product Catalog:
<p:tabView id="tabView" style="width: 65%" >
<p:tab id="books" title="Books">
<p:dataGrid var="book" value="#{saleBean.productList}" columns="3"
rows="9" paginator="true" paginatorTemplate="{CurrentPageReport}
{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink}
{LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="3,6,9">
<h:form id="product" >
<p:panel header="#{book.name}" style="text-align: center">
<h:panelGrid columns="1" style="width: 65%">
<!-- Add Book Images here -->
<h:outputText value="#{book.price}"/>
<h:outputLabel value="Dct (in dollars): " />
<h:inputText id="discount" value="#{saleBean.item.unit_discount}" style="width: 50%" />
<p:commandButton value="Add to Cart" update=":dataTableForm:sc"
action="#{saleBean.doAddItem}"/>
</h:panelGrid>
</p:panel>
</h:form>
</p:dataGrid>
</p:tab>
<p:tab id="arts" title="Art / Various">
<!-- Art Products to be added here -->
</p:tab>
<p:tab id="other" title="Other">
<!-- Various Products to be Added here -->
</p:tab>
</p:tabView>
<hr/>
<h1>Shopping Cart</h1>
<hr/>
<h:form id="dataTableForm">
<p:dataTable id="sc" value="#{saleBean.sd}" var="item" style="width: 60%">
<p:column>
<f:facet name="header">
<h:outputText value="Product"/>
</f:facet>
<h:outputText value="#{item.product_fk}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Quantity"/>
</f:facet>
<h:outputText value="#{item.quantity}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Unit Price"/>
</f:facet>
<h:outputText value="#{item.unit_Cost}"/>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Unit Discount"/>
</f:facet>
<h:outputText value="#{item.unit_discount}"/>
</p:column>
</p:dataTable>
</h:form>
</h:body>
This the bean (Simplified):
public String doAddItem()
{
item.setUnit_Cost(product.getPrice());
item.setProduct_fk(product);
item.setQuantity(1);
sd.add(item);
return "productCatalog";
}
According to PrimeFaces documentation :
http://www.primefaces.org/docs/vdl/3.4/primefaces-p/commandButton.html
Your actionListener="#{saleBean.doAddItem}" must use a function corresponding to that :
public void doAddItem(ActionListener event)
{
// do your stuff
}
To use action here is an example :
action="#{saleBean.doAddItem}"
public String doAddItem(void)
{
item.setUnit_Cost(product.getPrice());
item.setProduct_fk(product);
item.setQuantity(1);
sd.add(item);
return "productCatalog";
}
Try to use only pf components when you can eg p:datatable. Replace the button with a p:commandButton and use process and update instead of f:ajax.
Also maybe it will by better to include the p:datatable in the form too.

Fail to update h:outputText tag with (Primefaces) p:ajax call

I want for user while typing name, update name field in tab id="tab4" of accordionPanel.
Gives me an error with java.lang.IllegalArgumentException: out - the id of the tab
<ui:define name="contentBody">
<h:form id="form2">
<p:accordionPanel id="maintab" multiple="true">
<p:tab title="New Order">
<h:panelGrid columns="1" cellpadding="5">
<p:tabView id="tabView">
<p:tab title="Client" id="tab1">
<h:panelGrid columns="6" cellpadding="5">
<h:outputText value="Name " />
<p:inputText id="name" value="#{newOrderBean.name}">
<p:ajax update=":form2:maintab:out:name_id" />
</p:inputText>
</h:panelGrid>
</p:tab>
</p:tabView>
</h:panelGrid>
</p:tab>
<p:tab id="out" title="View Deatails">
<h:panelGrid id="panelgrid" columns="3" cellpadding="5">
<p:panel id="panel1" header="Client" style="width:200px;height:200px" >
<h:panelGrid id="grid1" columns="1">
<h:outputText id="name_id" value="#{newOrderBean.name}" />
</h:panelGrid>
</p:panel>
</h:panelGrid>
</p:tab>
</p:accordionPanel>
</h:form>
</ui:define>
could you please also clarify about the cases where i need to put my components into separate forms cause just for now i put the whole page into a single form tag. Thank you
Solved it!
With this code:
<h:outputText value="Name " />
<p:inputText id="name" value="#{newOrderBean.name}">
<f:ajax event="keyup" render=":form2:maintab:name_id" />
</p:inputText>

Resources