Reputation: 6680
I have a Jsf page with a fragment with <p:selectOneMenu/>
(Prime faces) and an Ajax associated with it. It have the default select item "--- Select One ---" and others items that were created dynamically.
This field is required, so if users submit the form without select, the page show a error message.
The problem occurs when I select one of this others options and go back selecting "--- Select One ---" again. Then the page shows the required field message, even before I submit the form. I try different ways of immediate
in <p:ajax>
and <p:selectOneMenu>
tags but none of them has the expected behavior.
The <p:messages>
is declared as below:
-- list.xhtml
<p:messages id="messages" autoUpdate="true" closable="true" escape="false" />
<.... include fragment.xhtml ....>
And the fragment:
-- fragment.xhtml
<p:selectOneMenu id="selectTipoCarro"
value="#{carroBean.carro.tipoCarroEnum}"
required="true">
<f:selectItems value="#{carroBean.listaSelectItemTipoCarroInclusao}" />
<p:ajax update="outputInicioVigenciaWrapper outputLabelCalendarInicioVigenciaWrapper"
listener="#{carroBean.aoMudarTipoCarro}" />
</p:selectOneMenu>
<h:panelGroup id="outputLabelCalendarInicioVigenciaWrapper">
<h:outputLabel id="outputLabelCalendarInicioVigencia"
rendered="#{carroBean.edicaoDataInicioVigenciaDisponivel}"
for="calendarInicioVigencia">
<span>*
#{labels['carro.inicio.vigencia']}: </span>
<p:calendar id="calendarInicioVigencia"
value="#{carroBean.carro.dataInicioVigencia}"
showOn="button"
pattern="dd/MM/yyyy" mask="true"
required="true"/>
</h:outputLabel>
</h:panelGroup>
<h:panelGroup id="outputInicioVigenciaWrapper">
<h:outputLabel for="outputInicioVigencia"
rendered="#{not carroBean.edicaoDataInicioVigenciaDisponivel}">
<span aria-live="polite">
<h:outputText id="outputInicioVigencia"
value="#{carroBean.carro.dataInicioVigencia}"
styleClass="dataFormat"
</h:outputText>
</span>
</h:outputLabel>
</h:panelGroup>
private SelectItem obterSelectItemSelecione() {
SelectItem selectItem = new SelectItem("", "-- Select One --");
return selectItem;
}
private void preencherListaSelectItemTipoCarro(List<SelectItem> select, TipoCarroEnum[] tiposCarrosConsiderados) {
select.clear();
select.add(obterSelectItemSelecione());
for (TipoCarroEnum tipoCarro : tiposCarrosConsiderados) {
select.add(new SelectItem(tipoCarro, tipoCarro.getNome()));
}
}
public void aoMudarTipoCarro() {
getCarro().setDataInicioVigencia(carroService.obterProximaDataInicioVigenciaDisponivel(getCarro().getTipoCarroEnum()));
}
Upvotes: 3
Views: 3286
Reputation: 31651
That's the expected behaviour. When adding a p:ajax
tag to your p:selectOneMenu
you make the value be processed everytime the user changes the input, so it will be validated and rejected if you mark it as required
. My favourite workaround for this cases is to include a request param in the button to submit the whole form and check for it in the required
attribute. That's it:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:comp="http://java.sun.com/jsf/composite/comp"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head />
<h:body>
<h:form>
<p:messages autoUpdate="true" />
<p:selectOneMenu value="#{val}"
required="#{param['validate']}">
<p:ajax event="change" />
<f:selectItem itemLabel="None" noSelectionOption="true" />
<f:selectItem itemLabel="val1" itemValue="val1" />
</p:selectOneMenu>
<p:commandButton value="Submit" ajax="false">
<f:param name="validate" value="true" />
</p:commandButton>
</h:form>
</h:body>
</html>
See also:
Upvotes: 4
Reputation: 6040
Explanation
This happens because you have a p:messages
component with autoUpdate
set to true and you have attached p:ajax
to your selectOneMenu so anytime your value changes, p:messages
is updated. Therefore, due to the use of required="true"
an error messages is shown as soon as you have selected "--- Select One ---".
Solution
ignoreAutoUpdate="true"
to your p:ajax
orautoUpdate="true"
if not necessaryUpvotes: 2