我正在研究旧系统,它使用jsf1.2在当天写回了很多代码。现在我的任务是在按钮点击时通过ajax动态添加/删除输入元素组。
我在this post的指导下如何动态添加输入字段,进行了一些调整以支持ajax,并证明了概念非常合理。
现在,当我使用自己的自定义标记组件而不是<h:inputText> .. </h:inputText>
或其他表单字段时,会出现问题。
使用自定义标签时,我会在页面加载时显示页面,但如果我尝试删除项目,则对于列表中的第一个组件,我会收到错误java.io.IOException: Cannot add the same component twice: editform:parentTable:0:fieldsTable:0:HTML_TITLE_INPUT_en
我认为问题是由于组件树已经在组件树中,当自定义标签尝试在回发时再次添加它时,但我仍然不知道如何解决问题。
注1:我必须使用自定义标签,因为它里面有很多逻辑,它用于显示每种类型的表单字段(inputText,textarea,checkboxes等)
xhtml代码:
<h:dataTable id="parentTable" value="#{bean.groups}" var="group" styleClass="parentTableStyleClass">
<h:column>
<h:dataTable id="fieldsTable" value="#{group.fields}" var="field">
<h:column>
<h:outputLabel value="#{field.label}" styleClass="col-sm-2 control-label" />
</h:column>
<h:column>
<customTag:propertyValue
name="#{field.name}"
operation="edit"
instance="#{bean.instance}"
styleClass="form-control"
inputWrapperClass="col-sm-5"/>
</h:column>
</h:dataTable>
</h:column>
<h:column>
<p:commandButton value="Remove Group"
styleClass="btn btn-secondary btn-sm"
action="#{bean.removeGroup(group)}"
process="@(.parentTableStyleClass)"
update="@(.parentTableStyleClass)" />
</h:column>
</h:dataTable>
标签类:
public void encodeBegin(FacesContext context) throws IOException {
getChildren().clear();
...
// bunch of logic
...
HtmlPanelGroup wrapper = new HtmlPanelGroup();
HtmlInputText inputText = new HtmlInputText();
...
// bunch of code creating input text field
...
wrapper.setStyleClass(getInputWrapperClass() + " input-group");
wrapper.getChildren().add(inputText);
getChildren().add(wrapper);
}