p:steps 但启用点击所有步骤

2023-11-27

我有使用标签的 primefaces 步骤<p:steps>像下面这样:

<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。如何为所有步骤启用单击?


哇,这是个好问题!

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

为了解决这个问题,我为 Steps 组件编写了一个自定义渲染器:

下面的大部分代码都来自 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 file:

   <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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

p:steps 但启用点击所有步骤 的相关文章

随机推荐

  • 按角度旋转整个 qwidget

    我正在 wt 中创建简单的俄罗斯方块 并继承了小部件来创建片段 我在游戏中放置了四个片段 四个不同的类 我在每件作品中都借鉴了绘画事件 如何旋转小部件 我可以在 painEvent 函数中绘制旋转图像 但我宁愿旋转整个小部件 这在 qt 中
  • PHP长轮询,无需过多的数据库访问

    我一直很喜欢长轮询的想法 在我的开发服务器上 我玩过各种通知 新帖子系统 每个系统都使用 javascript 来保持连接并 等待 某种响应 我一直对这种方法的许多实现存在疑问 它们都涉及重复轮询 mySQL 服务器以检查新行 可以使用专门
  • 删除 SQL Server 中字符串中的所有空格

    在 SQL Server 2008 中删除字符串中所有空格的最佳方法是什么 LTRIM RTRIM a b 将删除字符串右侧和左侧的所有空格 但我还需要删除中间的空格 只需更换即可 SELECT REPLACE fld or variabl
  • iOS 中何时刷新收据与恢复购买?

    我们的 iOS 应用程序使用应用程序内购买 包括一次性订阅和自动续订订阅 这两个都是非消耗品 iOS 提供了两个 API 刷新收据 and 恢复已完成的交易 似乎后者适用于所有情况 而前者仅适用于某些情况 具体来说 当我们将自动续订购买恢复
  • Golang使用goroutines并行下载多个文件

    是否可以使用 goroutine 并行下载和保存文件 下面是我的代码 它从我的保管箱下载文件 package main import encoding json fmt io io ioutil net http net url os pa
  • 事件中心是否应该根据消息类型进行拆分?

    我正在考虑将 Azure 事件中心用于我当前正在进行的项目 今天我们使用服务总线队列来执行命令 在这里我们为每种消息类型使用一个队列 拥有多个事件中心是否有意义 还是使用一个中心处理多种消息类型更好 这是一个充满权衡和判断的问题 您希望现在
  • 如何通过 JavaScript 获取通过 CSS 设置的准确 RGBa 值?

    在我尝试过的大多数浏览器中 rgba 一旦浏览器解析了 CSS 值似乎就会改变 例如 以下 CSS background color rgba 255 0 0 0 5 通过访问时给出以下 CSS 值jQuery css background
  • 管理核心数据 iCloud 事务日志

    我正在将 iCloud 与 Core Data 结合使用 基于 Apple 指定的 SQLite 库式 应用程序设计 虽然基本功能运行得很好 但我担心事务日志及其管理方式 虽然我的应用程序的数据库并不大 但它非常活跃 并且在应用程序使用过程
  • OS X 产品签名错误:找不到适当的签名身份

    我正在尝试使用命令行实用程序签署 OS X 安装程序包产品标志 但出现错误 productsign sign Developer ID Installer XYZ input pkg output pkg productsign error
  • 如何在mysql中按年龄段对用户数量进行分组

    本质上我有一个 mysql 数据库 其中包含用户及其相应的出生日期 我还发现了以下代码 可以帮助我找到用户从出生日期算起的实际年龄 查找出生日期我需要做的是找到不同的 年龄段 并计算该年龄段的用户数量 我也发现了this示例准确地展示了如何
  • 有没有办法让不和谐机器人通过accept_invite或类似的东西加入服务器?

    注意 我使用的是discord py 0 16 12 我想知道是否有任何方法可以让机器人在代码中加入服务器 就像有一个命令是这样的 client command pass context True async def join ctx in
  • 如何在pygame中显示文本? [复制]

    这个问题在这里已经有答案了 我无法弄清楚如何在 pygame 中显示文本 我知道我不能像常规 Python IDLE 那样使 用 print 但我不知道如何使用 import pygame sys from pygame locals im
  • 带有 QAbstractListModel 的 QListView 显示空列表

    我创建了一个非常简单的例子QListView与定制QAbstractListModel The QListView显示但它是空的 我究竟做错了什么 Code include
  • Android:以编程方式从 Java 代码填充微调器

    如何以编程方式从 java 代码填充微调器 我的布局中有一个微调器 如下所示
  • GWT DataGrid 自动高度

    我正在尝试在我的应用程序中插入 gwt 数据网格 如果我设置静态高度 500px 一切都会很好 但我想让 dataGrid 自动调整到屏幕尺寸 当高度为 100 时 我得到一个空白屏幕 我还尝试将数据网格放入 resizeLayoutPan
  • 在沙箱中运行 .Net 应用程序

    几个月来 我开发了一个个人工具 用于在线编译 C 3 5 Xaml 项目 基本上 我使用 CodeDom 编译器进行编译 我正在考虑将其公开 但问题是使用此工具在服务器上执行任何操作都非常非常容易 我想保护我的服务器的原因是因为有一个 运行
  • 将php字符串分割成不同长度的块

    我正在寻找将字符串拆分为数组的方法 类似于str split 其中块的大小都不同 我可以通过用一堆循环遍历字符串来做到这一点substr 但这看起来既不优雅也不高效 是否有一个接受字符串和数组的函数 例如 1 18 32 41 108 12
  • 是否可以识别哈希类型?

    我知道您可以比较长度 但许多哈希类型具有相同的长度 有没有办法识别哈希的类型以及它是否已加盐 例如 hash 2bf231b0e98be99a969bd6724f42a691 hash 4ac5a4ff764807d6ef464e27e4d
  • 如何从 Laravel URL 中删除 /public/ [重复]

    这个问题在这里已经有答案了 我想删除 public 来自我的 Laravel 5 URL 的片段 我不想运行虚拟机 这在项目之间切换时看起来很尴尬 我不想将文档根目录设置为公共文件夹 这在项目之间切换时也很尴尬 我尝试过 htaccess
  • p:steps 但启用点击所有步骤

    我有使用标签的 primefaces 步骤