Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
857 views
in Technique[技术] by (71.8m points)

jsf 2 - Styling input component after validation failed

How can I style a component after validation failed?

I have the following textfield:

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

I am trying to change the color after the:

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

Is clicked.

I have found this site and tried to implement the way has been shown there.

This is my class:

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);
            }
        }
    }
}

I am registering it in faces-config.xml as:

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

Also I have tried to use

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

}

I was expecting that when the input field is invalid, for my case, blank, the css class ui-input-invalid will be added to the class attribute of the component. But it is not working. I fact the method processEvent is not executing at all.

What I am doing wrong and how can I achieve this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your concrete problem is caused because you didn't update the input component on complete of the ajax request. You're only updating the growl component. So the changes to the input component are never reflected into the client side.

I suggest to just update the entire form as it might contain other input components which also needs to be highlighted:

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

By the way, the @ListenersFor (and @ListenerFor) is misplaced here. It doesn't work that way and they're plain ignored. Get rid of them. See also How to register a (Component)SystemEventListener for all UIInputs.


Unrelated to the concrete problem, this SystemEventListener approach to highlight failed input components is flawed. It will fail when the input component is inside an iterating component such as <ui:repeat> or <h:dataTable>. It would highlight the input component in all rows even when only one of them has failed.

Better go for a client side approach instead. The JSF utility library OmniFaces offers the <o:highlight> component for exactly this purpose. See also the <o:highlight> tag documentation, the <o:highlight> showcase example and the <o:highlight> source code.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...