Как сделать два JSF selectOneMenus, которые зависят друг от друга с AJAX? - PullRequest
1 голос
/ 31 мая 2011

У меня есть два 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");
    }
}

Таким образом, «SBER» появляется в поле idNameContrBank, только если я изменяю значение второго меню на somethig, а затем возвращаюсь в NoSelectOption.Это странно для меня.Я использую 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>

Нет значений, но есть правильные идентификаторы!Как это может быть?Почему?

Но если я верну NoSelectionOption active, то страница получит ответ

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

1 Ответ

1 голос
/ 31 мая 2011

Я подозреваю, что JSF может перезаписывать ваши попытки, поскольку он обычно вызывает все установщики для всех свойств, представленных на странице, и обычно делает это после выполнения valueChangeListener s.Я никогда не видел тег <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 (а невсе остальное на странице, как обычно делает JSF).Затем вы можете вызвать valueContractorChanged из установщика (или даже сделать его частью установщика).

Если вы замените таким образом все теги <a4j:ajax />, вы получите желаемый результат.Проверьте больше информации о теге по ссылке выше.

...