JSF - reRender não funciona

Fala feras :smiley:

Tenho um reRender que deveria renderizar um painel que contem um div e um dataTable. Usei o a4j:commandButton e não resolveu.

					<tr>
						<td>&nbsp;</td>
						<td><a4j:commandButton action="#{inputDelegate.informarHorariosRegistrados}" value="Registrar Horário" reRender="horariosRegistrados"/></td>
					</tr>
				</table>
				<br/>
				<rich:separator width="100%"></rich:separator>
				<br/>
				<a4j:outputPanel id="horariosRegistrados" rendered="#{inputMBean.consulta}">
					<div align="center">
						<p><h:outputLabel value="Nome: " for="nome" styleClass="labelInput" />
							<h:outputText value="#{inputMBean.funcionarioTO.nome}" id="nome"/>
						</p>	
						<br/>
						<p><h:outputText value="Horários Registrados" styleClass="labelInput"/> </p>
						<br/>
						
					</div>
				</a4j:outputPanel>

			</a4j:form>
	public void informarHorariosRegistrados(){
		InputMBean inputMBean = (InputMBean)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("inputMBean");
		FuncionarioService funcionarioService = ServiceFactory.getFuncionarioService();
		inputMBean.setFuncionarioTO(funcionarioService.getFuncionarioTO(inputMBean.getFuncionarioTO().getRg(), inputMBean.getFuncionarioTO().getSenha()));
		inputMBean.consulta = true;
	}

O estranho é não dar nenhuma exceção e os dados são buscados corretamente. O que pode estar ocorrendo?

Abs

Confira no html gerado se o componente horariosRegistrados não foi renomeado com o nome do form.

Ex: form:horariosRegistrados

Use

<a4j:outputPanel ajaxRendered="true">
      <h:messages/>
</a4j:outpurPanel>

para ver se há algo de errado!

Olá thiagowig,

Respondendo de uma maneira direta, você não pode reRenderizar um componente na qual possua o atributo rendered dinâmico, ou seja, ele não pode possuir EL para definir seu estado. No seu caso, o componente a4j:outputPanel.

Para resolver isso reRenderize o componente pai do a4j:outputPanel. Lembrando que este componente pai não pode ter o atributo rendered dinâmico, ou seja, ele sempre precisa ser renderizado.

Abraços e boa sorte.

Se eu der um F5 na tela, ele carrega o que deveria ser exibido via ajax.

Não tem mensagem de erro no ajax.

[quote=rponte]Olá thiagowig,

Respondendo de uma maneira direta, você não pode reRenderizar um componente na qual possua o atributo rendered dinâmico, ou seja, ele não pode possuir EL para definir seu estado. No seu caso, o componente a4j:outputPanel.

Para resolver isso reRenderize o componente pai do a4j:outputPanel. Lembrando que este componente pai não pode ter o atributo rendered dinâmico, ou seja, ele sempre precisa ser renderizado.

Abraços e boa sorte.[/quote]

Boa rponte, problema resolvido :slight_smile:

rponte,

e se eu quiser usar um rendered dinamico? não tem como usar com o reRender?

@rponte parabens pela contribuiçao!!

realmente sua afirmação procede, sofri muito com este problema e o corrigia da maneira que vc citou, porem ninguem nunca soube me explicar o “pq”.

Poderia informar a fonte dessa informação ?

ah parabens pelo blog

grande abrasssssss

Oi padcoe,

[quote=padcoe]rponte,
e se eu quiser usar um rendered dinamico? não tem como usar com o reRender?[/quote]

Você pode usar sim um rendered dinâmico e ao mesmo tempo utilizar o reRender após um evento para “repintar” este mesmo componente. Mas isso provavelmente falhará quando o componente sumir (rendered=false). Enquanto o rendered for avaliado como true você não terá este problema. Por isso o ideal é evitar este cenário e sempre “repintar” um componente pai qualquer. No caso do Richfaces o a4j:outputPanel é uma excelente escolha como componente pai, caso contrário um h:panelGroup resolve.

Olá renanreismartins,

[quote=renanreismartins]@rponte parabens pela contribuiçao!!

realmente sua afirmação procede, sofri muito com este problema e o corrigia da maneira que vc citou, porem ninguem nunca soube me explicar o “pq”.

Poderia informar a fonte dessa informação ?

ah parabens pelo blog

grande abrasssssss[/quote]

Vou tentar explicar o motivo, espero que fique claro.

Não é interessante tentar reRenderizar um componente com rendered dinâmico pois quando o atributo rendered é avaliado para false o componente (código XHTML) não aparece na árvore DOM da página. Sendo, após um evento AJAX o código JavaScript do Richfaces responsável por atualizar o bloco de código (onde se encontraria o componente) não consegue achar a posição exata para reRenderizar na página, já que o código XHTML do componente não existe na árvore DOM. Então no final ele acaba simplesmente não fazendo nada.

Por isso, quando você reRenderiza um componente pai qualquer (que sempre tem rendered avaliado para true) o Richfaces consegue encontrar a posíção exata da página, e como o componente com rendered dinâmico é um nó (filho) do componente pai ele também é “repintado”.

Enfim, tudo ocorre normalmente no lado servidor. O problema mesmo ocorre no lado cliente (browser). Você pode observar isso com o Firebug, se achar necessário.
Espero que tenha ficado claro.

Sobre a fonte da informação, eu estou quase certo que eu li na documentação do Richfaces. Lá ele explica exatamente este cenário. Se não me engano, a documentação do Trinidad também comenta sobre isso. Ou seja, é um problema recorrente com vários, se não todos, os conjuntos de componentes AJAX.

Abraços.

Aproveitando, acabei achando alguns trechos na documentação do Richfaces:

Aqui (Topico 5.5):

E aqui (Topico 5.6.1):

Enfim, espero que ajude.

Estou com um problema sera que alguém pode dar uma luz, quando dou um reRender no outputPane o inputText não funciona, não pega os dados digitados, o codigo seguinte é uma parte do codigo

                            <h:outputLabel value="Tem advogado particular:"/>
                            <a4j:region >
                                <h:selectOneRadio value="#{testeBean.dadosTecnicos.isAdvogado}" id="advogado" label="advogado">
                                    <f:selectItem itemLabel="sim" itemValue="true"  />
                                    <f:selectItem itemLabel="não" itemValue="false"  />
                                    <a4j:support event="onchange" reRender="pl" ajaxSingle="true"/>
                                </h:selectOneRadio>
                            </a4j:region>
                             <a4j:outputPanel id="pl" >
                                <h:outputLabel value="Nome:" rendered="#{testeBean.dadosTecnicos.isAdvogado}"/>
                                <h:inputText value="#{testeBean.dadosTecnicos.nomeAdvogado}" id="nomeAdvogado" label="nome do advogado"
                                         styleClass="rich-input-text input" rendered="#{testeBean.dadosTecnicos.isAdvogado}"/>
                              </a4j:outputPanel>

Jogue o <a4j:outputPanel id=“pl” > dentro de um <h:panelGroup> que resolve.

Depois de muito tempo sem blogar eu acabei tirando um post sobre o assunto da minha lista de drafts, http://www.rponte.com.br/2010/12/01/problema-do-rendered-dinamico-com-jsf/ .

Espero que com o post o problema e a solução fiquem mais claros.

Um abraço.

rponte, é isso mesmo!
Certas coisas a gente tem idéia ou sabe, mas as vezes deixa de responder a um colega ou não, acaba respondendo mas sem se expressar devidamente.
Você foi bem claro!
O post no blog ficou ótimo tmb.

Agora só falta algum modera marcar como “resolvido”.
:stuck_out_tongue:

Bom dia sei que o post é antigo, mas é justamente o erro que tenho…

fiz conforme você explicou, aliás parabéns pela explicação… mas mesmo assim não sei o que houve de errado, segue o código:

[code]<?xml version="1.0" encoding="ISO-8859-1"?>

SM2 - SOLUÇÃO MÓVEL DE MANUTENÇÃO - WEB
		<a4j:outputPanel id="Panel1">
			<h:outputText value="teste" />
			<a4j:commandButton value="teste" reRender="txtValue, aPanel2"
				action="#{testeMB.teste}" ajaxSingle="true">
			</a4j:commandButton>
		</a4j:outputPanel>

		<rich:spacer width="100%" height="20" style="color:blue"></rich:spacer>

		<h:outputLabel value="#{testeMB.render}" id="txtValue"/>

		<a4j:outputPanel id="aPanel2">
			<h:panelGroup id="Panel2" rendered="#{testeMB.render}">
				<h:outputText value="#{testeMB.mensagem}"/>
				<a4j:commandButton value="teste2" />
			</h:panelGroup>
		</a4j:outputPanel>

	</a4j:form>
</f:view>

</ui:composition>

[/code]
package br.com.sigga.test;

public class TesteMB {
	
private String mensagem = null;  
private boolean render;


public boolean isRender() {
	return render;
}

public void setRender(boolean render) {
	this.render = render;
}

public void teste() {  
	render = true;
    setMensagem("Funcionou!!");  
}  

/** 
 * @return the mensagem 
 */  
public String getMensagem() {  
    return mensagem;  
}  

/** 
 * @param teste the mensagem to set 
 */  
public void setMensagem(String mensagem) {  
    this.mensagem = mensagem;  
}  
}  

Conforme imprimi na tela o valor está true, mas não renderiza o panel de baixo … Você sabe oq ue pode ser?

Bom dia sei que o post é antigo, mas é justamente o erro que tenho…

fiz conforme você explicou, aliás parabéns pela explicação… mas mesmo assim não sei o que houve de errado, segue o código:

[code]<?xml version="1.0" encoding="ISO-8859-1"?>

SM2 - SOLUÇÃO MÓVEL DE MANUTENÇÃO - WEB
		<a4j:outputPanel id="Panel1">
			<h:outputText value="teste" />
			<a4j:commandButton value="teste" reRender="txtValue, aPanel2"
				action="#{testeMB.teste}" ajaxSingle="true">
			</a4j:commandButton>
		</a4j:outputPanel>

		<rich:spacer width="100%" height="20" style="color:blue"></rich:spacer>

		<h:outputLabel value="#{testeMB.render}" id="txtValue"/>

		<a4j:outputPanel id="aPanel2">
			<h:panelGroup id="Panel2" rendered="#{testeMB.render}">
				<h:outputText value="#{testeMB.mensagem}"/>
				<a4j:commandButton value="teste2" />
			</h:panelGroup>
		</a4j:outputPanel>

	</a4j:form>
</f:view>

</ui:composition>

[/code]
package br.com.sigga.test;

public class TesteMB {
	
private String mensagem = null;  
private boolean render;


public boolean isRender() {
	return render;
}

public void setRender(boolean render) {
	this.render = render;
}

public void teste() {  
	render = true;
    setMensagem("Funcionou!!");  
}  

/** 
 * @return the mensagem 
 */  
public String getMensagem() {  
    return mensagem;  
}  

/** 
 * @param teste the mensagem to set 
 */  
public void setMensagem(String mensagem) {  
    this.mensagem = mensagem;  
}  
}  

Conforme imprimi na tela o valor está true, mas não renderiza o panel de baixo … Você sabe oq ue pode ser?