Projets
Pages enfant
  • Affichage dynamique suite à un clic-bouton

Comparaison des versions

Légende

  • Ces lignes ont été ajoutées. Ce mot a été ajouté.
  • Ces lignes ont été supprimées. Ce mot a été supprimé.
  • La mise en forme a été modifiée.
Commentaire: Migrated to Confluence 5.3

Supposons que l'on souhaite afficher un formulaire de saisie (ou tout autre composant) de saisie dynamiquement dans une page (affichant d'autres choses) seulement si au moment ou l'utilisateur clique sur un bouton

Remarque
titleA compléter

Schéma ou exemple

Sommaire

Piste 1 : utiliser le

...

rendered

... celui du form ou d'un panelGrid avec un booléen dans le contrôleur (ici showUserForm)

...

donc update="...panelFormAddUser..." ajax n'a aucun effet puisqu'il n'est pas sur la page.
En revanche si on désactive ajax sur le bouton la page est rechargée complètement :

Bloc de code
<p:commandButton value="Afficher formulaire" actionListener="#{welcomeController.showFormNewUser}" ajax="false">
						</p:commandButton>

... ça marche

Il faut donc un contenant qui s'affiche toujours, qui sera vide par defaut défaut et contiendra le formulaire à l'appel du cliqueclic

Piste 2 : Utiliser un binding

Ceci consiste à mapper un objet qui compose la vue à une propriété du contrôleur.

...

Bloc de code
import javax.faces.component.UIComponent;
[...]
private UIComponent panelUserForm;
[...]

        public void showFormNewUser() {
		        this.panelUserForm.setRendered(true);
        }

[...]
	public UIComponent getPanelUserForm() {
		return panelUserForm;
	}

	public void setPanelUserForm(UIComponent panelUserForm) {
		this.panelUserForm = panelUserForm;
	}
[...]

... et dans la JSP on mappe :

Bloc de code

<h:panelGrid id="panelFormAddUser" binding="#{welcomeController.panelUserForm}" columns="1" rendered="false">
	<h:form id="formAddUser">
	[...]
	</h:form>
</h:panelGrid>

Comme précédemment, update="...panelFormAddUser..." ajax n'a aucun effet puisqu'il n'est pas sur la page.
En revanche si on désactive ajax sur le bouton la page est rechargée complètement :

Bloc de code
<p:commandButton value="Afficher formulaire" actionListener="#{welcomeController.showFormNewUser}" ajax="false">
						</p:commandButton>

... ça marche

Il faut donc un contenant qui s'affiche toujours, qui sera vide par défaut et contiendra le formulaire à l'appel du clic

Piste 3 : Un contenant vide qui sera mis à jour au moment du clic

Pour que seul le panel soit rafraichi avec Ajax e non la page complète nous allons repartir de l'exemple précédent et laisser le panelGrid toujours visible et on va jouer sur la visibilité du formulaire.

Bloc de code

<h:panelGrid id="panelFormAddUser" binding="#{welcomeController.panelUserForm}" columns="1" rendered="true">
	<h:form id="formAddUser" rendered="false">
	[...]
	</h:form>
</h:panelGrid>

avec le bouton

Bloc de code
<p:commandButton value="Afficher formulaire" update="@form,panelFormAddUser,growl"
	action="#{welcomeController.showFormNewUser}" >
	</p:commandButton>

Désormais au clic on appellera :

Bloc de code
        public void showFormNewUser() {
	        this.panelUserForm.getChildren().get(0).setRendered(true);
        }

Là ça marche, au clic le rendered du formulaire est positionné à true et le panel est rafraichi.

Pour améliorer

On va maintenant ajouter un bouton dans le formulaire pour cacher ce dernier.
On a donc l'exemple complet :

Bloc de code

<p:commandButton value="Afficher formulaire" update="@form,panelFormAddUser,growl"
	action="#{welcomeController.showFormNewUser}" >
	</p:commandButton>
[...]
<h:panelGrid id="panelFormAddUser" binding="#{welcomeController.panelUserForm}" columns="1" rendered="true">
	<h:form id="formAddUser" rendered="false">
	[...]
	</h:form>
        <h:form id="formhideAddUser" rendered="false">
	        <p:commandButton value="Masquer formulaire" update="panelFormAddUser,growl"
			action="#{welcomeController.hideFormNewUser}" >
		</p:commandButton>
	</h:form>
</h:panelGrid>

Désormais aux clics on appellera le cas échéant :

Bloc de code

        import javax.faces.component.UIComponent;
        [...]
        private UIComponent panelUserForm;

        public void showFormNewUser() {		
                for (UIComponent component : this.panelUserForm.getChildren()) {
			component.setRendered(true);
		}
        }
        public void hideFormNewUser() {
                for (UIComponent component : this.panelUserForm.getChildren()) {
			component.setRendered(false);
		}
        }

Pour améliorer encore un peu

On intègre le bouton d'affichage du formulaire dans le panel et on switch les rendered

Bloc de code


<h:panelGrid id="panelFormAddUser" binding="#{welcomeController.panelUserForm}" columns="1" rendered="true">
	 <h:form id="formshowAddUser" rendered="true">
                <p:commandButton value="Afficher formulaire" update="@form,panelFormAddUser,growl"
	               action="#{welcomeController.toogleFormNewUser}" >
	        </p:commandButton>
        </h:form>
        <h:form id="formAddUser" rendered="false">
	[...]
	</h:form>

        <h:form id="formhideAddUser" rendered="false">
	        <p:commandButton value="Masquer formulaire" update="panelFormAddUser,growl"
			action="#{welcomeController.toogleFormNewUser}" >
		</p:commandButton>
	</h:form>
</h:panelGrid>

Désormais aux clics on appellera une seule méthode :

Bloc de code

        import javax.faces.component.UIComponent;
        [...]
        private UIComponent panelUserForm;

        public void toogleFormNewUser() {		
                for (UIComponent component : this.panelUserForm.getChildren()) {
			if (component.getAttributes().get("rendered").toString().equals("true"))
				component.setRendered(false);
			else
				component.setRendered(true);
		}
        }

Piste 4 : La solution de facilité... un composant

Primefaces propose par exemple le composant dialog

Bloc de code

<p:commandButton value="Afficher formulaire" onclick="dialogNewUser.show();" type="button"/> 
[...]
<p:dialog header="Création d'un utilisateur" widgetVar="dialogNewUser" modal="true">
	<h:form id="formAddUser">
         [...]
        </h:form>
</p:dialog>