0

So I have this form on my login.xhtml:

<h:form id="login">
    <p:graphicImage url="img/logo.jpg" width="448" height="119"/>
    <p> Si pertenece a una empresa, inserte su usuario y password. </p>
    <p:outputLabel for="usuario" value="Usuario:" />
    <p:inputText id="usuario" value="#{loginController.login.username}"/>
    <p:outputLabel for="password" value="Password:" />
    <p:password id="password" value="#{loginController.login.password}"/>
    <p:commandButton value="Login" update="out" actionListener="#{loginController.login()}"/>
    <h:outputText id="out" />
    <a href="#"> Si no pertenece a una empresa, haga click para continuar</a>
</h:form>

When the button is clicked, this method is activated:

public String login() {
    login = service.login(login.getUsername(), login.getPassword());

    if (login.getUsername() == null) {
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Usuario y/o password incorrecto!"));
        return null;
    } else {
        return "index.jsf?faces-redirect=true";
    }
}

I am trying to validate if the user exists or not but using AJAX. So if the username and password are incorrect, I want it to display the message on the <h:outputText> without reloading the page. If it is successful, I want the redirect to happen. None of these are working.

What am I doing wrong?

Tiny
  • 27,221
  • 105
  • 339
  • 599
Erick
  • 823
  • 16
  • 37
  • Display that message using an ``. `globalOnly` is set to `true` because you need not display the message for a specific component i.e. you do not associate the given `` with a specific component in this example - you have set a `null` client id here `.addMessage(null, new FacesMessage("Usuario y/o password incorrecto!"))`. – Tiny Apr 22 '15 at 02:42
  • @Tiny: My understanding from the op was that he does not want it globally but 'on' the `h:outputText` – Kukeltje Apr 22 '15 at 05:21
  • 1
    Maybe requirement-dependent (an `` component may also be chosen). @Kukeltje – Tiny Apr 22 '15 at 05:24
  • `h:outputText` component is not designed for this requirement. As @Tiny says, use the `h:message`. – Aritz Apr 22 '15 at 06:17

2 Answers2

1

The <h:outputText> isn't designed for the purpose of displaying faces messages. You could hack around as below

<h:outputText value="#{facesContext.messageList[0].summary}" />

but this is plain ugly. You're supposed to use <h:message> or <h:messages> to show faces messages (or the PrimeFaces <p:xxx> equivalents, of course).

With addMessage(null, message) you're with the null client ID basically adding a global message. You can show them exclusively as below:

<h:messages globalOnly="true" />

You can also add a message for a specific component like so addMessage("login", message), referencing the <h:form id="login">.

context.addMessage("login", new FacesMessage("Unknown login. Perhaps you want to sign up?"));

You can the display it with a <h:message> whose for attribute references exactly that ID:

<h:message for="login" />

Of course, give it an id and refer it in <p:commandButton update>.

<p:commandButton ... update="loginMessage" />
...
<h:message id="loginMessage" for="login" />

The <p:xxx> equivalents have by the way an autoUpdate="true" attribute which removes the need to do so.

See also:


As to the redirect fail, it's caused by the PrimeFaces showcase examples being littered with actionListener instead of action on <p:commandButton> over all place, and therefore confusing starters who actually intend to invoke business actions and navigation using <p:commandButton>.

You should be using action attribute instead.

<p:commandButton ... action="#{loginController.login}" />

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you. It was really helpful but I have another question. If I wanted my login() method above not to return a String but to be void. What can I do instead of return "index.jsf?faces-redirect=true"? Since I want to make it void, I can't return something. – Erick Apr 22 '15 at 14:05
  • Use `ExternalContext#redirect()`. There are examples in this answer: http://stackoverflow.com/questions/11277366/what-is-the-difference-between-redirect-and-navigation-forward-and-when-to-use-w/11277482#11277482 – BalusC Apr 23 '15 at 06:05
  • By the way, your profile mentions "J2EE", but this was succeeded by "Java EE" nearly a decade ago. Surely you're not working with old technology? – BalusC Apr 23 '15 at 06:07
  • thank you for that comment. I recently started developing Java enterprise applications. I use modern tools like JSF 2.0, Java 8, Hibernate and SOAP web service. I guess I never understood the different between Java EE and J2EE. Now I know the difference. – Erick Apr 23 '15 at 14:22
  • 2
    So when you see "J2EE" vacancies while searching for a job, by all means skip them. Generally either the HR/Team has no idea what it's talking about, or you had to maintain a legacy J2EE monster app ;) – BalusC Apr 23 '15 at 14:36
0

On command button you are using actionListener to navigate while actionListener is used for the method which return void. If you have to navigate use "action" attribute of "h:commandButton" rather than "actionListener".

Gaurav Jeswani
  • 4,410
  • 6
  • 26
  • 47
  • Thank you for the comment. I am actually about to start studying to understand the differences between action and actionListener.@BalusC has a really good post explaining it – Erick Apr 23 '15 at 14:28
  • One more point is there that In a command button when you define both action and actionListener than first actionListener will get called and after that action will get called. – Gaurav Jeswani Apr 23 '15 at 15:09