Search code examples
ajaxjsfjsf-2facelets

JSF - Pass a parameter on ajax call - What's wrong on this code?


I need to pass a parameter to a bean when i do an ajax call.

My bean is this :

@ManagedBean
@RequestScoped
public class Selector {
    @ManagedProperty(value="#{param.page}")
    private String page;

    @PostConstruct
    public void init() {
        if(page==null || page.trim().isEmpty()) {
            this.page="homepage";
        }

        System.out.println(this.page);
    }

    public String getPage() { return page; }
    public void setPage(String page) { this.page=page; }
}

And, when i do the ajax call, i need (due to the fact that i want to render a different context) the page parameter. So i've done this :

// in this moment selector.page = articles
<h:inputHidden value="#{selector.page}" id="page" />

<h:commandLink>
    <f:setPropertyActionListener target="#{articlesSelector.order}" value="1" />
    <f:ajax event="click" render=":articlesContent"/>
    <h:graphicImage value="img/arrow_up.png" alt="Arrow Up"/>
</h:commandLink>

But, on the Apply request phase, the page still "homepage". It should get the page-parameter from the request, apply it to the Component tree and render the "articles" context. Why doesnt happens?

Cheers


Solution

  • Because the value of <h:inputHidden> is only set during update model values phase. This is indeed an unintuitive behaviour which existed for long in JSF. I've ever reported an issue about this, but this was closed as "by design".

    There are several ways to fix this, among others the view scope. In your particular case, you can use <f:param> instead of <h:inputHidden>:

    <h:commandLink>
        <f:param name="page" value="#{selector.page}" />
        <f:setPropertyActionListener target="#{articlesSelector.order}" value="1" />
        <f:ajax event="click" render=":articlesContent"/>
        <h:graphicImage value="img/arrow_up.png" alt="Arrow Up"/>
    </h:commandLink>
    

    It will then be available as request parameter #{param.page} and in your request scoped bean thus be set as @ManagedProperty.