Validation and Faces Messages are not displayed - ajax

I have the following form in a p:outputPanel
<h:form id="someForm">
<p:panel id="panel" header="HEADER">
<h:panelGrid columns="5">
<h:outputLabel value="Name:" for="name" />
<p:inputText id="name" value="#{userBean.name}" required="true"
requiredMessage="ASD" label="name" maxlength="15">
<f:validateLength minimum="10"></f:validateLength>
<p:ajax event="blur" update="inputValidationMessage" />
</p:inputText>
<p:message id="inputValidationMessage" showDetail="true" for="name"
display="icon" />
<p:watermark for="name" value="e.g Jill" />
</h:panelGrid>
<p:commandButton value="Save" update="panel"
actionListener="#{userBean.doSomething}">
</p:commandButton>
</p:panel>
</h:form>
I expect that when the inputText element loses focus and its content has a length less than 10 characters, the message ASD is displayed right next to it. However, what happens in case validation fails is, only a red cross icon is displayed. The message ASD is missing. Changing showDetail to showSummary doesn't work neither.
Secondly, the commandButton calls userBean.doSomething:
UserBean#doSomething:
public void doSomething(ActionEvent actionEvent) {
RequestContext context = RequestContext.getCurrentInstance();
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_WARN,
"Summary",
"Detail"));
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
context.addCallbackParam("booleanVar", true);
}
The FacesMessage is not being displayed.
I'm using JSF2.0 with Primefaces 3.0 on Weblogic 12.1.
Any help appreciated.

You've declared the <p:message> as follows:
<p:message ... display="icon" />
Here's a cite from the <p:message> documentation in the PrimeFaces User Guide:
Display Mode
Message component has three different display modes;
text : Only message text is displayed.
icon : Only message severity is displayed and message text is visible as a tooltip.
both (default) : Both icon and text are displayed.
So the message severity is displayed as icon and message text is only displayed as tooltip of the icon. You need to remove the display="icon" so that it will show both in view.
<p:message ... />

Related

Component doesn't show the validation/error message just an icon

I have an autocomplete with validator. If the validator fails, it doesn't show the error message. It is shown only in a tooltip.
<h:panelGroup styleClass="form-group">
<div class="col-md-3">
<p:outputLabel value="#{labels['product_console_ins_management_company']}"
for="managementCompany" />
<p:panel rendered="#{empty saveProduct.initShowId}" >
<div class="form-control">
<p:autoComplete id="managementCompany"
required="true"
requiredMessage="#{labels['product_console_ins_management_company_validation']}"
value="#{saveProduct.product.company}"
var="b" itemLabel="#{b.description}" itemValue="#{b}"
completeMethod="#{saveProductConsoleController.completeInstrumentFactory}"
process="#this" scrollHeight="300" forceSelection="true"
converter="components.SimpleTypeBeanCollectionArrayConverter">
<f:validator validatorId="managementCompanyValidator"/>
<f:attribute name="boundList"
value="#{domainData.instrumentFactoryList}" />
</p:autoComplete>
</div>
</p:panel>
<br />
<p:outputLabel
rendered="#{ not empty saveProduct.initShowId}"
value="#{saveProduct.product.company.description}" />
<p:message for="managementCompany" display="icon" />
</div>
</h:panelGroup>
Screenshot of the problem
This is exactly what you tell it to do and effectively your question is not related to the validator or the p:autocomplete.
From the PrimeFaces documentation (read it, use it, it IS usefull)
Display Mode
Message component has three different display modes;
text : Only message text is displayed.
icon : Only message severity is displayed and message text is visible as a tooltip.
both (default) : Both icon and text are displayed.
This can also be seen in the PrimeFaces showcase for the message(s) component
So if you want different behaviour, choose a different value ('text' or 'both')

Validation messages across required fields with converter

I have a form with multiple fields, of which I need one of them required to continue or a group of them. For simplicity, I'll just paste a simpler version of my code here
<h:form id="searchForm">
<p:growl for="searchForm" showDetail="true" showSummary="true"/>
<p:inputText id="name"
value="#{backingBean.name}"
required="#{backingBean.nameRequired and backingBean.masterRequired}">
<p:ajax />
</p:inputText>
<h:panelGroup id="dateForm">
<p:inputMask id="date"
value="#{backingBean.date}"
mask="99/99/9999"
required="#{backingBean.dateRequired and backingBean.masterRequired}"
converterMessage="Please insert using format dd/mm/yyyy">
<f:convertDateTime pattern="dd/MM/yyyy" />
<f:validator validatorId="dateValidator" />
<p:ajax update="dateForm" />
</p:inputMask>
</h:panelGroup>
<p:selectOneMenu id="documentType" effect="fade"
value="#{backingBean.documentType}"
required="#{backingBean.documentRequired and backingBean.masterRequired}">
<f:selectItem itemLabel="Select document type" noSelectOption="true" />
<f:selectItems
value="#{constantsController.docType.entrySet()}"
var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
<p:ajax />
</p:selectOneMenu>
<p:inputText id="documentNumber"
value="#{backingBean.documentNumber}"
required="#{backingBean.documentRequired and backingBean.masterRequired}">
<p:ajax />
</p:inputText>
<p:commandButton id="searchButton"
value="Search"
action="#{controllerBean.submitSearch}"
icon="ui-icon-search">
<p:ajax
listener="#{backingBean.checkRequired()}" update="#form" />
</p:commandButton>
</h:form>
When all fields are empty, the is shown as it should. Now what I need is the inputMask date to only show the converter message and the validation message. I need it to not show the message when the requiredMessage will try to be shown.
I tried putting a <p:message for="date" rendered="#{!empty param['date']}" /> but it does not work, since it is not rendered on the first load, and ajax does not update the panelGroup, I think it is because since I gave an invalid value to the converter, it does not fire the update.
Additional information:
As you can see, I have multiple required fields, I need at least one of these:
-name
-date
-document type + document number
Now, to validate the required fields, I'm doing the following on my backing bean:
public void checkRequired() {
nameRequired = name.equals("");
dateRequired = date == null;
documentRequired = documentType.equals("") || documentNumber.equals("");
masterRequired = nameRequired && dateRequired && documentRequired;
if(masterRequired)
{
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_WARN, "Incomplete form",
"Please insert at least 1 field");
FacesContext.getCurrentInstance().addMessage("searchForm", message);
return;
}
}

Validation errors in dialog not updating after failed submit in JSF

So I click a button which opens a dialog. Inside this dialog I want to fill out information in a form and submit and save it. Some of the inputTexts need to be required in order to submit. So I use the required="true" attribute. It stops the submission, but it does not update the field with a red outline of everything. Now, if I hit cancel and open up the dialog again it will show the fields that failed validation with a red outline!
I thought I could solve this by manually updating the dialog whenever I try to submit the form. This just causes the dialog to close though instead of staying open and refreshing the dialog to show the validation failures.
This is the dialog, when I hit the save button is when I submit the form
<h:form>
<p:dialog header="#{headerValue}" widgetVar="#{uniqueId}_editDialog"
modal="false" showEffect="fade" styleClass="dialogGrid"
dynamic="true" draggable="true" resizable="false">
<p:outputPanel style="text-align:center;" layout="block">
<p:messages autoUpdate="true"/>
<ui:insert name="editContent">
Edit Content Here. Use 'selectedModel.whatever'
</ui:insert>
<p:panelGrid columns="3" styleClass="buttonGrid">
<ui:insert name="saveButton">
<p:commandButton iconPos="left" value="#{msg.save}"
rendered="#{'VIEW' != selectedModel.viewState}"
process="#widgetVar(#{uniqueId}_editDialog)"
action="#{adapterInjector.add(modelList, selectedModel)}"
update="#widgetVar(#{uniqueId}_itemsDataList) #widgetVar(#{uniqueId}_addButton) #widgetVar(#{uniqueId}_editDialog)"
oncomplete="if(!args.validationFailed) PF('#{uniqueId}_editDialog').hide()"
partialSubmit="true" validateClient="true">
</p:commandButton>
</ui:insert>
<p:commandButton iconPos="right" value="#{msg.cancel}"
process="#this" oncomplete="PF('#{uniqueId}_editDialog').hide()"
resetValues="true" partialSubmit="true">
</p:commandButton>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
This is an inserted component which has the required attribute
<p:selectOneMenu id="licenseCert"
value="#{selectedModel.selectedLicenseCert}" filter="true"
required="true">
<f:selectItem itemLabel="#{msg.selectOne}" itemValue=""
noSelectionOption="true" />
<f:selectItems value="#{licCert.allLicenseCertMap.entrySet()}"
var="entry" itemValue="#{entry.key}" itemLabel="#{entry.value}" />
</p:selectOneMenu>
</p:column>
Turns out this fixed the problem.
For best practice you should:
move the <h:form> inside the dialog
process the moved <h:form> in the save button.

Open PrimeFaces Dialog located in another .xhtml file

I have a number of questions that are related to each other so the title of question may not be appropriate. Sorry for this.
I want to have a p:inputText and p:commandButton in a p:dialog such that when the user presses that button or presses enter key the value entered in the
p:inputText will be saved in the database. To do this I followed this example http://www.primefaces.org/showcase/ui/dialogForm.jsf and it worked fine when I tried it in a seperate .xhtml file in which there were no other dialogs or command buttons.
<h:body>
<h:form id="form">
<p:commandButton id="showDialogButton" type="button" value="Show" onclick="PF('dlg').show()" />
<p:dialog header="Enter FirstName" widgetVar="dlg" resizable="false">
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{subjectController.attributeValue}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" update=":form:display :form:firstname" action="#{subjectController.saveUpdateSubjectAttributeValue}" oncomplete="PF('dlg').hide();"/>
<p:defaultCommand target="submitButton"></p:defaultCommand>
</p:dialog>
<p:outputPanel id="display" style="display:block;margin-top:10px;">
<h:outputText id="name" value="Hello #{subjectController.attributeValue}" rendered="#{not empty subjectController.attributeValue}"/>
</p:outputPanel>
</h:form>
</h:body>
The .xhtml file that I originally have contains a number of other dialogs and command buttons. When i used the same code in that file it does not work properly. By not working properly I mean to say that when enter key or submit button is pressed the value entered by the user is not set in the corresponding setter of the inputText in the managed bean. To call the setter before pressing the enter key or button I need to use p:ajax inside p:inputText tag. I tried to use p:ajax events such as "mouseout", "blur", "change" etc. They work for the submit button but not for the enter key. Then I tried "keypress" and "keyup" etc. They worked for both but the setter for the value in the p:inputText was called on each key press which was not desired.
My first question:
If the sample code is working fine in a separate file why doesn't it work when I have other dialogs or commandbuttons in the same file. In both the cases I am using the same managed bean. What is the difference?
Assuming that the problem may be caused using more than one dialogs in the same file, I thought of declaring these dialogs in separate files such that I have
A.xhtml , B.xhtml, C.xhtml pages which contain the actual content and whenever I need to open a dialog the required dialog is located in file such as dialog.xhtml. Being a beginner in JSF, Primefaces and Ajax I was confused about how to do this. Searching on the internet I found this post relevant PrimeFaces dialog lazy loading (dynamic="true") does not work?. But in this case, p:dialog is located on the same page but the content contained in this dialog is located in another file which is included using ui:include. I tried this but it shows the same behavior.
My Second Question:
Is there any way to programmatically open a dialog from another file e.g. if I have a p:commandButton in A.xhtml and p:dialog in the same file I can do this using
<p:commandButton id="submitButton" value="Submit" update=":form:display :form:firstname" action="#{subjectController.saveUpdateSubjectAttributeValue}" oncomplete="PF('dlg').hide();"/>
and in the corresponding subjectController I have
saveUpdateSubjectAttributeValue(){
RequestContext context = RequestContext.getCurrentInstance();
context.openDialog("openDialog");
// or
context.execute("openDialog");
}
But what if the "openDialog" is located in B.xhtml?
What I understand, I can use enclose p:dialog in a ui:composition (in B.xhtml) and and use ui:include in A.xhtml. But I am confused in how and where to call openDialog.open() or openDialog.hide()?
I've tried to replicate the behavior you posted here and I believe that the cause is probably somewhere else as mentioned by Yipitalp.
Anyway, here are the sample code I used that might do what you expect (Primefaces 4):
The Managed Bean
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;
#ManagedBean
#ViewScoped
public class DialogBean implements Serializable {
private String attribute1;
private String attribute2;
private String attribute3;
private String dlg;
public void openDialog() {
RequestContext context = RequestContext.getCurrentInstance();
context.execute("PF('" + dlg + "').show()");
}
public String getAttribute1() {
return attribute1;
}
public void setAttribute1(String attribute1) {
this.attribute1 = attribute1;
}
public String getAttribute2() {
return attribute2;
}
public void setAttribute2(String attribute2) {
this.attribute2 = attribute2;
}
public String getAttribute3() {
return attribute3;
}
public void setAttribute3(String attribute3) {
this.attribute3 = attribute3;
}
public String getDlg() {
return dlg;
}
public void setDlg(String dlg) {
this.dlg = dlg;
}
}
The view
Note that I use a different form for every dialog in the view.
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="dlg" value="Dlg:" />
<p:selectOneMenu id="dlg" value="#{dialogBean.dlg}" >
<f:selectItem itemLabel="dlg1" itemValue="dlg1" />
<f:selectItem itemLabel="dlg2" itemValue="dlg2" />
<f:selectItem itemLabel="dlg3" itemValue="dlg3" />
</p:selectOneMenu>
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" action="#{dialogBean.openDialog}"/>
<p:defaultCommand target="submitButton" />
</h:form>
<p:button id="showDialogButton1" value="Show 1" onclick="PF('dlg1').show();
return false;" />
<p:button id="showDialogButton2" value="Show 2" onclick="PF('dlg2').show();
return false;" />
<p:button id="showDialogButton3" value="Show 3" onclick="PF('dlg3').show();
return false;" />
<br />
<p:dialog header="Enter FirstName" widgetVar="dlg1" resizable="false">
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{dialogBean.attribute1}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" oncomplete="PF('dlg1').hide();"/>
<p:defaultCommand target="submitButton" />
</h:form>
</p:dialog>
<p:dialog header="Enter FirstName" widgetVar="dlg2" resizable="false">
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{dialogBean.attribute2}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" oncomplete="PF('dlg2').hide();"/>
<p:defaultCommand target="submitButton" />
</h:form>
</p:dialog>
<p:dialog header="Enter FirstName" widgetVar="dlg3" resizable="false">
<h:form>
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="firstname" value="Firstname:" />
<p:inputText id="firstname" value="#{dialogBean.attribute3}" />
</h:panelGrid>
<p:commandButton id="submitButton" value="Submit" oncomplete="PF('dlg3').hide();"/>
<p:defaultCommand target="submitButton" />
</h:form>
</p:dialog>
<p:outputPanel autoUpdate="true" style="border: 1px solid black; margin-top:10px;">
Value 1:
<h:outputText id="v1" value="#{dialogBean.attribute1}" />
<br />
Value 2:
<h:outputText id="v2" value="#{dialogBean.attribute2}" />
<br />
Value 3:
<h:outputText id="v3" value="#{dialogBean.attribute3}" />
</p:outputPanel>
I hope that will give you some clue!
I was able to solve major part of my problems using DialogFramework. I have a Menu.xhtml page, it contains p:tieredMenu in p:layoutUnit with position="north" using which I select which page to open. Depending on the selection, the p:layoutUnit with position="center" includes that page using ui:include. The Menu.xhtml page contains a h:form with id="form" inside h:body and everything else is placed inside this h:form. There are a number of pages that can be included inside the <p:layoutUnit position="center"> depending upon the selection. One of them is Person.xhtml(containing everything enclosed inside a ui:composition ). It contains a p:fieldset. Inside p:fieldset there are 3 p:dataTable. Outside this p:fieldset I have placed 3 p:contextMenu one for each of those datatables. Inside one of those p:contextMenu I have placed
<p:menuitem value="Update" actionListener="#{controller.updateAttributeValue}" />
and the corresponding function contains
public void updateAttributeValue(){
System.out.println("update attribute value");
RequestContext context = RequestContext.getCurrentInstance();
context.openDialog("selectCar2");
this.attributeValue = null;
}
selectCar2.xhtml contains the following code
<h:body>
<h:form>
<h:panelGrid id="updateAttributeValuePanel" columns="2" style="margin-bottom:10px">
<h:outputLabel value="Attribute Value " />
<p:inputText id="attributeValue" value="#{controller.attributeValue}" required="true" />
</h:panelGrid>
<p:commandButton id="saveUpdateAttributeValue" value="Submit" actionListener="#{controller.saveUpdateAttributeValue}"
/>
<p:commandButton id="cancelUpdateAttributeValue" value="Cancel "
action="#{controller.cancelUpdateAttributeValue}"
/>
<p:defaultCommand target="saveUpdateAttributeValue" />
</h:form>
</h:body>
The corresponding save function is as follows
public void saveUpdateAttributeValue(){
RequestContext context = RequestContext.getCurrentInstance();
System.out.println("this.attributevalue = " + this.attributeValue);
////save value in database
this.attributeValue = null;
context.update(":form:resourceAttributeValueDataTable");
//also tried context.update("resourceAttributeValueDataTable");
context.closeDialog(this.attributeValue);
}
and
public void cancelUpdateAttributeValue(){
RequestContext context = RequestContext.getCurrentInstance();
context.closeDialog(this.attributeValue);
System.out.println("cancel update attribute value");
this.attributeValue = null;
System.out.println("this.attributevalue = " + this.attributeValue);
}
The dialog opens and the value is successfully saved in the database. The only problem now is that the corresponding datatable is not updated and I need to refresh the page to see the updated value. previously my dialog was also in the same page outside the p:fieldset and I was not using h:form inside dialog so I was updating the datatable as
<p:commandButton id="saveUpdateAttributeValue" value="Submit" actionListener="#{controller.saveUpdateAttributeValue}"
update = ":form:attributeValueDataTable "/>
But now they are in two different files and two different forms so I am not sure how to update in this case? I have tried to use
context.update(":form:resourceAttributeValueDataTable");
//or
context.update("resourceAttributeValueDataTable");
but the datatable is not updated. Any help will be highly appreciated.

p:ajax update not working after clicking commandlink

I have a jsf page that adds an order from a client.
All works fine except when I click the commandLink to show the p:dialog to add a new client the update on the "reste" inputtext stop working (even if I close the p:dialog without adding the new client) :
Clients List :
<strong>Client :</strong><
<p:autoComplete
id="client"
value="#{venteSolaireBean.client}"
completeMethod="#{venteSolaireBean.autocompleteClient}"
var="item"
itemLabel="#{item.nom} #{item.prenom}"
itemValue="#{item}"
converter="#{venteSolaireBean.clientConverter}"
dropdown="true"
scrollHeight="200" >
</p:autoComplete>
Link to a p:dialog to add a new Cleint :
<p:commandLink onclick="dlgClient.show()" immediate="true">
<img src="images-main/add-icon.gif" border="0" alt="Add Client" class="img-action"/>
</p:commandLink>
Three p:inputtext items with ajax behavior :
<strong>Montant :</strong>
<p:inputText value="#{venteSolaireBean.venteSolaire.montant}">
<p:ajax event="keyup" update="reste" listener="#{venteSolaireBean.calcul}" />
</p:inputText>
<strong>Avance :</strong></td>
<p:inputText value="#{venteSolaireBean.venteSolaire.avance}">
<p:ajax event="keyup" update="reste" listener="#{venteSolaireBean.calcul}" />
</p:inputText>
<strong>Reste :</strong></td>
<p:inputText id="reste" value="#{venteSolaireBean.venteSolaire.reste}">
</p:inputText>
The venteSolaireBean.calcul function to execute with the listener :
public void calcul() {
venteSolaire.setReste(venteSolaire.getMontant() - venteSolaire.getAvance());
}
I checked by logging the calcul() function and I'm sure it was invoked and the value giving to setReste() is correct.
I don't see why inputtext didn't update.
please help.
I think that there are some problems with the validation. As immediate=true often leads to such problems and you are not using any primefaces-functionality on the button to show the dialog, you should replace the p:commandButton with a plain HTML button to show the "add client"-dialog.

Resources