ADF : récupérer la valeur choisie d'une liste de sélection <af:selectOneChoice>

Lorsqu’on utilise le composant ADF <af:selectOneChoice> et que l’on veut récupérer la valeur choisie on se heurte dans la plupart des essais effectués au problème suivant. On obtient la valeur de l’index dans la liste et non la valeur elle-même.

Il n’existe pas de solution purement déclarative pour récupérer cette valeur. Il faut le faire en passant par un traitement dans le managed bean de la page.

Pré-requis

Utiliser une version Jdeveloper 11.1.1.x

Résultat du bind d’un attribut sur une page jsf sous la forme d’une liste de choix

Prenons l’exemple d’un attribut CliId qui est bindé sur une page jsf sous la forme d’une liste de choix.
On obtient le tag suivant sur le fichier XML contenant les bindings de la page.

	<list IterBinding="AdmRefServerIterator" StaticList="false" Uses="LOV_CliId"
	          id="CliId" DTSupportsMRU="true" ChangeEventPolicy="ppr"/>

Point important à connaître, la liste de choix créée est associée à un objet JUCtrlListBinding qui nous servira de base pour notre traitement.

Récupération de la valeur choisie au sein du managed bean

L’idée consiste à récupérer la valeur choisie pour la liste CliId à travers l’utilisation du Listener, ValueChangeListener.

   public void onSelectClient(ValueChangeEvent valueChangeEvent) {
	Number selectedValue = null;
	try {
		// Recuperation de l'objet binde gerant la liste des clients
		JUCtrlListBinding clients = ADFUtils.findCtrlListBinding("CliId");
		// Recuperation de la valeur selectionnee
		selectedValue = (Number)clients.getAttributeValue();
	} catch (Exception e) {
		LOGGER.error("[onSelectClient] clients.getAttributeValue() = " + clients.getAttributeValue());
		LOGGER.error("[onSelectClient] Exception= " + e);
		// Envoi message d'avertissement à l'utilisateur
               FacesContext fc = FacesContext.getCurrentInstance();
               FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_ERROR, null,
                                                  "Exception lors de la récupération de la valeur du client choisie." +e);
               fc.addMessage(null, fm);
	} finally {
		LOGGER.debug("[onSelectClient]  selectedValue = " + selectedValue);
	}
  }

Arrivé à ce point, on pense avoir fait le plus dur. Mais au désespoir, en lisant la valeur récupérée, on se rend compte qu’elle ne correspond pas au choix fait sur l’interface utilisateur.

Tout est-il perdu, notre approche n’est-elle pas la bonne?

Puis après une rapide analyse, on se rend compte qu’en fait elle correspond à la valeur précédemment choisie de la liste. Et là, l’espoir renaît. En fait, le JUCtrlListBinding n’est pas à jour au moment où on l’a sollicité. Il suffit dès lors de rajouter le code effectuant cette mise à jour avant de récupérer la valeur, on obtient dès lors :

  public void onSelectClient(ValueChangeEvent valueChangeEvent) {
	Number selectedValue = null;
	try {
		// Recuperation de l'objet binde gerant la liste des clients
		JUCtrlListBinding clients = ADFUtils.findCtrlListBinding("CliId");
		// Mise a jour forcee de la valeur selectionnee dans la liste
		int index = Integer.parseInt(String.valueOf(valueChangeEvent.getNewValue()));
		clients.setSelectedIndex(index);
		// Recuperation de la valeur selectionnee
		selectedValue = (Number)clients.getAttributeValue();
	} catch (Exception e) {
		LOGGER.error("[onSelectClient] clients.getAttributeValue() = " + clients.getAttributeValue());
		LOGGER.error("[onSelectClient] Exception = " + e);
		// Envoi message d'avertissement à l'utilisateur
               FacesContext fc = FacesContext.getCurrentInstance();
               FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_ERROR, null,
                                                  "Exception lors de la récupération de la valeur du client choisie." +e);
               fc.addMessage(null, fm);
	} finally {
		LOGGER.debug("[onSelectClient]  selectedValue = " + selectedValue);
	}
  }

Bibliographie :

cet article s’est largement inspiré de Reading the selected value of a select list in java.