I am validating the inputted items of the form when form is submitted through AJAX but the form is not rendering the required message in the h:message section. By full post back method validation method works fine but in AJAX submission method the required message doesn't render.
Here is the code:
item.xhtml
<h:form class="form-signin" id="registrationform" enctype="multipart/form-data">
<h:panelGroup id="panel" border="0" cellpadding="0" cellspacing="10" styleClass=" labelText">
<f:facet name="header">
<h:messages id="message" style="color:red;margin:8px;" globalOnly="true" />
</f:facet>
</h:panelGroup>
<div class="section-title">
<div class="title">Item Description</div>
</div>
<h:panelGrid columns="6">
<h:outputLabel for="goodName" value="Names of good *" styleClass="labelforItems" />
<h:outputLabel for="quantity" value="Quantity *" styleClass="labelforItems" />
<h:inputText id="quantity" style="#{ component.valid ? 'border-color:#ccc;' : 'border-color:red;'}" value="#{registrationBean.quantity}" styleClass="form-control input-adjust quantity" required="true" requiredMessage="Package quantity is required." />
<h:outputLabel for="hscode" value="HS Code*" styleClass="labelforItems" />
<h:inputText id="hscode" value="#{registrationBean.hscode}" styleClass="form-control input-adjust hscode" required="true" requiredMessage="HS Code is required" />
<h:outputLabel for="goodsDescription" value="Description *" styleClass="labelforItems" />
<h:inputTextarea id="goodsDescription" value="#{registrationBean.descriptions}" style="#{ component.valid ? 'border-color:#ccc;' : 'border-color:red;'}" required="true" requiredMessage="Goods description is required." styleClass="form-control textareawh goodsDescription" />
<h:commandLink value="Add" id="addItem" action="#{registrationBean.addItemAction}" onclick="pkgDiv()" styleClass="btn btn-primary">
<f:ajax execute="goodName quantity brand model hscode goodsDescription" render=":registrationform:panel" />
</h:commandLink>
<h:outputLabel />
<h:outputLabel />
<h:outputLabel />
<h:outputLabel />
</h:panelGrid>
</h:form>
Related
I have a rich faces popuppanel that I want to keep open until all validation is done. For now I just have a required attribute on the address. If the address is missing and the Submit button is clicked the popuppanel should stay open until the address is entered which it does. However when the user enters an address the form sends the email as it should but the page stays open. I need the popuppanel to close when the required field is entered.
<rich:popupPanel id="addressModalPanel" header="Change Billing Address" modal="true" domElementAttachment="form" width="450" height="400">
<h2>Submit Change of Billing Address</h2>
<h:outputLabel value="Enter changes to your company's billing address in the fields below and then click Submit" /><br></br>
<h:panelGrid columns="2" >
<h:outputLabel value="Company Name: "/>
<h:inputText value="#{supplieraddress.supplierAddress.supplierName}" disabled="true" />
<h:outputLabel value="Vendor Number: " />
<h:inputText value="#{supplieraddress.supplierAddress.id}" disabled="true"/>
<h:outputLabel value="Address: " />
<h:inputText id="add1" value="#{supplieraddress.supplierAddress.add1}" required="true" requiredMessage="Address is required" style="width:200px" />
<h:outputLabel value=""/>
<h:inputText value="#{supplieraddress.supplierAddress.add2}" style="width:200px" />
<h:outputLabel value=""/>
<h:inputText value="#{supplieraddress.supplierAddress.add3}" style="width:200px" />
<h:outputLabel value="City: " />
<h:inputText id="city" value="#{supplieraddress.supplierAddress.city}" />
<h:outputLabel value="State: " />
<h:inputText id="state" value="#{supplieraddress.supplierAddress.state}" style="width:50px" />
<h:outputLabel value="Zip: " />
<h:inputText id="zip" value="#{supplieraddress.supplierAddress.zip}" style="width:50px" />
<h:outputLabel value="Country (If not US): " />
<h:inputText id="country" value="#{supplieraddress.supplierAddress.country}" style="width:50px" />
<a4j:commandButton id="submit" value="Submit" actionListener="#{supplieraddress.billingAddressEmail()}" oncomplete="if(#{!empty add1}) #{rich:component('addressModalPanel')}.hide()" >
</a4j:commandButton>
<h:commandButton value="Close" >
<rich:componentControl event="click" target="addressModalPanel" operation="hide" />
</h:commandButton>
<a4j:outputPanel ajaxRendered="true">
<rich:message for="add1" style="color:red"/>
</a4j:outputPanel>
</h:panelGrid>
</rich:popupPanel>
if(#{!empty add1}) looks like a misuse of the empty operator; empty is to be applied to Collections only. What you should be using instead
<a4j:commandButton id="submit" value="Submit" actionListener="#{supplieraddress.billingAddressEmail()}" oncomplete="if(!#{facesContext.validationFailed}) #{rich:component('addressModalPanel')}.hide()" >
Where facesContext.validationFailed is a convenience method that checks the validation status of the current JSF context
I am not able to validate input fields using primefaces ajax on the client side by calling event blur using primefaces
<h:panelGrid columns="2">
<p:outputLabel for="uname" value="Name"/>
<p:inputText id="uname" value="#{userbean.name}" required="true" requiredMessage="Enter your name">
<p:ajax event="blur" rendererType="name"/>
</p:inputText>
<h:outputText value=""/>
<p:message id="name" for="uname" />
<p:outputLabel for="add" value="Address"/>
<p:inputText id="add" value="#{userbean.address}" required="true" requiredMessage="Enter your address">
<p:ajax event="blur" rendered="address"/>
</p:inputText>
<h:outputText value=""/>
<p:message id="address" for="add" />
<h:commandButton value="Submit"/>
</h:panelGrid>
I am not sure what you're doing with 'rendererType and rendered' on your ajax events - they make no sense and ikely just breaking.
I've got it working fine in the below example (note my bean is different name) - i made the grid only 1 in colum size just for testing purposes and you're best off wrapping those full data objects you want re-rendered after ajax request. see the below code p:ajax uses 'update' to render content, where f:ajax uses render="id" etc..
<h:form>
<h:panelGrid columns="1">
<h:panelGroup layout="block" id="nameSection" >
<p:outputLabel for="uname" value="Name"/>
<p:inputText id="uname" value="#{onBlur.name}" required="true" requiredMessage="Enter your name">
<p:ajax event="blur" update="nameSection"/>
</p:inputText>
<h:outputText value=""/>
<p:message id="name" for="uname" />
</h:panelGroup>
<h:panelGroup layout="block" id="addressSection" >
<p:outputLabel for="add" value="Address"/>
<p:inputText id="add" value="#{onBlur.address}" required="true" requiredMessage="Enter your address">
<p:ajax event="blur" update="addressSection"/>
</p:inputText>
<h:outputText value=""/>
<p:message id="address" for="add" />
</h:panelGroup>
</h:panelGrid>
<h:commandButton value="Submit"/>
</h:form>
i am working on login page in which there is 2 input field user name and password and 2 submit button login and forgot password. All these 4 elements are in a form. I have applied validation for null input to user name password. If a user click on login without providing username and password it shows some primefaces message. Forgot password is a popup, which has also two field username and email, same blank alidation is also here. my problem is when i click on login witout providing any input, it popups the forgot password window along with username and password validation error.
Following is my code.
Thanks
Login Page
<h:form >
<p:panel id="panel" >
<p:focus context="panel"/>
<h:panelGrid >
<h:outputLabel for="firstname" value="#{app.username} : " style="font-weight:bold; font-size:12px;">
<h:outputLabel value="*" style="color:red; font-size:12px;"/></h:outputLabel>
<p:inputText id="firstname" required="true" label="Firstname" value="#{userManageBean.user.userName}" size="35" maxlength="10" requiredMessage="User Name is required."/>
<p:message for="firstname" />
<br/>
<h:outputLabel for="surname" value="#{app.paswrd} : " style="font-weight:bold; font-size:12px;">
<h:outputLabel value="*" style="color:red; font-size:12px;"/></h:outputLabel>
<p:inputText id="surname" required="true" label="#{app.paswrd}" value="#{userManageBean.user.password}" type="password" size="35" maxlength="10" requiredMessage="Password is Required" />
<p:message for="surname" />
<h:outputText value="#{userManageBean.message}" style="font-weight:bold; font-size:12px; color:red; "></h:outputText>
</h:panelGrid>
<br/>
<p:commandButton id="SubmitButton1" value="#{app.log_in}" action="#{userManageBean.submitLoginUser}" ajax="false" />
<p:commandButton value="#{app.forgotpwd}" onclick="dlg1.show();" ajax="false" />
</p:panel>
</h:form>
Pop up
<h:form>
<p:dialog header="#{app.forgotpwd}" widgetVar="dlg1" resizable="false" width="300" showEffect="clip" hideEffect="fold" modal="true" visible="#{facesContext.validationFailed}" >
<table>
<tr>
<td><h:outputText value="#{app.username} : "/> <h:outputText value="*" style="color:red; font-size:12px;"/></td>
<td> <p:inputText id="txt" value="#{forgetPwdBean.userID}" required="true" requiredMessage="User Name is Required" />
<p:message for="txt" ></p:message>
<!-- <p:tooltip for="txt" value="#{viewcontrollerBundle.username}" showEffect="fade" hideEffect="fade" /> -->
</td>
</tr>
<tr><td>
<h:outputText value="#{app.emp_id} : "/><h:outputText value="*" style="color:red; font-size:12px;"/></td>
<td> <p:inputText id="txt1" value="#{forgetPwdBean.emailID}" required="true" requiredMessage="Email is Required"/>
<p:message for="txt1"></p:message>
<!-- <p:tooltip for="txt1" value="#{viewcontrollerBundle.mailid}" showEffect="fade" hideEffect="fade" /> -->
</td>
</tr>
<tr><td><p:commandButton value="#{app.submit}" action="#{forgetPwdBean.forgetPassword}" ajax="false"/>
</td></tr>
</table>
</p:dialog>
</h:form>
The following code causes your dialog to popup whenever a validation of your form fails.
<p:dialog ... visible="#{facesContext.validationFailed}">
Edit (Why the dialog isnt shown without above code):
The underlying problem is that your commandButtons are non-ajax, so the page will be completly reloaded and you might only see the dialog for a split second
If you look into the primefaces showcase you can see that the button that use onclick="dlg.show()" use ajax:
<p:commandButton id="modalDialogButton" value="Modal" onclick="dlg2.show();" type="button"/>
Updating the question to below:
Please see attached code.
<h:form id="tblForm" styleClass="formTblClass">
<h3 style="text-align: center; background-color: purple; color: white;">Contact Details</h3>
<h:panelGrid id="contactPanel" columns="3">
<h:outputLabel for="roleIn" value="Role: " />
<h:selectOneMenu id="roleIn" value="#{docHeader.roleIn}" required="true" requiredMessage="Please select one from dropdown.">
<f:selectItem itemLabel="--Select--" noSelectionOption="true"/>
<f:selectItems value="#{docHeader.listOfRoles}"/>
</h:selectOneMenu>
<h:message for="roleIn" style="color: red;"/>
<h:outputLabel for="empIdIn" value="Employee ID: " />
<h:inputText id="empIdIn" value="#{docHeader.empId}" required="true" requiredMessage="Please enter valid employee id">
<f:ajax listener="#{docHeader.fetchEmpDetails}" render="empName workPhone emailId" />
</h:inputText>
<h:message for="empIdIn" style="color: red;"/>
<h:outputLabel for="empName" value="Name: " />
<h:inputText id="empName" readonly="true" value="#{docHeader.empName}" /><br/>
<h:outputLabel for="workPhone" value="Work Phone: " />
<h:inputText id="workPhone" readonly="true" value="#{docHeader.workPhone}" /><br/>
<h:outputLabel for="emailId" value="Email ID: " />
<h:inputText id="emailId" readonly="true" value="#{docHeader.emailId}" /><br/>
</h:panelGrid>
<h:commandButton value="Add">
<f:ajax event="click" listener="#{docHeader.addContactToList}"
render="contactPanel contactTable" execute="#this contactPanel" />
</h:commandButton>
<h:dataTable id="contactTable" value="#{docHeader.contactList}"
var="contact" headerClass="list-header" rowClasses="list-row" columnClasses="list-column-center" border="1" width="100%">
<h:column>
<f:facet name="header">Role</f:facet>#{contact.roleIn}
</h:column>
<h:column>
<f:facet name="header">Employee ID</f:facet>#{contact.empId}
</h:column>
<h:column>
<f:facet name="header">Employee Name</f:facet>#{contact.empName}
</h:column>
<h:column>
<f:facet name="header">Work Phone</f:facet>#{contact.workPhone}
</h:column>
<h:column>
<f:facet name="header">Email ID</f:facet>#{contact.emailId}
</h:column>
</h:dataTable>
<div style="text-align: center">
<h:commandButton value="Next">
<f:ajax event="click" render="none" listener=""/>
</h:commandButton>
</div>
</h:form>
From above code, addtoContactList is working absolutely fine and the contactTable is displaying the information too.
But when clicked on NEXT i'm getting required field messages and not able to navigate to the next page.
When clicked next i want execute a method in managed bean like moveToNextPage.
Any Ideas appreciated.
You have <h:message> tag for each inputText in the upper panelGrid. So by default <f:ajax> does the following render="#this" and execute="#this". You need to change like below:
<h:panelGrid id="myPanel" columns="3">
<h:outputLabel for="wrNum" value="ITG/WR #: " />
<h:inputText id="wrNum" required="true" value="#{docHeader.wrNum}" requiredMessage="Please enter ITG/WR #."/>
<h:message for="wrNum"/>
<h:outputLabel for="wrDesc" value="ITG/WR Description: " />
<h:inputText id="wrDesc" required="true" value="#{docHeader.wrDesc}" requiredMessage="Please enter ITG/WR Description"/>
<h:message for="wrDesc"/>
</h:panelGrid>
<h:commandButton value="Add" immediate="true">
<f:ajax event="click" listener="#{docHeader.addWrReqInfoToList}" render="myPanel workReqInfoTbl" execute="#this myPanel"/>
</h:commandButton>
<h:dataTable id="workReqInfoTbl" value="#{docHeader.workReqInfoList}" var="wrReqInfo" style="border: red solid 1px;">
</h:dataTable>
I got a problem. I have a bean CreateProjectBean which is RequestScope bean. I want to use Prime Faces component called Collector so i can dynamicly change in view createProject table groupRoleAdapters which is a field of CreateProjectBean. Unforuntely every time i click "add" or "remove" in collector, there is a new request being sent to bean, which means, that GroupRoleAdapters is being created once more - of course empty.
My collector code:
<p:panel header="Add group">
<h:panelGrid columns="2">
<h:outputLabel value="Group name: *" for="txt_title"></h:outputLabel>
<h:selectOneMenu id="groupMenu"
value="#{createProjectBean.groupRoleAdapter.groupName}">
<f:selectItems value="#{createProjectBean.groupNames}"
var="group" itemValue="#{group}" itemLabel="#{group}" />
</h:selectOneMenu>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:groupMenu" />
<h:outputLabel value="Role name: *" for="txt_title"></h:outputLabel>
<h:selectOneMenu id="roleMenu"
value="#{createProjectBean.groupRoleAdapter.roleName}">
<f:selectItems value="#{createProjectBean.roleNames}" var="role"
itemValue="#{role}" itemLabel="#{role}" />
</h:selectOneMenu>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:roleMenu" />
<f:verbatim>
<br />
</f:verbatim>
<p:commandButton value="Add" update="creationForm:out"
action="#{createProjectBean.reinit}">
<p:collector value="#{createProjectBean.groupRoleAdapter}"
addTo="#{createProjectBean.selectedGroupRoleAdapters}"/>
</p:commandButton>
</h:panelGrid>
</p:panel>
<f:verbatim>
<br />
</f:verbatim>
<p:outputPanel id="out">
<p:dataTable value="#{createProjectBean.selectedGroupRoleAdapters}"
var="groupRoleAdapter">
<p:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{groupRoleAdapter.groupName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Role" />
</f:facet>
<h:outputText value="#{groupRoleAdapter.roleName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Operation" />
</f:facet>
<p:commandLink value="Remove" update="creationForm:out">
<p:collector value="#{groupRoleAdapter}" removeFrom="#{createProjectBean.selectedGroupRoleAdapters}" />
</p:commandLink>
</p:column>
</p:dataTable>
</p:outputPanel>
I'd like to use the same instance of bean while adding and removing groupRoleAdapters from list selectedGroupRoleAdapters (represented by collector table), but create new instance of bean every time i try to create new project, so changing scope to sessionScope is not what i can accept.
Thanks in advance for every help.
I attach full code of that view:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<ui:composition template="/templates/template.xhtml">
<ui:define name="head">
<title>Create Project</title>
<link rel="stylesheet" type="text/css"
href="#{facesContext.externalContext.requestContextPath}/styles/style.css" />
</ui:define>
<ui:define name="content">
<div class="mainTable">
<center><f:view>
<h:outputText id="error" rendered="false" />
<h:message styleClass="errorMessage" for="error" />
<h:form id="creationForm">
<h:panelGrid columns="2" width="420">
<h:panelGroup width="300">
<h:outputLabel styleClass="formLabel" value="Name: "></h:outputLabel>
</h:panelGroup>
<h:panelGroup>
<h:inputText styleClass="formField" id="name"
value="#{createProjectBean.project.name}" required="true">
<f:validateLength minimum="3" />
</h:inputText>
</h:panelGroup>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:name" />
<h:panelGroup>
<h:outputLabel styleClass="formLabel" value="Short Name: " />
</h:panelGroup>
<h:panelGroup>
<h:inputText styleClass="formField" id="shortname"
value="#{createProjectBean.project.shortname}" required="false">
<f:validateLength maximum="8" />
</h:inputText>
</h:panelGroup>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:shortname" />
<h:panelGroup>
<h:outputLabel styleClass="formLabel" value="Homepage: " />
</h:panelGroup>
<h:panelGroup>
<h:inputText styleClass="formField" id="homepage"
value="#{createProjectBean.project.homepage}" required="false">
</h:inputText>
</h:panelGroup>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:hostname" />
<h:panelGroup>
<h:outputLabel styleClass="formLabel" value="Description: " />
</h:panelGroup>
<h:panelGroup>
<h:inputTextarea styleClass="formField" id="description"
value="#{createProjectBean.project.description}" required="false"
cols="50" rows="10" />
</h:panelGroup>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:description" />
<h:panelGroup>
<h:outputLabel styleClass="formLabel" value="Plugins: " />
</h:panelGroup>
<h:selectManyListbox id="pluginBox"
value="#{createProjectBean.selectedPluginNames}">
<f:selectItems value="#{createProjectBean.pluginNames}"
var="plugin" itemValue="#{plugin}" itemLabel="#{plugin}" />
</h:selectManyListbox>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:pluginBox" />
<h:panelGroup>
<h:outputLabel styleClass="formLabel" value="Tags: " />
</h:panelGroup>
<h:selectManyListbox id="tagBox"
value="#{createProjectBean.project.tags}">
<f:selectItems value="#{createProjectBean.allTags}" var="tag"
itemValue="#{tag}" itemLabel="#{tag.name}" />
</h:selectManyListbox>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:tagBox" />
<f:verbatim>
<br />
</f:verbatim>
<p:panel header="Add group">
<h:panelGrid columns="2">
<h:outputLabel value="Group name: *" for="txt_title"></h:outputLabel>
<h:selectOneMenu id="groupMenu"
value="#{createProjectBean.groupRoleAdapter.groupName}">
<f:selectItems value="#{createProjectBean.groupNames}"
var="group" itemValue="#{group}" itemLabel="#{group}" />
</h:selectOneMenu>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:groupMenu" />
<h:outputLabel value="Role name: *" for="txt_title"></h:outputLabel>
<h:selectOneMenu id="roleMenu"
value="#{createProjectBean.groupRoleAdapter.roleName}">
<f:selectItems value="#{createProjectBean.roleNames}" var="role"
itemValue="#{role}" itemLabel="#{role}" />
</h:selectOneMenu>
<f:verbatim>
<br />
</f:verbatim>
<h:message styleClass="errorMessage" for="creationForm:roleMenu" />
<f:verbatim>
<br />
</f:verbatim>
<p:commandButton value="Add" update="creationForm:out"
action="#{createProjectBean.reinit}">
<p:collector value="#{createProjectBean.groupRoleAdapter}"
addTo="#{createProjectBean.selectedGroupRoleAdapters}"/>
</p:commandButton>
</h:panelGrid>
</p:panel>
<f:verbatim>
<br />
</f:verbatim>
<p:outputPanel id="out">
<p:dataTable value="#{createProjectBean.selectedGroupRoleAdapters}"
var="groupRoleAdapter">
<p:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{groupRoleAdapter.groupName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Role" />
</f:facet>
<h:outputText value="#{groupRoleAdapter.roleName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Operation" />
</f:facet>
<p:commandLink value="Remove" update="creationForm:out">
<p:collector value="#{groupRoleAdapter}"
removeFrom="#{createProjectBean.selectedGroupRoleAdapters}" />
</p:commandLink>
</p:column>
</p:dataTable>
</p:outputPanel>
<f:verbatim>
<br />
</f:verbatim>
<h:commandButton value="Create" styleClass="formButton"
action="#{createProjectBean.create}" />
</h:panelGrid>
</h:form>
</f:view></center>
</div>
</ui:define>
</ui:composition>
</html>
If you're already on JSF 2.0, just put the bean in view scope, by either #ViewScoped annotation or by <managed-bean-scope>view</managed-bean-scope> in faces-config.xml.
If you're still on JSF 1.x (which I'm afraid of since you're using those ugly JSF 1.0/1.1-mandatory <f:verbatim> tags), then you have to either put bean in session scope, eventually in combination with an unique request scoped parameter which is retained in subsequent requests by h:inputHidden or f:param, or to grab a 3rd party library with a component which is able to save the state of an entire request scoped bean for the subsequent request, like Tomahawk's t:saveState.