[RESOLVIDO] Renderização do h:outputText em sincronia com a modificação de um h:inputText

7 respostas
V

Olá pessoal,

Dado o seguinte fragmento:

<h:outputLabel value="Cliente:" for="inpCliPed" />
<h:inputText id="inpCliPed" value="#{pedido.pedido.cliente}"
  style="width : 70px">
  <f:converter converterId="clienteConverter" />
  <a4j:support event="onchange" reRender="outCliPed" />
</h:inputText>
<h:outputText id="outCliPed"
  value="#{pedido.pedido.cliente.display}" />

Está ocorrendo o seguinte: quando o componente inpCliPed perde o foco, é atualizado a informação do componente outCliPed. Ok está como eu quero.
O problema é que ocorre um delay entre o momento que entre a perda de foco do inpCliPed e o momento em que o outCliPed é atualizado, coisa de 3 seg. Neste meio tempo o outCliPed fica exibindo a informação relativa ao valor anterior de inpCliPed.
Gostaria que isso não ocorre-se, então pensei em fazer com que no momento em que iniciei a modificação do campo inpCliPed (ou seja no evento onkeyup, por exemplo) o componente ficasse invisível ou em branco. Talvez com a propriedade rendered do outCliPed, mas queria fazer isso direto no cliente, não no servidor.

Uso JSF com RichFaces.

7 Respostas

thiago.correa

Troque o onchange para onkeyup ou onkeydown

V

Se eu fizer isso o delay de 3 seg vai ocorrer a cada caracter que eu digitar, foi por isso que usei o onchange.

thiago.correa

Mas o problema é o delay ou quando o campo perder o foco o conteúdo é diferente do digitado?!

Sugestão, se está em busca de performance, não use ajax para copiar o que foi digitado! Se o teu projeto permitir use javascript mesmo para isso

<html>
	<head>
		<style>
			div {display:inline;}
		</style>
	</head>
	<body>
		<input type="text" onkeyup="document.getElementById('div1').innerHTML = this.value;"
		<div id="div1"></div>
	</body>
</html>

Mais prático mais rápido e não “sobrecarrega” o servidor!

V

Tiago, a sua solução não resolve meu problema porque o valor que é atribuído ao outCliPed (um outputText) não é o valor do componente inpCliPed (um inputText).

O valor atribuído ao outputText é outro atributo do objeto que está vinculado ao inpCliPed, cuja valor é atualizado após a execução do converter que está ligado este inputText.

Sim, o delay decorrente desta operação é um problema, mas não é o que eu quero resolver (claro que isso seria bom, mas é mais complicado pois tem consulta a banco de dados e tals). O problema que eu quero resolver é o fato de que durante a execução do converter o oupputText fica com o valor anterior e o usuário tem a impressão de que ele não foi atualizado até que termine o processo.
O que eu gostaria então de fazer é não dar margem a está visão do usuário, ou seja, não quero manter o valor anterior no outputText durante o processo. Bastaria por exemplo que eu conseguisse ocultar o outputText assim que o usuário iniciar a modificação do valor do inputText (não pode ser ao receber foco, pois ele pode não alterar nada, logo não haverá processamento).

Não sei se consegui me fazer entender.

thiago.correa

Bom, se via JS não é possível e o delay não seria bom, coloque uma mensagem de “Atualizando” ao lado do campo a ser atualizado (ou até mesmo no lugar) para isso utilize os atributos onSubmit onComple da tag a4j:support! Não sana o delay do servidor, porém, indica ao usuário que algum processamento está sendo feito!

V

Poderia me dar um exemplo de como fazer isso: alterar a propriedade value do meu outputText no onsubmit para “Atualizando” e no onComplete para “#{pedido.pedido.cliente.display}”?

Tipo, imagino que seria uma função javascript que eu poderia reutilizar para outros outputText. Mas não manjo de javascript.

Agradeço.

V

Fiz uma função javascript assim:

<script language="JavaScript">  
function SetValue(elementId, valueTo){
    document.getElementById(elementId).value = valueTo;
}
</script>

e na página

<h:outputLabel value="Cliente:" for="inpCliPed" />
<h:inputText id="inpCliPed" immediate="true"
  value="#{pedido.pedido.cliente}" style="width : 70px">
  <f:converter converterId="clienteConverter" />
  <a4j:support event="onchange" 
      onsubmit="SetValue('frmCadPedido:outCliPed', 'Carregando...')" 
      oncomplete="SetValue('frmCadPedido:outCliPed', '#{pedido.pedido.cliente.display}')" 
      reRender="outCliPed"/>
</h:inputText>
<h:outputText id="outCliPed" value="#{pedido.pedido.cliente.display}"/>

Mas não teve o comportamento desejado.

Então fiz de um outro modo que atende a minha necessidade usando o componente status do ajax

<h:outputLabel value="Cliente:" for="inpCodCliPed" />
<h:inputText id="inpCodCliPed" value="#{pedido.pedido.cliente}"
  style="width : 70px">
  <f:converter converterId="clienteConverter" />
  <a4j:support event="onchange" status="statusCodCliPed" reRender="outCodCliPed"/>
</h:inputText>
<h:outputText id="outCodCliPed" value="#{pedido.pedido.cliente.display}" />
<a4j:status id="statusCodCliPed" forceId="true"
  startText="Atualizando"
  stopText="" />

Desta forma apesar de a informação no outputText ficar desatualizada até o final da operação o usuário terá uma informação de que esta aguarda atualização. Ficou legal.

Criado 22 de setembro de 2010
Ultima resposta 23 de set. de 2010
Respostas 7
Participantes 2