Ola,
Estou tendo o seguinte problema utilizando JSF, o problema foi detectado durante a implementação utilizando PrimeFaces, no entanto foi possível isolar o mesmo em um ambiente JSF(Mojarra v2.1.7). Segue abaixo a exemplificação do problema.
Em um formulário tenho os campos [b]A[/b] e [b]B[/b]. O [b]campo B[/b] é preenchido segundo uma entrada determinada no campo [b]campo A[/b]. Assim ao informar [u]"1"[/u] no [b]campo A[/b] é disparado um evento [i]onChange[/i] que preenche o [b]campo B[/b] com [b]"foo"[/b], informado [u]"2"[/u] é preenchido com [b]"bar"[/b].
Dessa forma é possível testar alternando os valores no [b]campo A[/b] entre "1" e "2", ao sair do campo o valor do [b]campo B[/b] será alterado por [i]#{testeHelper.doProcessar}[/i] e o ajax se encarrega de recarregar o [b]campo B[/b].
Importante notar que o [b]campo A[/b] é obrigatório([i]required="true"[/i]) e o [b]campo B[/b] [b]não[/b] é obrigatório.
[u][b][color=red] O PROBLEMA [/color][/b][/u]
Deixando o [b]campo A[/b] em branco e pressionando [b]Submit[/b] temos um erro de obrigatoriedade:
[color=red]Erro: sourceId=form:A[severity=(ERROR 2), summary=(form:A: Erro de validação: o valor é necessário.), detail=(form:A: Erro de validação: o valor é necessário.)][/color][size=9][i] * mensagem no console[/i][/size]
Neste momento, caso o [b]campo A[/b] seja preenchido e o evento [i]onChange[/i] disparado, o [b]campo B[/b] não é mais atualizado com o novo valor, o mesmo retorna o ultimo valor do [b]campo B[/b] antes do [i]submit[/i].
Através do log no console é possível verificar que o método invocado no [i]onChange[/i] é executado.
O funcionamento perfeito só é restaurado recarregando a página ou pressionando algum dos botões do formulário. Outro ponto importante é que, colocando o [b]campo B[/b] como obrigatório o problema não ocorre.
XHTML[color=darkblue] [/color]
<?xml version="1.0"?>
<!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:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head/>
<h:body>
<h:form id="form">
# versao: 1<br />
<!-- A -->
<h:outputLabel value="A:" />
<h:inputText id="A" value="#{testeHelper.fieldA}" required="true"
valueChangeListener="#{testeHelper.doProcessar}">
<f:ajax event="change" render='fieldB'/>
</h:inputText>
<!-- B -->
<h:outputLabel value="B:" />
<h:inputText id="fieldB" required="false" value="#{testeHelper.fieldB}" />
<!-- Buttons -->
<h:commandButton value="Submit" update="form" />
<h:commandButton value="Clear B" actionListener="#{testeHelper.clearFieldB}" />
</h:form>
</h:body>
</html>
JAVA[color=darkblue] [/color]
@ManagedBean(name = "testeHelper")
@SessionScoped
public class TesteHelper implements Serializable {
private static Logger log = Logger.getLogger(TesteHelper.class.getName());
private static final long serialVersionUID = 1704375637853717337L;
private String fieldA = null;
private String fieldB = null;
public TesteHelper(){
log.info("TesteHelper started");
}
public void doProcessar(ValueChangeEvent event){
log.info("FIELD_A [" + getFieldA() + "] OLD [" + event.getOldValue() + "] NEW [" + event.getNewValue() + "] FASE JSF [" + event.getPhaseId() + "]");
if ("1".equals(event.getNewValue())){
setFieldB("foo");
log.info("Processing field 1");
} else if ("2".equals(event.getNewValue())){
setFieldB("bar");
log.info("Processing field 2");
} else {
log.info("No Processing field found, clear process will be invoke!");
clearFieldB();
}
}
public void clearFieldB(){
setFieldB(null);
log.info("Clearing field B");
}
public String getFieldA() {
return fieldA;
}
public void setFieldA(String fieldA) {
this.fieldA = fieldA;
}
public String getFieldB() {
return fieldB;
}
public void setFieldB(String fieldB) {
this.fieldB = fieldB;
}
}