如何磷单标签AJAX的更新组件:accordionPanel从外面?组件、标签、AJAX、accordionPanel

2023-09-10 19:44:15 作者:空城旧梦忆悲伤

我有一个号码:accordionPanel 从而重新presents项目的列表,并在每个标签有一个形式。在提交任何重复的形式,它有可能额外需要的数据,这是当一个号码:对话框弹出,提示用户输入更多的数据。该对话框手风琴面板之外定义,因为不像从手风琴的物品,它们中只有一个可以表示在一个时间,因此,没有必要来增加通过重复它在手风琴的每个选项卡服务HTML

手风琴的定义如下所示(简化,但所有相关的描述符):

 <电话号码:accordionPanel ID =myAccordion值=#{managedBean.getAccordionList}VAR =项目多=假动态=真正的缓存=真正的>

    <电话号码:AJAX事件=tabChange监听器=#{managedBean.processTabChange}/>

    <电话号码:分页标题=#{item.tabTitle}ID =itemTab>

        < H:格式ID =itemForm>

            < H:outputLabel为=了itemname值=产品名称:/>
            <电话号码:inputText的ID =了itemname称号=项目名称:
                    MAXLENGTH =16值=#{appeal.itemName}>
            < / P:inputText的>
 

因此​​,呈现为了itemname 的HTML是 myAccordion:0:itemForm:了itemname 在一审, myAccordion:1:itemForm:了itemname 第二,等等

对话框定义如下:

 <电话号码:对话ID =commentDialogID标题=输入注释widgetVar =commentDialog模式=真正的调整大小=真正的高度=自动>
    < H:格式ID =commentForm>

        < H:outputLabel为=意见的价值=评论:/>

        <电话号码:inputTextarea ID =意见标题=注释
                行=6COLS =33
                值=#{managedBean.activeItem.comment}
                所需=真正的>
            < F:AJAX渲染=意见/>
        < / P:inputTextarea>

        < H:的commandButton值=提交行动=#{managedBean.proceed}的onclick =PF('commentDialog')隐藏();>
            < F:AJAX渲染=*** ??? ***/>
        < / H:的commandButton>

    < /小时:形式GT;
< / P:对话框>
 

我曾多次被拜倒在都试图 F:AJAX 更新手风琴面板只有一个选项卡中,活跃的地区之一,从该对话框被弹出。我试图用

 :myAccordion:#{managedBean.activeItem.displayIndex}:itemForm:了itemname
:myAccordion:#{managedBean.activeItem.displayIndex}:itemForm
:myAccordion:#{managedBean.activeItem.displayIndex}:itemTab
 
JavaScript Ajax

代替的*** ??? *** ,但没有人会编译:

  javax.faces.FacesException:< F:AJAX>包含未知的ID:myAccordion:0:itemForm - 无法找到它的成分j_idt20的背景下
 

如果我跳过索引标记(例如:myAccordion:itemForm:了itemname )它编译,但它在功能上没有什么。该项目实体类有一个 getDisplayIndex 这并不准确返回当前选项卡的索引。

我的问题是非常相似,这在这个问题,它并没有真正有一个很好的答案。难道是 PrimeFaces

的限制 解决方案

我不知道是什么版本构建Primefaces您正在使用的,但是这似乎是在Primefaces 5.1.1中的错误,我可以重现这个问题。通过升级到Primefaces 5.2,Ajax的EL会突然发现被引用的ID。如果需要,我可以张贴MCVE。

编辑:MCVE:

XHTML:

 < H:格式ID =itemForm>
    <电话号码:accordionPanel ID =myAccordion绑定=#{accordionView}值=#{playgroundController.users}动态=真正的activeIndex =#{playgroundView.activeIndex}VAR =用户多= 假>

        <电话号码:AJAX事件=tabChange更新=commentDialogID/>

        <电话号码:分页标题=#{user.name}>
                < H:outputLabel为=了itemname值=产品名称:/>
                <电话号码:inputText的ID =了itemname称号=项目名称:最大长度=16
                    值=#{user.amount}>
                < / P:inputText的>
                <电话号码:的commandButton值=的ShowDialog的onclick =PF(commentDialog)显示();>< / P:的commandButton>
        < / P:标签>

    < / P:accordionPanel>
< /小时:形式GT;

<电话号码:对话ID =commentDialogID标题=输入注释widgetVar =commentDialog模式=真正的调整大小=真正的高度=自动>
    < H:格式ID =commentForm>

        < H:outputLabel为=意见的价值=评论:/>

        <电话号码:inputTextarea ID =意见标题=注释
                行=6COLS =33
                值=#{playgroundView.activeIndex}
                所需=真正的>
            < F:AJAX渲染=意见/>
        < / P:inputTextarea>

        <电话号码:的commandButton值=提交的onclick =PF('commentDialog')隐藏();。更新=:itemForm:myAccordion:#{playgroundView.activeIndex}:了itemname>< / P:的commandButton>

    < /小时:形式GT;
< / P:对话框>
 

PlaygroundView豆:

请注意,在这个例子中activeIndex必须具有一个初始值,否则该EL:的

 更新=:itemForm:myAccordion:#{playgroundView.activeIndex}:了itemname
 

将解析错误,将抛出一个错误,它无法找到引用的组件的ID。这当然有缺点,即第一个选项卡将在页面加载时开放,但这是另一个问题

 私人字符串activeIndex =0;

公共字符串getActiveIndex(){
    返回activeIndex;
}

公共无效setActiveIndex(字符串activeIndex){
    this.activeIndex = activeIndex;
}
 

PlaygroundController豆:

 私人列表<使用者>用户;
@覆盖
    公共无效initializeView(){
    createUsers();
}

公共无效createUsers(){
        用户USER1 =新用户();
        用户user2 =新用户();
        用户用户3 =新用户();
        user1.setName(User123);
        user1.setAmount(1);
        user2.setName(User456);
        user2.setAmount(2);
        user3.setName(User12312345111111111111111111111111111);
        user3.setAmount(3);
        清单<使用者>用户列表=新的ArrayList<使用者>();
        userList.add(用户1);
        userList.add(用户2);
        userList.add(用户3);
        用户=用户列表;
    }
 

用户:

 公共类用户实现Serializable {
    字符串名称;
    INT量= 0;
}
 

I have a p:accordionPanel which represents a list of items and in each tab there is a form. Upon submitting any of the repeating forms, it is possible that extra data in needed, which is when a p:dialog is popped up prompting the user to enter some more data. That dialog is defined outside the accordion panel because, unlike the items from the accordion, only one of them can be showing at a time so there is no need to augment the HTML served by repeating it in each tab of the accordion.

The definition of the accordion looks as follows (simplified but with all the relevant descriptors):

<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>

Consequently, the HTML rendered for itemName is myAccordion:0:itemForm:itemName in the first instance, myAccordion:1:itemForm:itemName in the second, etc.

The dialog is defined as follows:

<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> 

What I have repeatedly been failing at are attempts to f:ajax update only a single tab in the accordion panel, the active one from which the dialog was popped up. I tried using

:myAccordion:#{managedBean.activeItem.displayIndex}:itemForm:itemName
:myAccordion:#{managedBean.activeItem.displayIndex}:itemForm
:myAccordion:#{managedBean.activeItem.displayIndex}:itemTab

in place of *** ??? *** but none of them would compile:

javax.faces.FacesException: <f:ajax> contains an unknown id ':myAccordion:0:itemForm' - cannot locate it in the context of the component j_idt20

If I skip the index token (e.g. :myAccordion:itemForm:itemName) it does compile but it does functionally nothing. The Item entity class has a getDisplayIndex which does accurately return the index of the active tab.

My problem is quite similar to that which is described in this question, which doesn't really have a good answer. Could it be a limitation of PrimeFaces?

解决方案

I don't know what verion of Primefaces you are using, but this seems to be a bug in Primefaces 5.1.1 where i could recreate this issue. By upgrading to Primefaces 5.2, the ajax EL could suddenly find the referenced id. I can post a MCVE if needed.

Edit: The 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:

Note that in this example the activeIndex has to have an initial value, otherwise this EL:

update=":itemForm:myAccordion:#{playgroundView.activeIndex}:itemName"

will resolve wrongly and will throw an error that it cannot find the id of the referenced component. This of course has the drawback that the first tab will be open when the page loads, but that's another issue

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;
    }

User:

public class User implements Serializable {
    String name;
    int amount = 0;
}