我找到了三个解决我的问题的方法。第一个是使用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");.
如果有人知道这样做的方法,请发布解决方案。