2016-12-05 9 views
0

Je voudrais créer un formulaire d'inscription avec deux composants PrimeFaces: Wizard et Progress Bar. Pour la fève de soutien, je me sers le suivant:p: assistant avec une barre de progression

haricots Sauvegarde: UserWizard.xhtml

import java.io.Serializable; 
import java.util.Map; 
import java.util.TreeMap; 

import javax.annotation.PostConstruct; 
import javax.faces.application.FacesMessage; 
import javax.faces.context.FacesContext; 
import javax.faces.event.AjaxBehaviorEvent; 
import javax.faces.view.ViewScoped; 
import javax.inject.Named; 

import org.primefaces.context.RequestContext; 
import org.primefaces.event.FlowEvent; 

    @ViewScoped 
    @Named 
    public class UserWizard implements Serializable { 

     private User user = new User(); 

     private boolean skip; 

     private Integer progress = 0; 

     public User getUser() { 
      return user; 
     } 

     public void setUser(User user) { 
      this.user = user; 
     } 

     public void save() {   
      FacesMessage msg = new FacesMessage("Successful", "Welcome :" + user.getFirstname()); 
      FacesContext.getCurrentInstance().addMessage(null, msg); 
     } 

     public boolean isSkip() { 
      return skip; 
     } 

     public void setSkip(boolean skip) { 
      this.skip = skip; 
     } 

     public String onFlowProcess(FlowEvent event) { 
      String oldStep = event.getOldStep(); 
      Integer oldValue = getStepNumber(oldStep); 
      String newStep = event.getNewStep(); 
      Integer newValue = getStepNumber(newStep); 
      if(oldValue < newValue) 
       progress += 25; 
      else 
       progress += 25; 

      return event.getNewStep(); 
} 

public Integer getStepNumber(String Step) { 
    Integer StepNumber; 
    switch(Step) { 
     case "personal": 
      StepNumber = 1; 
      break; 
     case "address": 
      StepNumber = 2; 
      break; 
     case "contact": 
      StepNumber = 3; 
      break; 
     default: 
      StepNumber = 4; 
      break; 
    } 
    return StepNumber; 
} 

     public Integer getProgress() { 
      return progress; 
     } 

     public void setProgress(Integer progress) { 
      this.progress = progress; 
     } 

     public void onComplete() { 
      FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Progress Completed")); 
     } 

     public void cancel() { 
      progress = null; 
     } 
    } 

Formulaire d'inscription: registration.xhtml

<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets" 
    xmlns:f="http://xmlns.jcp.org/jsf/core" 
    xmlns:p="http://primefaces.org/ui" 
    xmlns:h="http://xmlns.jcp.org/jsf/html"> 
<body> 
    <f:view contracts="#{view.locale.language}"> 
     <ui:composition template="/template.xhtml"> 
      <ui:define name="centralBody"> 
<h:form> 

<p:growl id="growl" sticky="true" showDetail="true"/> 

<p:wizard flowListener="#{userWizard.onFlowProcess}"> 
    <p:tab id="personal" title="Personal"> 
     <p:panel header="Personal Details"> 
      <p:messages /> 
      <h:panelGrid columns="2" columnClasses="label, value"> 
       <h:outputText value="Firstname: *" /> 
       <p:inputText value="#{userWizard.user.firstname}" required="true" label="Firstname"/> 

       <h:outputText value="Lastname: *" /> 
       <p:inputText value="#{userWizard.user.lastname}" required="true" label="Lastname"/> 

       <h:outputText value="Age: " /> 
       <p:inputText value="#{userWizard.user.age}" /> 

       <h:outputText value="Skip to last: " /> 
       <h:selectBooleanCheckbox value="#{userWizard.skip}" /> 
      </h:panelGrid> 
     </p:panel> 
    </p:tab> 

    <p:tab id="address" title="Address"> 
     <p:panel header="Address Details"> 
      <p:messages /> 
      <h:panelGrid columns="2" columnClasses="label, value"> 
       <h:outputText value="Street: " /> 
       <p:inputText value="#{userWizard.user.street}" /> 

       <h:outputText value="Postal Code: " /> 
       <p:inputText value="#{userWizard.user.postalCode}" /> 

       <h:outputText value="City: " /> 
       <p:inputText value="#{userWizard.user.city}" /> 

       <h:outputText value="Skip to last: " /> 
       <h:selectBooleanCheckbox value="#{userWizard.skip}" /> 
      </h:panelGrid> 
     </p:panel> 
    </p:tab> 

    <p:tab id="contact" title="Contact"> 
     <p:panel header="Contact Information"> 
      <p:messages /> 
      <h:panelGrid columns="2" columnClasses="label, value"> 
       <h:outputText value="Email: *" /> 
       <p:inputText value="#{userWizard.user.email}" required="true" label="Email"/> 

       <h:outputText value="Phone: " /> 
       <p:inputText value="#{userWizard.user.phone}"/> 

       <h:outputText value="Additional Info: " /> 
       <p:inputText value="#{userWizard.user.info}"/> 
      </h:panelGrid> 
     </p:panel> 
    </p:tab> 

    <p:tab id="confirm" title="Confirmation"> 
     <p:panel header="Confirmation"> 
      <h:panelGrid id="confirmation" columns="3" columnClasses="grid,grid,grid"> 
       <h:panelGrid columns="2" columnClasses="label, value"> 
        <h:outputText value="Firstname: " /> 
        <h:outputText value="#{userWizard.user.firstname}" styleClass="outputLabel"/> 

        <h:outputText value="Lastname: " /> 
        <h:outputText value="#{userWizard.user.lastname}" styleClass="outputLabel"/> 

        <h:outputText value="Age: " /> 
        <h:outputText value="#{userWizard.user.age}" styleClass="outputLabel"/> 
       </h:panelGrid> 

       <h:panelGrid columns="2" columnClasses="label, value"> 
        <h:outputText value="Street: " /> 
        <h:outputText value="#{userWizard.user.street}" styleClass="outputLabel"/> 

        <h:outputText value="Postal: " /> 
        <h:outputText value="#{userWizard.user.postalCode}" styleClass="outputLabel"/> 

        <h:outputText value="City: " /> 
        <h:outputText value="#{userWizard.user.city}" styleClass="outputLabel"/> 
       </h:panelGrid> 

       <h:panelGrid columns="2" columnClasses="label, value"> 
        <h:outputText value="Email: " /> 
        <h:outputText value="#{userWizard.user.email}" styleClass="outputLabel"/> 

        <h:outputText value="Phone " /> 
        <h:outputText value="#{userWizard.user.phone}" styleClass="outputLabel"/> 

        <h:outputText value="Info: " /> 
        <h:outputText value="#{userWizard.user.info}" styleClass="outputLabel"/> 

        <h:outputText /> 
        <h:outputText /> 
       </h:panelGrid> 
      </h:panelGrid> 

      <p:commandButton value="Submit" actionListener="#{userWizard.save}" update="growl" process="@this"/> 
     </p:panel> 
    </p:tab> 
</p:wizard> 
<p:progressBar id="progressBar" widgetVar="pbAjax" ajax="true" value="#{UserWizard.progress}" labelTemplate="{value}%" styleClass="animated" global="false"> 
     <p:ajax event="complete" listener="#{UserWizard.onComplete}" update="growl" oncomplete="PF('startButton2').enable()"/> 
    </p:progressBar> 
</h:form> 
     </ui:define> 
     </ui:composition> 
    </f:view> 
</body> 
</html> 

Mon but est que, lorsque le flux d'inscription passe par les différents onglets d'inscription (Perso nal, adresse, contact et confirmation), la barre de progression dans la partie inférieure de l'écran doit être mise à jour en fonction des boutons suivant ou précédent. Pour ce faire, je veux utiliser la méthode

public String onFlowProcess(FlowEvent event) { 
    String oldStep = event.getOldStep(); 
    Integer oldValue = getStepNumber(oldStep); 
    String newStep = event.getNewStep(); 
    Integer newValue = getStepNumber(newStep); 
    if(oldValue < newValue) 
     progress += 25; 
    else 
     progress -= 25; 

    return event.getNewStep(); 
} 

public Integer getStepNumber(String Step) { 
    Integer StepNumber; 
    switch(Step) { 
     case "personal": 
      StepNumber = 1; 
      break; 
     case "address": 
      StepNumber = 2; 
      break; 
     case "contact": 
      StepNumber = 3; 
      break; 
     default: 
      StepNumber = 4; 
      break; 
    } 
    return StepNumber; 
} 

Mais je ne sais pas comment mettre à jour la barre de progression. J'ai essayé:

  • changer la valeur de la valeur de la barre de progression (variables de progression) dans la fonction
    onFlowProcess. Ça ne marche pas.
  • <p:wizard ... update="progress_bar">. J'ai réalisé que l'attribut mise à jour n'est pas autorisé pour le composant Wizard.
  • <p:ajax listener="#{UserWizard.onFlowProcess}" update="@this"> au sein de l'élément <p:progressBar>.
+0

Et le vrai problème est? – Kukeltje

+1

Je garderais le côté serveur actuel de l'étape dans un bean et je comparerais avec le 'newstep' si l'événement se produit ... – Kukeltje

+0

Qu'avez-vous ** essayé **? Mettre à jour l'attribut? Ajax? commande à distance? – Kukeltje

Répondre

2

Depuis l'assistant (au moins dans PrimeFaces/JUSQU'A 6.0) ne semble pas en charge l'attribut update lorsque vous utilisez un flowListener et aucun événement ajax explicites sont pris en charge, la seule option que je vois est d'utiliser les PrimeFaces RequestContext à mettre à jour l'autre composant. Gardez à l'esprit que vous devez utiliser le 'chemin absolu' de l'élément, en y incluant tous les identifiants des conteneurs de dénomination. Il est préférable d'attribuer explicitement des identifiants à tous les conteneurs de nommage (y compris un formulaire!)

Donc en utilisant

RequestContext.getCurrentInstance().update("formId:progress_bar"); 

comme par exemple

public String onFlowProcess(FlowEvent event) { 
    String oldStep = event.getOldStep(); 
    Integer oldValue = getStepNumber(oldStep); 
    String newStep = event.getNewStep(); 
    Integer newValue = getStepNumber(newStep); 
    if(oldValue < newValue) 
     progress += 25; 
    else 
     progress -= 25; 

    RequestContext.getCurrentInstance().update("formId:progress_bar");   

    return event.getNewStep(); 
} 

dans le flowListener devrait fonctionner. Gardez à l'esprit que dans les mises à jour de beans, le ':' comme préfixe pour les chemins absolus n'est pas nécessaire, ils sont supposés être toujours absolus