Dúvida em JSF: selectOneMenu master-detail

3 respostas
p1Lagz89

Olá,

Pessoal, olhe o que eu estou tentando fazer e meus problemas:
Tenho uma página (escopo request) onde há um selectOneMenu que lista várias entidades Message (fiz o Conversor).
Ao usuário clicar em uma delas, é apresentado os detalhes dessa Message , para que ele edite (Selects, Checkbox, e uma textarea).
Acontece que ao usuário selecionar a Message e carregar os detalhes na tela, ao fazer uma alteração e salvar, não acontece nada, pois o objeto Message é nulo.
Daí alguem pode falar , claro, é porque a pagina ta no escopo request.
Eu coloquei aquele componente t:saveState pra salvar o objeto Message. Aí que ta o problema:
quando eu mudo o Message, ele salva o primeiro Message que eu escolhi e fica com ele até o fim
(o saveState faz isso). Não tem uma forma de ele “trancar” esses dados até eu mudar o valor do Select Somente (para que eu aproveite os dados no submit, mas não fique com os mesmos dados pra sempre) ?

Do jeito que ta eu mudo o select e ele persiste os dados do 1º Message pra sempre na arvore de componentes!!!

Alguém ja passou por isso?

Teria alguma solução alternativa?

Muito Obrigado.

3 Respostas

p1Lagz89

ps:
Message é uma entidade qualquer como Pessoa,
não tem nada a ver com h:message

p1Lagz89

Còdigo do select do componente principal

<select id="selectMessage" class="combos" 
	jsfc="h:selectOneMenu" converter="messageConverter" 
	valueChangeListener="#{MessageManagerPageForm.updateForm}" 
	value="#{MessageManagerPageForm.message}" 
	onchange="this.form.submit()">
	
	<f:selectItems value="#{MessageManagerPageForm.allMessages}" />
</select>

código de um dos componentes “detalhe”

<input type="checkbox" jsfc="h:selectBooleanCheckbox"  
name="checkbox5" value="#{MessageManagerPageForm.message.highlighted}" />

código do botão Salvar

<input  type="submit" jsfc="h:commandButton"
value="Save" id="savebt"
	action="#{MessageManagerPageForm.actionSalvar}">
</input>

ps: Estou usando facelets, mas isso não tem nada a ver

gilliard_santos

Olá, eu também tive o mesmo problema e consegui resolver da seguinte forma…
coloque seu componente como immediate=“true” e no seu metodo updateForm (que é o valueChangeListener) force “resetar” os componentes que voce quer atualizar ao mudar o valor do combo.
Seguem algns metodo auxiliares para voce resetar os valores da arvore de componentes:

private void resetChild(List childList)
	  {
	    for(int i=0;i&lt;childList.size();i++)
	    {
	      UIComponent component=(UIComponent)childList.get(i);
	      try
	      {
	        UIInput input = (UIInput) component;
	        input.setSubmittedValue(null);
	      }catch(Exception ex)
	      {
	        
	      }      
	      List childList2=component.getChildren();
	      resetChild(childList2);
	    }
	  }
	 
	protected void resetTree()
	{
	    FacesContext facesContext=FacesContext.getCurrentInstance();
	    UIViewRoot viewRoot= facesContext.getViewRoot();
	    List childList=viewRoot.getChildren();
	    resetChild(childList);
	}
	
	protected void resetTree(String clientId)
	{
		resetTree(findComponentInRoot(clientId));
	}
	
	protected void resetTree(UIComponent component)
	{
		resetChild(component.getChildren());
	}
	
	
	public static UIComponent findComponent(UIComponent base, String id) {

		// Is the "base" component itself the match we are looking for?
		if (id.equals(base.getId())) {
			return base;
		}

		// Search through our facets and children
		UIComponent kid = null;
		UIComponent result = null;
		Iterator kids = base.getFacetsAndChildren();
		while (kids.hasNext() && (result == null)) {
			kid = (UIComponent) kids.next();
			if (id.equals(kid.getId())) {
				result = kid;
				break;
			}
			result = findComponent(kid, id);
			if (result != null) {
				break;
			}
		}
		return result;
	}

	public static UIComponent findComponentInRoot(String id) {
		UIComponent ret = null;

		FacesContext context = FacesContext.getCurrentInstance();
		if (context != null) {
			UIComponent root = context.getViewRoot();
			ret = findComponent(root, id);
		}

		return ret;
	}

Com esses metodos voce poe tanto resetar a arvore inteira quanto apenas a arvore a partir de um componente passando o mesmo ou o clientId dele.

Nos fóruns pela net existem outras solucoes para esse problema, mas essa me pareceu simples e transparente quanto ao que esta sendo feito.
Espero que resolva pra voce também.
>

Criado 21 de novembro de 2006
Ultima resposta 26 de nov. de 2006
Respostas 3
Participantes 2