Что вызывает полный запрос на этой странице?

Рассмотрим следующую страницу jsf:

<h:body>
    <h:form id="SessionStartDialog">
        <table>
            <tr>
                <td class="label">
                    <h:outputLabel
                        value="Enter your username:" 
                        for="UsernameField"/>
                </td>
                <td class="input">
                    <h:inputText 
                        id="UsernameField"
                        value="#{login.username}"
                        validator="#{login.validateUsername}"
                        tabindex="1">
                        <f:ajax render="SelectWorkingSetListbox
                                StartSessionButton UsernameMessage" />
                    </h:inputText>
                    <h:message 
                        id="UsernameMessage"
                        for="UsernameField" />
                </td>
            </tr>
            <tr>
                <td class="label">
                    <h:outputLabel
                        value="Choose a working-set:" 
                        for="SelectWorkingSetListbox"/>
                </td>
                <td class="input">
                    <h:selectOneMenu
                        id="SelectWorkingSetListbox"
                        tabindex="2"
                        disabled="#{!login.showWorkingSets}"
                        value="#{login.selectedWorkingSetName}">
                        <f:selectItems 
                            value="#{login.workingSetNames}"/>
                        <f:ajax />
                    </h:selectOneMenu>
                </td>
            </tr>
        </table>
        <h:commandButton 
            id="StartSessionButton"
            styleClass="StartSessionButton"
            disabled="#{!login.showWorkingSets}"
            value="Start Session" 
            tabindex="3"
            action="#{login.startSession}" >
            <f:ajax execute="@form"/>
        </h:commandButton>
    </h:form>
</h:body>

Что-то там заставляет Safari сообщать об ошибке, что ajax и полные запросы смешиваются. Не понимаю почему, ведь все компоненты, вызывающие запросы, содержат <f:ajax>-теги. В чем проблема?

Обновление:

Я создал минимальный пример, который вызывает эту ошибку:

<h:body>
    <h:form>
        <f:ajax render="TextField">
            <h:inputText value="#{theBean.text}" />                
        </f:ajax>
        <h:outputText id="TextField" value="#{theBean.text}" />
    </h:form>
</h:body>

theBean — это простой bean-компонент с областью видимости, а text — свойство типа String. По какой-то причине это вызывает следующее сообщение в Safari 5.1:

httpError: Http Transport вернул код состояния 0. Обычно это результат смешивания ajax и полных запросов. Обычно это нежелательно как по причинам производительности, так и по причинам целостности данных.

Обновление 2 Причина этого, по-видимому, в том, что нажатие enter внутри поля input всегда вызывает отправку полной формы. Я понятия не имею, как предотвратить это. Как показано в первом примере, я хочу, чтобы пользователь ввел имя пользователя, а затем активируются другие компоненты формы (только если имя пользователя известно). Как бы мне реализовать это правильно?


person Björn Pollex    schedule 11.08.2011    source источник
comment
При событии какого компонента происходит полная обратная передача? При нажатии кнопки или других компонентах?   -  person Niks    schedule 12.08.2011
comment
@Nikhil: Это мой вопрос. Я не знаю. Я получаю сообщение, когда ввожу что-то в компонент h:inputText.   -  person Björn Pollex    schedule 12.08.2011
comment
Это происходит только в Safari? А как насчет других браузеров?   -  person Mateusz Dymczyk    schedule 20.08.2011
comment
@Zenzen: Firefox выдает то же сообщение. У меня сейчас нет другого браузера для тестирования.   -  person Björn Pollex    schedule 20.08.2011


Ответы (2)


Я бы захватил клавишу Enter на <form> и вместо этого активировал onchange на элементе <input>, где эта клавиша была нажата.

<h:form onkeydown="enterToChange(event)">
    ...
</h:form>

с участием

function enterToChange(event) {
  if (event.keyCode == 13 && event.target.tagName != 'textarea') {
    event.stopPropagation(); // Don't bubble up.
    event.preventDefault();  // Prevent default behaviour (submitting the form).
    event.target.onchange(); // Trigger onchange where key was actually pressed.
  }
}

Обратите внимание, что это игнорирует клавишу ввода в текстовых областях, где вы, конечно, хотели бы сохранить предполагаемое поведение (вставка новой строки).

При необходимости вы можете добавить дополнительную проверку, чтобы убедиться, что кнопка отправки не disabled, и если это так, то просто отпустите событие.

person BalusC    schedule 22.08.2011

Причина проблемы заключается в том, что при отсутствии <h:commandButton> (в первом примере он изначально отключен, во втором примере его нет) нажатие return вызовет отправку всей формы, что приведет к ошибке, показанной на вопрос.

На данный момент решение состоит в том, чтобы <h:commandButton> всегда был включен. Поскольку он <f:ajax> включен, это предотвратит полную отправку.

P.S.: я разместил этот ответ, чтобы показать возможное решение для других. Я все еще хотел бы знать, есть ли лучшее решение (такое, которое не требует наличия <h:commandButton>).

person Björn Pollex    schedule 20.08.2011