0

I am novice for JSF and I have a problem with my very simple Facelets view:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core" >
<h:head>
<title></title>
</h:head>
<h:body>

<h:form id="form">
    <h:panelGrid id="ciccio" columns="2">
    <h:outputText value="Nome " />
    <h:inputText value="#{thinBean.nome}" />
        <h:commandButton id="ok" value="OK"  />
        <h:commandButton id="vai" value="Go" rendered="#{not empty thinBean.nome}" action="Vista1" />
    </h:panelGrid>
</h:form>
</h:body>

</html>

and with my simple Backing Bean.

package magazzino;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean
@RequestScoped
public class ThinBean implements Serializable {

    private String nome;

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }
}   

After first call, only first button appears. When I entered test on the field nome and submit this form by clicking button identified by ok, also second button appears.

When I click on second button, identified by vai, nothing happen: Vista1 is not rendered.

I don't understand this behavior: why Invoke Application phase is skipped?

Thanks

Vasil Lukach
  • 3,658
  • 3
  • 31
  • 40
  • Where did you map the action of `` to the backing bean? – Tiny Feb 10 '14 at 17:57
  • hello, is there mandatory mapping action whith a backing bean method? – Fabrizio Ferracuti Feb 10 '14 at 18:21
  • No but are you doing a navigation? The `action` attribute of ``, `action="Vista1"` is supposed to be used as navigation case outcome (the target view). – Tiny Feb 10 '14 at 18:31
  • 2
    @Tiny if you have a managed bean with a method returning `"someString"` then it is the same doing `` and ``. Fabrizio: Looks like since your bean is `@RequestScoped`, the value of `nome` will be `null` when creating the bean in the request, thus the command button should not be rendered, causing a whole mess. It would be better to change the scope of your bean to `@ViewScoped` at least. Also, make sure you have a view with name Vista1 (typically by having a Vista1.xhtml file). – Luiggi Mendoza Feb 10 '14 at 19:34

1 Answers1

2

The rendered attribute of an UICommand component is also evaluated during apply request values phase, as part of safeguard against tampered/hacked requests wherein hackers try to invoke actions of UICommand components which are not rendered for non-admin users, for example.

In your particular case, you're using a request scoped bean. Thus, the bean is destroyed by end of every request and recreated in beginning of every request. Submitting the form by the first button counts as one request. Submitting the form by the second button counts as another request.

The UIInput values are set as managed bean property during update model values phase, which is after the apply request values phase. Thus, when the second button is pressed, the request scoped bean is newly created with all properties set to default (null). During apply request values phase, the rendered attribute is checking the input value, but it isn't been set yet and the bean is new and empty. So it won't consider the button as rendered and skip the decoding of the action event.

If you put the bean in the view scope, then it'll work for the very simple reason that the view scoped bean instance will live as long as you're interacting with the same view by returning null or void.

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean
@ViewScoped

An alternative is checking the raw HTTP request parameter in the rendered attribute instead of the model value.

<h:inputText binding="#{nome}" value="#{thinBean.nome}" />
<h:commandButton id="ok" value="OK"  />
<h:commandButton id="vai" value="Go" rendered="#{not empty param[nome.clientId]}" action="Vista1" />

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555