【问题标题】:How to make two JSF selectOneMenus that depend on each other with AJAX?如何使用 AJAX 制作两个相互依赖的 JSF selectOneMenus?
【发布时间】:2011-09-05 05:26:36
【问题描述】:

我有两个 selectOneMenu。我需要以下内容:

  1. 在第一次更改菜单时,我需要使用 AJAX 填充第二个和某些表单字段
  2. 在第二次菜单更改时,我只需要使用 AJAX 填充某些表单的字段。

在第 1 步填充第二个菜单和表单的字段是完美的,并且在第一次菜单更改之后,但是在第 2 步填充表单时存在问题。 当我更改第二个菜单的值时没有任何反应。但是当我将第二个菜单值返回给 NoSelectionOption 时,调用了 ajax 侦听器。 AJAX 侦听器似乎忽略了使用 AJAX 添加的值。

这是我的代码片段:

JSF:

<h:panelGrid>
    <h:panelGrid columns="1">
        <h:panelGrid columns="1">
            <h:panelGrid columns="2">
                <h:outputText value="Получатель:" />
                <h:selectOneMenu value="#{paymentOrder.curContractor}">
                    <f:selectItem itemLabel="Выберите контрагента .." noSelectionOption="true" />
                    <f:selectItems value="#{paymentOrder.userContractors}" var="contr"
                        itemValue="#{contr.idcontractor}"
                        itemLabel="#{contr.pnamecontractor}"/>
                    <a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="@this"/>
                </h:selectOneMenu>
            </h:panelGrid>
            <h:panelGrid columns="1">
                <h:panelGrid columns="4">
                    <h:outputText value="ИНН"/>
                    <h:inputText id="idINNContractor" value="#{paymentOrder.chosenContractor.inncontractor}"/>
                    <h:outputText value="КПП"/>
                    <h:inputText id="idKPPContractor"  value="#{paymentOrder.chosenContractor.kppcontractor}"/>
                </h:panelGrid>
                <h:panelGrid columns="2">
                    <h:outputText value="Получатель"/>
                    <h:inputTextarea id="idNameContractor" value="#{paymentOrder.chosenContractor.pnamecontractor}"/>
                </h:panelGrid>
            </h:panelGrid>
            <h:panelGrid columns="1">
                <h:panelGrid columns="2">
                    <h:outputText value="Счёт получателя:"/>
                    <h:selectOneMenu id="idContractorAccounts" value="#{paymentOrder.curContractorAccount}">
                        <f:selectItem itemLabel="Выберите счёт .."  noSelectionOption="true" />
                        <f:selectItems  value="#{paymentOrder.contractorAccounts}" var="acc"
                            itemValue="#{acc.naccountcontractor}"
                            itemLabel="#{acc.advName}"/>
                        <a4j:ajax event="valueChange" listener="#{paymentOrder.valueAccountChanged}" render="idContrAcc, idNameContrBank, idBikContrBank, idAccContrBank" execute="@this"/>
                    </h:selectOneMenu>
                </h:panelGrid>
                <h:panelGrid columns="2">
                    <h:outputText value="Сч.№"/>
                    <h:inputText id="idContrAcc" value="#{paymentOrder.curContractorAccount}"/>
                </h:panelGrid>
            </h:panelGrid>
        </h:panelGrid>      
</h:panelGrid>
<h:panelGrid columns="1">
        <h:panelGrid columns="4">   
            <h:panelGrid columns="2">
                <h:outputText value="Банк получателя"/>
                <h:inputTextarea id="idNameContrBank" value="#{paymentOrder.chosenBank.namebank}" />
            </h:panelGrid>
            <h:panelGrid columns="2">
                <h:outputText value="БИК"/>
                <h:inputText id="idBikContrBank" value="#{paymentOrder.chosenBank.bikbank}"/>
                <h:outputText value="Сч.№"/>
                <h:inputText id="idAccContrBank" value="#{paymentOrder.chosenBank.bankkorshet}"/>
            </h:panelGrid>
        </h:panelGrid>
    </h:panelGrid>
</h:panelGrid>

还有我的背豆片段:

public class PaymentOrder {

    @EJB(lookup="JpaBankBean/local")
    private JpaBankBeanLocal jpaBean;
    private Paymentdocument pDocument;
    private Paymentorder pOrder;
    private Klbankrf chosenBank;

    private String curContractorAccount;
    private String curContractorBank;
    private String curContractor;
    private String err;
    private String chosenAccount;

    private Contractor chosenContractor;
    @SuppressWarnings("rawtypes")
    private Set contractorAccounts;

    @SuppressWarnings("rawtypes")
    private List contractorBanks;
    private String userName;
    private Date nowDate;
    public PaymentOrder() {
        this.nowDate = Calendar.getInstance().getTime();
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
              setUserName(((UserDetails)principal).getUsername());
            } else {
              setUserName(principal.toString());
            }   
        pDocument = new Paymentdocument();
        pOrder = new Paymentorder();
        chosenContractor = new Contractor();
        chosenBank = new Klbankrf();
    }
    public void valueContractorChanged()
    {
        chosenContractor = jpaBean.getContractor(Integer.valueOf(getCurContractor()));
        setContractorAccounts(jpaBean.getContractorAccounts(Integer.valueOf(getCurContractor())));
        pDocument.setReceiver(chosenContractor.getPnamecontractor());
    }
    public List getUserContractors()
    {
        return jpaBean.getUserContractors(userName);
    }
    public void valueAccountChanged()
    {
        chosenBank.setNamebank("SBER");

        //TODO chosenBank = jpaBean.getContractorBank(getCurContractorAccount());
        //TODO setChosenAccount("012345678901234567890");
    }
}

因此,只有当我将第二个菜单值更改为某个值,然后再更改回 NoSelectOption 时,idNameContrBank 字段中才会出现“SBER”。这对我来说很奇怪。 我使用 RichFaces 4、JBoss AS 6。

我在forum 找到了一些信息,但没有解决方案。 如何制作第二个菜单来改变一些东西?还是我的错误?有什么想法吗?

提前致谢!

我做了一些实验。 当我将第二个菜单更改为使用 AJAX 填充的某个值时,页面会得到这样的响应:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
    <changes>
        <update id="docForm:idContrAcc">
            <![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" style=" width : 100%;" />]]>
        </update>
        <update id="docForm:idNameContrBank">
            <![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;"></textarea>]]>
        </update>
        <update id="docForm:idBikContrBank">
            <![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
        </update>
        <update id="docForm:idAccContrBank">
            <![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
        </update>
        <update id="javax.faces.ViewState"><![CDATA[3312710224811729695:3995303008700914422]]>
        </update>
    </changes>
</partial-response>

没有值,只有正确的 ID!怎么可能?为什么?

但如果我返回 NoSelectionOption 活动,则页面会得到响应

<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
    <changes>
        <update id="docForm:idContrAcc">
            <![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" value="" style=" width : 100%;" />]]>
        </update>
        <update id="docForm:idNameContrBank">
            <![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;">SBER</textarea>]]>
        </update>
        <update id="docForm:idBikContrBank">
            <![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
        </update>
        <update id="docForm:idAccContrBank">
            <![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
        </update>
        <update id="javax.faces.ViewState">
            <![CDATA[3312710224811729695:3995303008700914422]]>
        </update>
    </changes>
</partial-response>

看起来没问题 - 值已呈现!但是为什么当 NoSelectionOption 处于活动状态时会发生呢?!

【问题讨论】:

  • 等一下...您在使用 PrimeFaces 吗?难怪我从未听说过&lt;a4j:ajax /&gt;。您使用“richfaces”标记您的问题,这是一个不同的库。
  • 哦,顺便说一句,如果您使用的是泛型类型但不想指定泛型,您可以使用类似:Set&lt;?&gt;List&lt;?&gt; 而不必使用@SuppressWarnings("rawtypes")
  • 我使用的是 RichFaces 4。感谢您的旁注 :)

标签: java ajax jsf richfaces selectonemenu


【解决方案1】:

我怀疑 JSF 可能会覆盖您的尝试,因为它通常会为页面上公开的所有属性调用所有设置器,并且通常在执行 valueChangeListeners 之后执行此操作。我从未见过&lt;a4j:ajax /&gt; 标签,但你可以试试&lt;a4j:support /&gt; 标签。而不是这个:

<a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="@this"/>

试试这个:

<a4j:support event="onchange" ajaxSingle="true" reRender="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts"/>

由于ajaxSingle="true" 包含在标签中,这意味着只有curContractor 的设置器将被调用(而不是像JSF 通常那样在页面上的所有其余部分)。然后你可以从 setter 中调用valueContractorChanged(或者甚至只是让它成为 setter 的一部分)。

如果您以这种方式替换所有 &lt;a4j:ajax /&gt; 标记,您应该会得到所需的结果。通过上面的链接查看有关标签的更多信息。

【讨论】:

  • 谢谢,但是 在 RichFaces 3 中使用,我使用 RichFaces 4,它不再有
  • 我明白了,您使用的是 JSF 2.0 内置的 AJAX 标签?抱歉,我没有任何经验。
猜你喜欢
  • 2012-11-13
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 2020-02-13
  • 2010-11-11
相关资源
最近更新 更多