2017-08-11 2 views
5

I primefaces Schritten Tag <p:steps> wie unten haben:p: Schritte, aber aktivieren, klicken Sie auf alle Schritte

<p:steps activeIndex="3" styleClass="custom" readonly="false" style="padding: 20px;"> 
    <p:menuitem value="step 1." actionListener="#{masterController.menuSales(preferencesController)}" update="mainPanel"/> 
    <p:menuitem value="step 2." actionListener="#{masterController.menuCustomer(preferencesController)}" update="mainPanel"/> 
    <p:menuitem value="step 3." actionListener="#{masterController.menuItem(preferencesController)}" update="mainPanel"/> 
    <p:menuitem value="step 4"/> 
</p:steps> 

Und das Ergebnis ist wie folgt aus:

enter image description here

I Schritt 1 klicken können aber nicht Schritt 3 und 4. Wie kann ich Klick für alle Schritte aktivieren?

+0

Was spielst Du 'p umzusetzen versucht: steps'? –

+0

, um den Benutzer wissen zu lassen, welchen Schritt er/sie tun muss, um das Tutorial abzuschließen, aber der Benutzer kann den Schritt zum nächsten/vorherigen Schritt klicken, statt auf den Link vom Hauptmenü –

+1

Klingt wie funktional Sie wollen p: tabView stattdessen. Wahrscheinlich haben Sie aus kosmetischen Gründen p: steps gewählt, was nicht gut ist. –

Antwort

4

Wow, das ist eine nette Frage!

Ich habe viele Dinge mit der aktuellen API versuchte, es zu erreichen, aber scheine, wie es mit unseren aktuellen Optionen nicht möglich ist.

Um dies zu lösen ich einen benutzerdefinierten Renderer für den Step Komponente schrieb:

Die meisten Code unter dem gleichen aus der GitHub des PrimeFaces ist. Ich habe gerade ein paar Dinge geändert, um dieses spezielle Problem zu lösen.

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.LinkedHashMap; 
import java.util.List; 
import java.util.Map; 
import javax.faces.FacesException; 
import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.context.ResponseWriter; 
import org.primefaces.component.api.AjaxSource; 
import org.primefaces.component.api.UIOutcomeTarget; 
import org.primefaces.component.steps.Steps; 
import org.primefaces.component.steps.StepsRenderer; 
import org.primefaces.model.menu.MenuItem; 
import org.primefaces.util.ComponentTraversalUtils; 

public class CustomStepsRenderer extends StepsRenderer { 

@Override 
protected void encodeItem(FacesContext context, Steps steps, MenuItem item, int activeIndex, int index) throws IOException { 
    ResponseWriter writer = context.getResponseWriter(); 
    String itemClass; 

    if (steps.isReadonly()) { 
     itemClass = (index == activeIndex) ? Steps.ACTIVE_ITEM_CLASS : Steps.INACTIVE_ITEM_CLASS; 
    } else { 
     if (index == activeIndex) { 
      itemClass = Steps.ACTIVE_ITEM_CLASS; 
     } 
     else { 
      itemClass = Steps.VISITED_ITEM_CLASS; 
     } 
    } 

    String containerStyle = item.getContainerStyle(); 
    String containerStyleClass = item.getContainerStyleClass(); 

    if (containerStyleClass != null) { 
     itemClass = itemClass + " " + containerStyleClass; 
    } 

    //header container 
    writer.startElement("li", null); 
    writer.writeAttribute("class", itemClass, null); 
    writer.writeAttribute("role", "tab", null); 
    if (containerStyle != null) { 
     writer.writeAttribute("style", containerStyle, null); 
    } 

    encodeMenuItem(context, steps, item, activeIndex, index); 

    writer.endElement("li"); 
} 

@Override 
protected void encodeMenuItem(FacesContext context, Steps steps, MenuItem menuitem, int activeIndex, int index) throws IOException {   
    ResponseWriter writer = context.getResponseWriter(); 
    String title = menuitem.getTitle(); 
    String style = menuitem.getStyle(); 
    String styleClass = this.getLinkStyleClass(menuitem); 

    writer.startElement("a", null); 
    writer.writeAttribute("tabindex", "-1", null); 
    if (shouldRenderId(menuitem)) { 
     writer.writeAttribute("id", menuitem.getClientId(), null); 
    } 
    if (title != null) { 
     writer.writeAttribute("title", title, null); 
    } 

    writer.writeAttribute("class", styleClass, null); 

    if (style != null) { 
     writer.writeAttribute("style", style, null); 
    } 

    if (steps.isReadonly() || menuitem.isDisabled()) { 
     writer.writeAttribute("href", "#", null); 
     writer.writeAttribute("onclick", "return false;", null); 
    } else { 
     String onclick = menuitem.getOnclick(); 

     //GET 
     if (menuitem.getUrl() != null || menuitem.getOutcome() != null) { 
      String targetURL = getTargetURL(context, (UIOutcomeTarget) menuitem); 
      writer.writeAttribute("href", targetURL, null); 

      if (menuitem.getTarget() != null) { 
       writer.writeAttribute("target", menuitem.getTarget(), null); 
      } 
     } //POST 
     else { 
      writer.writeAttribute("href", "#", null); 

      UIComponent form = ComponentTraversalUtils.closestForm(context, steps); 
      if (form == null) { 
       throw new FacesException("MenuItem must be inside a form element"); 
      } 

      String command; 
      if (menuitem.isDynamic()) { 
       String menuClientId = steps.getClientId(context); 
       Map<String, List<String>> params = menuitem.getParams(); 
       if (params == null) { 
        params = new LinkedHashMap<String, List<String>>(); 
       } 
       List<String> idParams = new ArrayList<String>(); 
       idParams.add(menuitem.getId()); 
       params.put(menuClientId + "_menuid", idParams); 

       command = menuitem.isAjax() 
         ? buildAjaxRequest(context, steps, (AjaxSource) menuitem, form, params) 
         : buildNonAjaxRequest(context, steps, form, menuClientId, params, true); 
      } else { 
       command = menuitem.isAjax() 
         ? buildAjaxRequest(context, (AjaxSource) menuitem, form) 
         : buildNonAjaxRequest(context, ((UIComponent) menuitem), form, ((UIComponent) menuitem).getClientId(context), true); 
      } 

      onclick = (onclick == null) ? command : onclick + ";" + command; 
     } 

     if (onclick != null) { 
      writer.writeAttribute("onclick", onclick, null); 
     } 
    } 

    writer.startElement("span", steps); 
    writer.writeAttribute("class", Steps.STEP_NUMBER_CLASS, null); 
    writer.writeText((index + 1), null); 
    writer.endElement("span"); 

    Object value = menuitem.getValue(); 
    if (value != null) { 
     writer.startElement("span", steps); 
     writer.writeAttribute("class", Steps.STEP_TITLE_CLASS, null); 
     writer.writeText(value, null); 
     writer.endElement("span"); 
    } 

    writer.endElement("a"); 
} 

Dann registrieren Sie diesen neuen Renderer in Ihrer faces-config.xml Datei:

<render-kit> 
     <renderer> 
      <component-family>org.primefaces.component</component-family> 
      <renderer-type>org.primefaces.component.StepsRenderer</renderer-type> 
      <renderer-class>YOUR_PACKAGE.CustomStepsRenderer</renderer-class> 
     </renderer> 
    </render-kit> 

nicht YOUR_PACKAGE zu Ihrem CustomStepsRenderer Paket Speicherort zu ändern Vergessen.

Danach, nur bauen/re-Bereitstellung Ihrer Anwendung und alles sollte funktionieren:

enter image description here

+1

danke für deine antwort –

2

Nun, p:steps und p:wizard sind die Komponenten in PrimeFaces Komponenten-Suite, die darstellt, oder geben Sie den Schritt (e) in einem Workflow mehrere Schritte von einzelner Form (Schritt für Schritt) für den Prozess simplication zu verwalten und verwenden austauschbar sein kann, wenn Sie Verstehen Sie den Gebrauch richtig (abhängig von der Anforderung).

Für die Verwendung der Komponente p:steps sollten Sie sicherstellen, dass der/die nächste (n) Schritt (e) nur angezeigt wird, wenn der aktuelle Schritt vollständig verarbeitet wurde und die erforderlichen Daten gesammelt wurden. Nehmen Sie den Prozess des Online-Shoppings an, bei dem die Zahlungsabwicklung der letzte Schritt ist und nur dann angezeigt wird, wenn Sie einen Artikel in Ihrem Einkaufswagen haben und die anderen Informationen (falls vorhanden) angegeben haben.

Das obige Szenario kann auch p:wizard Komponente implementiert werden. Wobei nur der aktuelle Schritt teilweise verarbeitet wird und der nächste Schritt angezeigt wird, wenn der aktuelle Schritt die Validierung besteht. Die Komponente p:wizard bietet jedoch die Möglichkeit, das Standardverhalten zu überschreiben, indem der Ablauf des Assistenten gesteuert wird, benutzerdefinierte & Schaltflächen mit benutzerdefinierten Aktionshandlern angezeigt werden und die Validierung übersprungen wird, um die nächsten Schritte anzuzeigen.