【问题标题】:JSF ajax replace element on drop-down list selectionJSF ajax替换下拉列表选择中的元素
【发布时间】:2014-08-05 06:55:53
【问题描述】:

我有一个包含 2 列的数据表,每列都是一个下拉列表。我希望它:

1) 第二个下拉列表的选项是根据第一个下拉列表中选择的选项填充的

2) 如果第一个下拉列表选择为“其他”,则第二个下拉列表将替换为文本框。

下面是我的代码:

<p:column style="vertical-align: bottom;" headerText="Type">
   <h:selectOneMenu id="problemTypeDropdown" value="#{problem.type}">
        <f:selectItems value="#{backingBean.problemTypeList}"/>
            <p:ajax listener="#{backingBean.updateDescriptionDropdownList}"
                    update="problemDescriptionDropdown, problemDescText" />
            <f:attribute name="item" value="#{problem}"/>
            </h:selectOneMenu>
</p:column>
<p:column style="width: 200px; vertical-align: bottom;" headerText="Description">
    <h:selectOneMenu id="problemDescriptionDropdown"
                     value="#{problem.description}"
                     rendered="#{problem.type!='Other'}">
        <f:selectItems value="#{backingBean.descriptionDropdownList}"/>
    </h:selectOneMenu>
    <p:inputText id="problemDescText"
                 value="#{problem.description}"
                 rendered="#{problem.type=='Other'}"/>
</p:column>

支持 bean:

public void updateDescriptionDropdownList(AjaxBehaviorEvent event) {
    ProblemItem di = (ProblemItem)event.getComponent().getAttributes().get("item");

    if (di.getType().equals("Other"))
        return;
    descriptionDropdownList = getDescriptionList(di.getType());
}

现在可以根据第一个列表的选择填充第二个列表,但是如果第一个列表是“其他”,则第二个列表不会被文本框替换。

谁能告诉我我的代码有什么问题以及如何修复它?非常感谢。

【问题讨论】:

    标签: ajax jsf primefaces


    【解决方案1】:

    您需要将 h:selectOneMenu 和 p:inputText 放在容器/面板中,并在 ajax 事件后更新容器。

        <p:column style="vertical-align: bottom;" headerText="Type">
            <h:selectOneMenu id="problemTypeDropdown" value="#{problem.type}">
                <f:selectItems value="#{backingBean.problemTypeList}"/>
                    <p:ajax listener="#{backingBean.updateDescriptionDropdownList}"
                        update="problemDescPanel" />
                    <f:attribute name="item" value="#{problem}"/>
            </h:selectOneMenu>
        </p:column>
        <p:column style="width: 200px; vertical-align: bottom;" headerText="Description">
            <h:panelGroup id="problemDescPanel">
                <h:selectOneMenu id="problemDescriptionDropdown"
                     value="#{problem.description}"
                     rendered="#{problem.type!='Other'}">
                    <f:selectItems value="#{backingBean.descriptionDropdownList}"/>
                </h:selectOneMenu>
                <p:inputText id="problemDescText" rendered="#{problem.type=='Other'}"
                     value="#{problem.description}" />
            </h:panelGroup>
        </p:column>
    

    【讨论】:

    • 出现错误:“找不到从“form:tabView:tableId:0:problemTypeDropdown”引用的表达式为“tableId:0:problemDescPanel”的组件。我将更新路径更改为完整路径“ form:tabView:tableId:0:problemTypeDropdown" 但它仍然显示相同的错误消息。
    • 初始显示后,能否打开页面源码,在每一行查找problemDescPanel的准确id? afaik,这是 jsf 和 primefaces 的标准 id 约定,但我可能错了。另外,请尝试将form:tabView:tableId:#{rowIndex}:problemDescPanel 作为update 的完整路径。
    • 我试过了。这是错误:“找不到从“form:tabView:tableId:0:problemTypeDropdown”引用的表达式“form:tabView:tableId:0:problemDescPanel”的组件
    • 很抱歉让事情变得过于复杂(致敬并感谢 Balusc)。像这样使用时,它可以按预期工作:update="problemDescPanel"
    • 不客气。好吧,我在 mojarra 2.1.7 和 richfaces 4.3.1 中多次使用该 id 表示法/语法,但我想新版本的事情变得更简单了。您的解决方案的问题是:id 为“problemDescText”的组件最初未在页面上呈现。因此,当您尝试更新/重新渲染它时,找不到具有该 ID 的组件并且更新失败。您需要更新始终呈现在页面上的组件(在本例中为“problemDescPanel”),并有条件地呈现嵌套在其中的组件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多