2

在我的 Java 代码中,我想以编程方式创建一个<fieldset>可以在我的 JSF 表单中使用的标记。

我的表单设置如下所示:

Application app = FacesContext.getCurrentInstance().getApplication();

HtmlForm form = (HtmlForm) app.createComponent(HtmlForm.COMPONENT_TYPE);
form.setStyleClass("pure-form pure-form-stacked");

如您所见,我将HtmlForm.COMPONENT_TYPE其用作 JSF UI 组件的标识符,但我没有找到字段集的标识符,因此我尝试了:

UIComponent fieldset = app.createComponent("fieldset");
form.getChildren().add(fieldset);

不幸的是,这不起作用,所以我必须想出另一个解决方案。你有什么想法?

是否有一种通用方法可以创建 HTML 标记(在 JSF 上下文中是未知的)?

4

2 回答 2

4

您可以尝试以下方法:

有一个名为的组件<f:verbatim>,您可以在 xhtml 中使用,如下所示:

<f:verbatim escape="false">
    <fieldset id="blah"></fieldset>
</f:verbatim>

要以编程方式实现这一点,您可以像这样添加这个组件:

String fieldsetHTMLText ="<fieldset id=\"blah\"></fieldset>";

UIOutput verbatim = new UIOutput();
verbatim.setRendererType("javax.faces.Text");
verbatim.getAttributes().put("escape", false);
verbatim.setValue(fieldsetHTMLText);
于 2014-03-05T14:50:52.350 回答
4

我找到了三个解决我的问题的方法。第一个是使用PrimeFaces,第二个是使用MyFaces Tomahawk,第三个是使用JSF Verbatim UI component字符串输入。我将很快列出代码示例以及解决方案之间的差异。

1 PrimeFaces

通过包含 PrimeFaces 组件套件(以及它的 Apache Commons FileUpload 依赖项),您可以使用 Fieldset 类以编程方式即时创建字段集。坏事是,PrimeFaces Fieldset 组件依赖于 PrimeFaces JavaScript 文件,所以不是普通的字段集,而是一个字段集和一个 JavaScript 包含,这太多了。

import org.primefaces.component.fieldset.Fieldset;

...

form.getChildren().add(new Fieldset());

2 MyFaces 战斧

UI 组件集 Tomahawk 还附带一个 Fieldset 组件,可用于以编程方式创建 HTML 字段集。如果将使用 Tomahawk 的 Fieldset,那么将获得一个简单而漂亮的 fieldset 标签。这里的坏处是 Tomahawk 是 MyFaces 的扩展,而 MyFaces 本身是一个完整的 JavaServer Faces 实现,不应与标准 JSF 一起使用。

import org.apache.myfaces.custom.fieldset.Fieldset

...

form.getChildren().add(new Fieldset());

3 JSF逐字UI组件

标准化和 hacky 的方式是使用 JSF Verbatim UI 组件。在逐字组件中,您可以放置​​所需的任何 HTML。通过这个小技巧,我们可以创建一个逐字标记:

UIOutput fieldset = new UIOutput();
fieldset.setRendererType("javax.faces.Text");
fieldset.getAttributes().put("escape", false);
fieldset.setValue("<fieldset></fieldset>");

上面显示的代码呈现了一个字段集 HTML 元素,但是因为它是一个字符串,并且字符串中的标签是封闭的,所以您不能以编程方式将任何内容附加到该标签,因此这不起作用:

form.getChildren().add(fieldset);

要生成可用于嵌套元素的 HTML 标记,每个开始和结束标记都必须放在自己的 Varbatim 组件中,这使得该解决方案的文本非常繁重:

UIOutput fieldsetStart = new UIOutput();
fieldsetStart.setRendererType("javax.faces.Text");
fieldsetStart.getAttributes().put("escape", false);
fieldsetStart.setValue("<fieldset>");

UIOutput fieldsetClose = new UIOutput();
fieldsetClose.setRendererType("javax.faces.Text");
fieldsetClose.getAttributes().put("escape", false);
fieldsetClose.setValue("</fieldset>");

HtmlInputText inputText = (HtmlInputText) app.createComponent(HtmlInputText.COMPONENT_TYPE);

form.getChildren().add(fieldsetStart);
form.getChildren().add(inputText);
form.getChildren().add(fieldsetClose);

结论:

显示的解决方案都不是真正优雅的。PrimeFaces 和 MyFaces 有很大的依赖关系,标准的 JEE 方式需要大量的编写工作。我曾希望找到一个很好的解决方案来生成未知/自定义的 HTML 元素,例如:document.createElement("fieldset");.

如果有人知道这样做的方法,请发布解决方案。

于 2014-03-06T10:29:00.127 回答