Ajax – Primefaces 3.3/3.4 tabview: ajax update on tabChange

ajaxjsf-2primefaces

Using the following code, the content of the two tabs is cleared on tabChange event instead of being updated:

<h:form id="form">
    <p:tabView id="tabview">
        <p:ajax event="tabChange" listener="#{testBean.onChange}" update="@form"/>
        <p:tab title="Tab 1">
            <h:outputText value="Lorem ipsum dolor sit amet." id="ht1"/>
        </p:tab>
        <p:tab title="Tab 2">
            <h:outputText value="Donec et mi et arcu commodo hendrerit." id="ht2"/>
        </p:tab>
    </p:tabView>
</h:form>

The onChange method is an empty method is my test code.

I'm missing something here but I can't find what. What am I doing wrong?

EDIT

I'm using a ViewScoped bean.

I've tried update="@form", update=":form" and update=":form:tabview", the same problem occurs.

If I use update="ht1, ht2", everything is fine but in my onChange method, I would like to select programmatically the tab I want to be active (there is a treatment in my real code that validates some data: if the validation fails, I'd like to stay on tab 1, if it's ok, go to tab 2). To achieve that, I guess I must update the whole tabview component and not only the tabs' content. But maybe I'm wrong?

Full code

I made a few changes, here's my updated code that still doesn't work.

Managed bean:

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.TabChangeEvent;

@ManagedBean
@ViewScoped
public class TestBean implements Serializable {

    private int idx;
    private String s1 = "test 1";
    private String s2 = "test 2";

    public TestBean() {
        System.out.println("TestBean.init");
    }

    public void onChange(TabChangeEvent e){
        s1 = "TEST TEST";
        s2 = "TEST TEST";
    }

    public int getIdx() {
        return idx;
    }

    public void setIdx(int idx) {
        this.idx = idx;
    }

    public String getS1() {
        return s1;
    }

    public void setS1(String s1) {
        this.s1 = s1;
    }

    public String getS2() {
        return s2;
    }

    public void setS2(String s2) {
        this.s2 = s2;
    }
}

Facelet:

<?xml version='1.0' encoding='UTF-8' ?>
<!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:p="http://primefaces.org/ui">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form id="form">
            <p:tabView id="tabview" activeIndex="#{testBean.idx}">
                <p:ajax event="tabChange" listener="#{testBean.onChange}" update="@form"/>
                <p:tab title="Tab 1">
                    <h:outputText value="#{testBean.s1}" id="ht1"/>
                </p:tab>
                <p:tab title="Tab 2">
                    <h:outputText value="#{testBean.s2}" id="ht2"/>
                </p:tab>
            </p:tabView>
            <h:messages/>
        </h:form>
    </h:body>
</html>

UPDATE

I changed my Primefaces jar from 3.4 to 3.2 and magic, this behaviour doesn't happen anymore. I tried then with 3.3 and boom, error. I'm going to ask on the Primefaces forum if this is a known bug.

Best Answer

You should use activeIndex

 <p:tabView id="tabview" activeIndex="#{testBean.tabIndex}" >

And in your onchange method, after validation set the correct tabindex.

Related Topic