我有p:accordionPanel
代表项目列表,每个标签中都有一个表单。提交任何重复表单后,可能需要额外的数据,即弹出p:dialog
时提示用户输入更多数据。该对话框是在手风琴面板之外定义的,因为与手风琴的项目不同,它们中只有一个可以一次显示,所以不需要在手风琴的每个标签中重复播放所提供的HTML。
手风琴的定义如下(简化但包含所有相关描述符):
<p:accordionPanel id="myAccordion" value="#{managedBean.getAccordionList}" var="item" multiple="false" dynamic="true" cache="true">
<p:ajax event="tabChange" listener="#{managedBean.processTabChange}"/>
<p:tab title="#{item.tabTitle}" id="itemTab">
<h:form id="itemForm">
<h:outputLabel for="itemName" value="Item Name:"/>
<p:inputText id="itemName" title="Item Name:"
maxlength="16" value="#{appeal.itemName}">
</p:inputText>
因此,为itemName
呈现的HTML在第一个实例中为myAccordion:0:itemForm:itemName
,在第二个实例中为myAccordion:1:itemForm:itemName
,等等。
对话框定义如下:
<p:dialog id="commentDialogID" header="Enter comment" widgetVar="commentDialog" modal="true" resizable="true" height="auto">
<h:form id="commentForm">
<h:outputLabel for="comment" value="Comment:"/>
<p:inputTextarea id="comment" title="Comment"
rows="6" cols="33"
value="#{managedBean.activeItem.comment}"
required="true">
<f:ajax render="comment"/>
</p:inputTextarea>
<h:commandButton value="Submit" action="#{managedBean.proceed}" onclick="PF('commentDialog').hide();">
<f:ajax render="*** ??? ***"/>
</h:commandButton>
</h:form>
</p:dialog>
我一再失败的是尝试f:ajax
仅更新手风琴面板中的一个标签,即弹出对话框的活动标签。我尝试使用
:myAccordion:#{managedBean.activeItem.displayIndex}:itemForm:itemName
:myAccordion:#{managedBean.activeItem.displayIndex}:itemForm
:myAccordion:#{managedBean.activeItem.displayIndex}:itemTab
代替*** ??? ***
,但没有一个会编译:
javax.faces.FacesException: <f:ajax> contains an unknown id ':myAccordion:0:itemForm' - cannot locate it in the context of the component j_idt20
如果我跳过索引标记(例如:myAccordion:itemForm:itemName
),它会编译,但它在功能上没有任何作用。 Item
实体类有一个getDisplayIndex
,它可以准确地返回活动标签的索引。
我的问题与this question中描述的问题非常相似,它并没有真正有一个好的答案。可能是PrimeFaces
的限制吗?
答案 0 :(得分:1)
我不知道您正在使用的Primefaces版本,但这似乎是Primefaces 5.1.1中的一个错误,我可以重新创建此问题。通过升级到Primefaces 5.2,ajax EL可以突然找到引用的id。如果需要,我可以发布MCVE。
编辑:MCVE:
<强> XHTML:强>
<h:form id="itemForm">
<p:accordionPanel id="myAccordion" binding="#{accordionView}" value="#{playgroundController.users}" dynamic="true" activeIndex="#{playgroundView.activeIndex}" var="user" multiple="false">
<p:ajax event="tabChange" update="commentDialogID"/>
<p:tab title="#{user.name}">
<h:outputLabel for="itemName" value="Item Name:" />
<p:inputText id="itemName" title="Item Name:" maxlength="16"
value="#{user.amount}">
</p:inputText>
<p:commandButton value="showDialog" onclick="PF('commentDialog').show();"></p:commandButton>
</p:tab>
</p:accordionPanel>
</h:form>
<p:dialog id="commentDialogID" header="Enter comment" widgetVar="commentDialog" modal="true" resizable="true" height="auto">
<h:form id="commentForm">
<h:outputLabel for="comment" value="Comment:"/>
<p:inputTextarea id="comment" title="Comment"
rows="6" cols="33"
value="#{playgroundView.activeIndex}"
required="true">
<f:ajax render="comment"/>
</p:inputTextarea>
<p:commandButton value="Submit" onclick="PF('commentDialog').hide();" update=":itemForm:myAccordion:#{playgroundView.activeIndex}:itemName" ></p:commandButton>
</h:form>
</p:dialog>
PlaygroundView Bean:
请注意,在此示例中,activeIndex必须具有初始值,否则此EL:
update=":itemForm:myAccordion:#{playgroundView.activeIndex}:itemName"
将错误地解决并将抛出一个错误,它无法找到引用组件的id。这当然有一个缺点,即第一个标签会在页面加载时打开,但这是另一个问题
private String activeIndex = "0";
public String getActiveIndex() {
return activeIndex;
}
public void setActiveIndex(String activeIndex) {
this.activeIndex = activeIndex;
}
PlaygroundController Bean:
private List<User> users;
@Override
public void initializeView() {
createUsers();
}
public void createUsers() {
User user1 = new User();
User user2 = new User();
User user3 = new User();
user1.setName("User123");
user1.setAmount(1);
user2.setName("User456");
user2.setAmount(2);
user3.setName("User12312345111111111111111111111111111");
user3.setAmount(3);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
userList.add(user3);
users = userList;
}
用户:强>
public class User implements Serializable {
String name;
int amount = 0;
}
答案 1 :(得分:0)
您应该在tabChange事件上更新commandButton。
<p:ajax event="tabChange" listener="#{managedBean.processTabChange}" update=":commentForm:commandButtonId"/>
render
内的<f:ajax>
属性<h:commandButton>
在呈现阶段进行评估,而不是更快。因此,如果您不更新它,它将始终指向“0”。检查浏览器开发人员工具中的源代码并检查ajax请求(总是为调试做的事情)。您将看到带有':0:'的完整clientId,并且您不会在ajax请求中看到它发生变化。