sergionni
sergionni

Reputation: 13510

h:dataTable content displayed on .jsf page load,instead of commandLink click only

Looks like simple,but doesn't work)

When .jsf page is loaded ,values from DB is shown.
dao impl chunk:

public List<Product> getProducts() {
    return getHibernateTemplate().find("from Product");

}

managed bean chunk:

public List<Product> getProducts() {
    return this.getProductManager().getProducts();
}

I intented,that f:ajax does this work by click only:

         <h:form>

            <h:commandLink value="show" action="nothing">
                <f:ajax render="pr"/>
            </h:commandLink>


            <h:dataTable var="product" id="pr" value="#{showProducts.products}">
                  <h:column>#{product.name}</h:column>
            </h:dataTable>

         </h:form>

And the data is visible on page,when it's loaded. With Firebug I can see,that data is refreshed by click, so ajax does it's work.

Do I need additional attributes for h:dataTable element for table content to be displayed on click only?

Thank you.

Upvotes: 2

Views: 2854

Answers (1)

BalusC
BalusC

Reputation: 1108782

You need to hide the datatable on initial request and let the commandlink toggle a boolean where the datatable's rendered attribute is depending on.

Facelets:

<h:form>
    <h:commandLink value="show" action="#{showProducts.toggleShow}">
        <f:ajax render="products"/>
    </h:commandLink>
    <h:panelGroup id="products">
        <h:dataTable var="product" value="#{showProducts.products}" rendered="#{!showProducts.show}">
            <h:column>#{product.name}</h:column>
        </h:dataTable>
    </h:panelGroup>
</h:form>

Bean:

private boolean show;

public void toggleShow() {
    show = !show; // Or just show = true;
}

public boolean isShow() {
    return show;
}

That said, it's not the best practice to run expensive business/database logic inside a getter. A getter can be called more than once in bean's life. Rather do this job in bean's constructor or @PostConstruct method.

private List<Product> products;

@PostConstruct
public void init() {
    products = this.getProductManager().getProducts();
}

public List<Product> getProducts() {
    return products;
}

Or if it actually needs to be lazily loaded, then rather do so:

private List<Product> products;

public List<Product> getProducts() {
    if (products == null) {
        products = this.getProductManager().getProducts();
    }
    return products;
}

Upvotes: 1

Related Questions