Стилизация компонента ввода после сбоя проверки

Как я могу стилизовать компонент после неудачной проверки?

У меня есть следующее текстовое поле:

<p:inputText id="username" value="#{authController.username}" autocomplete="off" required="true" />

Я пытаюсь изменить цвет после:

<p:commandButton id="submit" value="Login" actionListener="#{authController.login}" update=":growl" />

Нажимается.

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

Это мой класс:

public class RequiredFieldValidationListener implements SystemEventListener {

    public boolean isListenerForSource(Object source) {
        return true;
    }

    public void processEvent(SystemEvent event) throws AbortProcessingException {
        if (event.getSource() instanceof UIInput) {
            UIInput source = (UIInput) event.getSource();

            if (!source.isValid()) {
                String originalStyleClass = (String) source.getAttributes().get("styleClass");
                source.getAttributes().put("data-originaStyleClass", originalStyleClass);
                source.getAttributes().put("styleClass", originalStyleClass + " ui-input-invalid");
            } else {
                String originalStyleClass = (String) source.getAttributes().get("data-originaStyleClass");
                source.getAttributes().put("styleClass", originalStyleClass);
            }
        }
    }
}

Я регистрирую его в faces-config.xml как:

<application>
    ---

    <system-event-listener>
        <system-event-listener-class>com.edfx.adb.web.event.RequiredFieldValidationListener</system-event-listener-class>
        <system-event-class>javax.faces.event.PostValidateEvent</system-event-class>
        <source-class>javax.faces.component.html.HtmlInputText</source-class>                       
    </system-event-listener>

</application>

Также я пытался использовать

@ListenersFor({ @ListenerFor(sourceClass = HtmlInputText.class, systemEventClass = PostValidateEvent.class) })
public class RequiredFieldValidationListener implements SystemEventListener {

}

Я ожидал, что когда поле ввода недействительно, для моего случая пусто, класс css ui-input-invalid будет добавлен к атрибуту класса компонента. Но это не работает. На самом деле метод processEvent вообще не выполняется.

Что я делаю неправильно и как я могу этого добиться?


person Tapas Bose    schedule 08.12.2012    source источник


Ответы (2)


Ваша конкретная проблема вызвана тем, что вы не обновили компонент ввода при завершении запроса ajax. Вы только обновляете компонент рычания. Таким образом, изменения во входном компоненте никогда не отражаются на стороне клиента.

Я предлагаю просто обновить всю форму, так как она может содержать другие компоненты ввода, которые также необходимо выделить:

<p:commandButton ... update="@form" />

Кстати, @ListenersFor@ListenerFor) здесь неуместны. Это не работает таким образом, и они просто игнорируются. Избавься от них. См. также Как зарегистрировать (Component)SystemEventListener для всех UIInputs.


Не связанный с конкретной проблемой, этот SystemEventListener подход к выявлению неисправных входных компонентов ошибочен. Это не удастся, если входной компонент находится внутри повторяющегося компонента, такого как <ui:repeat> или <h:dataTable>. Компонент ввода будет выделен во всех строках, даже если не удалось выполнить только одну из них.

Вместо этого лучше использовать подход на стороне клиента. Библиотека утилит JSF OmniFaces предлагает компонент <o:highlight> именно для этой цели. См. также документацию по тегу <o:highlight>, пример <o:highlight> витрины и исходный код <o:highlight>.

person BalusC    schedule 09.12.2012
comment
Хех, почти всегда у омнифейсов вроде есть то, что нужно. Очень хорошо :) - person Aksel Willgert; 09.12.2012
comment
@Aksel: это именно философия OmniFaces :) - person BalusC; 09.12.2012
comment
Спасибо BalusC, очень хорошее решение, и оно работает. В первую очередь это не работало, так как я установил <context-param><param-name>javax.faces.PARTIAL_STATE_SAVING</param-name><param-value>false</param-value></context-param> в своем web.xml, после удаления этого параметра контекста он работает. Я хотел бы знать, какова связь между этим параметром контекста и o:highlight? Есть ли способ использовать оба из них? - person Tapas Bose; 09.12.2012
comment
Также есть еще один момент, который я хотел бы вам сказать, что я оставил два поля ввода пустыми и нажал кнопку, после чего эти два поля ввода стали окрашены. После этого я заполняю любой из них и снова нажимаю кнопку, я ожидал, что будет выделен только тот ввод, который пуст, но на практике я увидел, что ранее выделенный ввод все еще выделен, после поджога я обнаружил, что класс css ошибка все равно есть. Это фактическое поведение? Как я могу решить эту проблему? - person Tapas Bose; 09.12.2012
comment
У него тот же ответ, что и на ваш первоначальный вопрос: обновить форму при отправке. Что касается частичного сохранения состояния, спасибо, я не знал о таком поведении и посмотрю на него. - person BalusC; 09.12.2012
comment
Извините, не удается воспроизвести не работает проблема с отключенным сохранением частичного состояния (снимок OmniFaces 1.3 и Mojarra 2.1.14). Не стесняйтесь сообщать в систему отслеживания проблем OmniFaces вместе с конкретным WAR, демонстрирующим проблему. - person BalusC; 09.12.2012
comment
Здравствуйте @BalusC, я создал тикет: code.google.com/ p/omnifaces/issues/detail?id=110 - person Tapas Bose; 10.12.2012

Я попробовал связанный пример и получил SystemEventListener.processEvent() для запуска при использовании

<h:inputText ... required="true"/>

Итак, я решил, что это связано с Faces-config.xml. Указание первичных граней InputText в качестве исходного класса сделало свое дело:

<application>
    <system-event-listener>
        <system-event-listener-class>RequiredFieldValidationListener</system-event-listener-class>
        <system-event-class>javax.faces.event.PostValidateEvent</system-event-class>
        <source-class>org.primefaces.component.inputtext.InputText</source-class>
    </system-event-listener>
</application>

использовать

<p:inputText ... required="true"/>
person Aksel Willgert    schedule 09.12.2012
comment
Спасибо. Теперь метод выполняется, но source.getAttributes().get("styleClass"); возвращает null, также я пытался перебрать Map source.getAttributes(), чтобы увидеть его элементы, но такого ключа нет, я нашел только две пары ключ-значение: javax.faces.component.VIEW_LOCATION_KEY : /login.xhtml @21,44 com.sun.faces.facelets.MARK_ID : 2030916047_790d5125. Также другие функции, например, у меня есть Growl, который показывал сообщения об ошибках проверки обязательных полей, больше не отображаются. Я пытался разыграть его с InputText вместо UIInput, но безуспешно. - person Tapas Bose; 09.12.2012