2017-08-11 81 views
5

我有使用标签<p:steps>像下面primefaces步骤:号码:步骤,但开启所有点击步骤

<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> 

,结果是这样的:

enter image description here

我可以点击第1步但不是第3步和第4步。我怎样才能启用点击所有步骤?

+0

什么是你想使用'p以实现:steps'? –

+0

,让用户知道他/她必须做什么才能完成教程,但用户可以单击该步骤进入下一个/上一步而不是单击主菜单中的链接 –

+1

声音的功能与您想要的p:tabView相反。您可能选择p:步骤出于美观的原因,这是不明智的。 –

回答

4

哇,这是一个很好的问题!

我已经尝试了很多与当前的API来完成它的事情,但似乎是不可能与我们目前的选项。

为了解决这个问题我写了一个自定义的渲染步骤组成:

大多数下面的代码是从PrimeFaces的GitHub上的相同。我只是改变了一些东西来解决这个具体问题。

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"); 
} 

然后,在你的faces-config.xml文件中注册这个新的渲染:

<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> 

不要忘记YOUR_PACKAGE更改为您CustomStepsRenderer包的位置。

之后,只需建立/重新部署应用程序,一切都应该很好地工作:

enter image description here

+1

感谢您的回答 –

2

那么,p:stepsp:wizard在PrimeFaces组件套件,它表示或指示工作流中的步骤(一个或多个)来管理过程简单化单一形式(步步)的多个步骤,并且如果你可以互换使用的组分正确理解使用情况(取决于要求)。

对于使用p:steps组件,您应确保只有当当前步骤完成处理并收集所需数据时才会显示下一步。 假设在线购物的过程中,付款处理是最后一步,当且仅当购物车中有物品并提供了其他信息(如果有)时才会显示。

上述场景也可以使用p:wizard组件实现。只有当前步骤部分处理,如果当前步骤通过验证,则显示下一个步骤。但是,p:wizard组件可以通过控制向导流程,使用自定义操作处理程序呈现自定义的前一个按钮并跳过验证以查看后续步骤来覆盖其默认行为。