如何使用AJAX使两个JSF selectOneMenus相互依赖



我有两个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");
    }
}

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

我在这个论坛上找到了一些信息,但没有解决方案。如何制作第二个菜单来更改某些内容?还是我错了?有什么想法吗?

提前感谢!

我做了一些实验。当我将第二个菜单更改为一些用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处于活动状态时会发生这种情况?!

我怀疑JSF可能会覆盖您的尝试,因为它通常会为页面上显示的所有属性调用所有setter,并且通常在执行valueChangeListener之后执行。我从来没有见过<a4j:ajax />标签,但你可以试试<a4j:support />标签。取而代之的是:

<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的setter(而不是像JSF通常那样调用页面上的所有其他部分)。然后,您可以从setter调用valueContractorChanged(甚至只是将其作为setter的一部分)。

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

相关内容

  • 没有找到相关文章

最新更新