4

I'm learning how to use ajax within jsf, I made a page that does actually nothing, an input text that is filled with a number, submitted to the server, call the setter for that element with the value submitted, and display the getter's value.

Here's the simple bean's code:

@ManagedBean(name="helper",eager=true)
public class HealthPlanHelper {


    String random = "1";

    public void setRandomize(String s){
        random = s;
                System.out.println("Calling setter");
    }

    public String getRandomize(){
        return random;
    }

}

And the jsf page:

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">
<h:head></h:head>
<h:body>

    <h:form>
        <h:commandButton action="nothing">
            <f:ajax render="num"/>
        </h:commandButton>

        <h:inputText value="#{helper.randomize}" id="num"/>
    </h:form>

</h:body>
</html>

As you see, this is a request scoped bean, whenever I click the button the server shows that it creates an instance of the bean, but the setter method is never called, thus, the getter return always "1" as the value of the string.

When I remove the the setter is called normally.

BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
a.u.r
  • 1,153
  • 2
  • 19
  • 32

1 Answers1

8

The <f:ajax> processes by default only the current component (read description of execute attribute). Basically, your code is exactly the same as this:

<h:form>
    <h:commandButton action="nothing">
        <f:ajax execute="@this" render="num"/>
    </h:commandButton>
    <h:inputText value="#{helper.randomize}" id="num"/>
</h:form>

In effects, only the <h:commandButton action> is been processed and the <h:inputText value> (and any other input field, if any) is completely ignored.

You need to change the execute attribute to explicitly specify components or sections you'd like to process during the ajax request. Usually, in order to process the entire form, @form is been used:

<h:form>
    <h:commandButton action="nothing">
        <f:ajax execute="@form" render="num"/>
    </h:commandButton>
    <h:inputText value="#{helper.randomize}" id="num"/>
</h:form>

See also:

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • That worked right, does it mean that the same thing is applied to validators (not only the setter, but any process that is associated with the executed components) ? – a.u.r Jul 31 '13 at 03:24
  • 1
    That's correct. It affects all the phases between restore view and render response (grab request parameter, convert it, validate it, udpate model and invoke action). With `execute` you basically control which components should be processed during the form submit. Note that in e.g. PrimeFaces this already defaults to `@form` (and they renamed `execute` to `process` (and `render` to `update`) which makes IMO more sense). – BalusC Jul 31 '13 at 03:29