dúvida em uso de a4j

caros,

Em meu projeto tenho uma página jsp com 4 combos. o primeiro é alimentado automaticamente quando a página é carregada, o segundo tem que ser alimentado a partir da seleção do primeiro, o terceiro a partir da seleção no segundo e o quarto a partir da seleção no terceiro. É uma implementação para filtrar registros em uma tabela genérica no banco de dados e, por enquanto, é a página mais complicada no meu projeto.

Porém não consigo submeter a requisição para o que o managed bean carregue os valores do próximo combo. Alguma idéia de como resolver isso?

Obrigado desde já,
Gustavo

O trecho da página jsp que contém os combos e a tentativa de implementação do é:

<rich:columnGroup>
	<rich:column width="50%">
		<h:outputText
			value="#{bundle['anamanRegisterServiceJSP.entity']}"></h:outputText>
	</rich:column>
	<rich:column>
		<rich:comboBox
		        id="entityDropDown"
			defaultLabel="#{bundle['anamanRegisterServiceJSP.selectEntity']}"
			width="300"
			listHeight="100px"
			value="#{anamanRegisterServiceMB.selectedEntity}"
			immediate="true"
			>
		<f:selectItems value="#{anamanRegisterServiceMB.entities}" />
		<a4j:support event="onchange"
			 immediate="true"
			 action="#{anamanRegisterServiceMB.entityCL}"
			 ajaxSingle="true"
			 reRender="typeDropDown,areaDropDown" />
		</rich:comboBox>
	</rich:column>
</rich:columnGroup>
<rich:columnGroup>
	<rich:column width="50%">
		<h:outputText value="#{bundle['anamanRegisterServiceJSP.type']}"></h:outputText>
	</rich:column>
	<rich:column>
		<rich:comboBox
			id="typeDropDown"
			defaultLabel="#{bundle['anamanRegisterServiceJSP.selectType']}"
			width="300" 
			listHeight="100px"
			value="#{anamanRegisterServiceMB.selectedRefType}">
		<f:selectItems value="#{anamanRegisterServiceMB.refTypes}" />
		<a4j:support event="onchange"
			 immediate="true"
			 actionListener="#{anamanRegisterServiceMB.typeCL}"
			 ajaxSingle="true"
			 action="#{anamanRegisterServiceMB.refTypes}"
			 reRender="areaDropDown" />
		</rich:comboBox>
	</rich:column>
</rich:columnGroup>

<rich:columnGroup>
	<rich:column width="50%">
		<h:outputText value="#{bundle['anamanRegisterServiceJSP.area']}"></h:outputText>
	</rich:column>
	<rich:column width="50%">
		<rich:comboBox
 			id="areaDropDown"
			defaultLabel="#{bundle['anamanRegisterServiceJSP.selectArea']}"
			width="300"
			listHeight="100px"
			value="#{anamanRegisterServiceMB.selectedRefArea}"
			immediate="true"
			>
		<f:selectItems value="#{anamanRegisterServiceMB.refAreas}" />
		<a4j:support event="onchange"
			 immediate="true"
			 actionListener="#{anamanRegisterServiceMB.areaCL}"
			 ajaxSingle="true"
			 action="#{anamanRegisterServiceMB.refAreas}"
			 />
		</rich:comboBox>
	</rich:column>
</rich:columnGroup>

e o managed bean está definido assim:

package anaman.mb;

import java.util.ArrayList;
import java.util.List;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import anaman.core.input.AnamanRegisterService;
import anaman.model.AnamanRegister;
import anaman.model.AnamanRegisterTypeDTO;

public class AnamanRegisterMB {
	// Init
	// ---------------------------------------------------------------------------------------
	private AnamanRegisterService ars = AnamanRegisterService.getInstance();

	private List<SelectItem> entities;
	private String selectedEntity;
	
	private List<SelectItem> refTypes;
	private String selectedRefType;
	
	private List<SelectItem> refAreas;
	private String selectedRefArea;
	
	//private AnamanRegisterService selectedItem;
	
	// Bindings
	//private  typeBinding;
	
	
	// Actions
	// ------------------------------------------------------------------------------------


	
	// Getters
	// ------------------------------------------------------------------------------------

	public List<SelectItem> getEntities() {
		List<SelectItem> entities = new ArrayList<SelectItem>();
		List<AnamanRegister> entityList = ars.getRegisterEntityList();
		for(AnamanRegister entity : entityList) {
			entities.add(new SelectItem(entity.getRegisterEntity()));
		}
		return entities;
	}

	/**
	 * @return the selectedEntity
	 */
	public String getSelectedEntity() {
		return selectedEntity;
	}

	public List<SelectItem> getRefTypes() {
		List<SelectItem> refTypes = new ArrayList<SelectItem>();
		if (selectedEntity == null) {
			setEntityAnvisa();
		}
		List<AnamanRegister> rTLBE = ars.getRegisterRefTypeListByEntity(selectedEntity);
		for (AnamanRegister rType : rTLBE) {
			if (rType.getIdRegister() != 0 
					&& rType.getRegisterArea().equalsIgnoreCase("registerarea")) {
				/*SelectItem s = new SelectItem();
				s.setValue(anamanRegister.getRegisterType());
				s.setLabel(anamanRegister.getRegisterRef() + " - " + anamanRegister.getRegisterType());
				System.out.println(s.getLabel());
				refTypes.add(s);*/
				//String type = rType.getRegisterType();
				AnamanRegisterTypeDTO type = new AnamanRegisterTypeDTO();
				type.setType(rType.getRegisterType());
				String label = rType.getRegisterRef() + " - " + rType.getRegisterType();
				refTypes.add(new SelectItem(type, label));
			}
		}
		return refTypes;
	}
		
	public String setEntityAnvisa(){
		setSelectedEntity("ANVISA");
		return selectedEntity;
	}
	
	/**
	 * @return the selectedRefType
	 */
	public String getSelectedRefType() {
		System.out.println("selectedRefType: " + selectedRefType);
		return selectedRefType;
	}
	
	public List<SelectItem> getRefAreas() {
		List<SelectItem> refAreas = new ArrayList<SelectItem>();
		if (selectedRefType != null) {
			List<AnamanRegister> rALBT = ars.getRegisterRefAreaListByType(selectedRefType);
			for (AnamanRegister rArea : rALBT) {
				if (rArea.getIdRegister() != 0 
						&& rArea.getRegisterApp().equalsIgnoreCase("registerapp")) {
					String area = rArea.getRegisterArea();
					String label = rArea.getRegisterRef() + " - " + rArea.getRegisterArea();
					refAreas.add(new SelectItem(area, label));
				}
			}
			return refAreas;
		} else {
			return new ArrayList<SelectItem>();
		}
	}
	
	/**
	 * @return the selectedArea
	 */
	public String getSelectedRefArea() {
		System.out.println(selectedRefArea);
		return selectedRefArea;
	}
	
	/**
	 * @return the selectedItem
	 *//*
	public AnamanRegisterService getSelectedItem() {
		return selectedItem;
	}

	// Setters
	// ------------------------------------------------------------------------------------
	/**
	 * @param entities the entities to set
	 */
	public void setEntities(List<SelectItem> entities) {
		this.entities = entities;
	}
	
	/**
	 * @param selectedEntity the selectedEntity to set
	 */
	public void setSelectedEntity(String selectedEntity) {
		System.out.println("setSelectedEntity: " + selectedEntity);
		this.selectedEntity = selectedEntity;
	}
	
	/**
	 * @param refTypes the refTypes to set
	 */
	public void setRefTypes(List<SelectItem> refTypes) {
		this.refTypes = refTypes;
	}
	
	/**
	 * @param selectedRefType the selectedRefType to set
	 */
	public void setSelectedRefType(String selectedRefType) {
		System.out.println("setSelectedRefType: " + selectedRefType);
		this.selectedRefType = selectedRefType;
	}

	/**
	 * @param refAreas the refAreas to set
	 */
	public void setRefAreas(List<SelectItem> refAreas) {
		this.refAreas = refAreas;
	}
	
	/**
	 * @param selectedRefType the selectedRefType to set
	 */
	public void setSelectedRefArea(String selectedRefArea) {
		System.out.println("setSelectedRefArea: " + selectedRefArea);
		this.selectedRefArea = selectedRefArea;
	}
	
	
	
	/**
	 * @param selectedItem the selectedItem to set
	 *//*
	public void setSelectedItem(AnamanRegisterService selectedItem) {
		this.selectedItem = selectedItem;
	}*/

	// Change Listeners
	public void entityCL(ValueChangeEvent evt) {
		setSelectedEntity(selectedEntity);
    }
	
	public void typeCL(ValueChangeEvent evt) {
		setSelectedRefType(selectedRefType);
	}
	
	public void areaCL(ValueChangeEvent evt) {
		setSelectedRefArea(selectedRefArea);
        }
}

Primeiramente remova o atributo immediate=true dos ajax support. Esse atributo é utilizado para “pular” as fases de conversão e validação mas ele também faz com que os valores não sejam alterados no seu MB, ou seja, a fase “Update model values” do JSF não é executada.

Outra coisa, vc não precisa necessariamente utilizar o atributo actionListener para chamar suas ações no MB. No seu código o atributo actionListener aponta sempre para a sua ação e o atributo action aponta para um método getter de uma propriedade (não entendi o sentido disso). Eu faria com que a action apontasse diretamente para um método do MB e nem utilizaria actionListener.

hmm, legal, lfpoli,

vou tentar aqui!

quanto ao immediate=true nos a4j, beleza, entendi perfeitamente.

mas não entendi direito o que você quis dizer com o segundo parágrafo:

então para eu definir o valor selecionado no combo, eu algo assim?

<a4j:support ...
        action="#{anamanRegisterServiceMB.selectedRefType}" />

obrigado!

Vc pode continuar usando actionListener se quiser, mas também pode configurar sua action para chamar o método que atualmente é chamado pelo actionListener. Basta mudar a assinatura do método (remover o parâmetro).

Como eu comentei anteriormente, não vejo sentido em ter uma action apontando para um método getter no MB. Actions normalmente são métodos que processam eventos disparados pelo usuário, porém vc está utilizando-as somente para retornar valores.

Eu entendo e concordo com o que tu dissestes e não queria usar uma action apenas para retornar um valor. Tentei essa abordagem por que não consegui que o valor selecionado no combo retornasse como uma string para eu a mandasse como parâmetro em um método (que faz um select no banco de dados) para popular o próximo combo.

Vou tentar outra coisa coisa aqui, se der certo posto o resultado…