In JSF, how to update a page dynamically and partially with ajax and with out form validation?

838 views Asked by At

I have a JSF 2 form like this:

<h:form>
<h:panelGrid columns="2">
<a4j:repeat value="#{dialog.departments}" var="depart">
        <h:inputText value="#{depart.name}"/>
        <h:selectOneRadio value="#{depart.hasSubdepartment}">
           <f:ajax render="@form" execute="@form" immediate="true"/>
           <f:selectItem itemValue="#{true}"/>
           <f:selectItem itemValue="#{false}"/>
        </h:selectOneRadio>

    <a4j:repeat  value="#{depart.subdepartments}" var="sub" rendered="#{depart.hasSubdepartment}">
        <h:inputText value="#{sub.name}"/>
        <h:outputText value="&#160;" />
    </a4j:repeat>
</a4j:repeat>
</h:panelGrid>
</h:form>

I have simply the form. As you could see, this form displays data structure of departments like a tree. What I want to implements is that if user switch the radio button to true, the sub-departments will be displayed, if switch to false, the sub-departments will be hidden. The problem is that:

  • If the execute value of the f:ajax tag is set to @form, the validation of the backing beans such as @NotNull and @Size will be called. But we don't want to call the validation now since we do not want to save the data now.
  • If the execute value of the f:ajax tag is set to @this, it seems that the after the ajax request, the value of the radio reverts. For example, if the radio value is false, and we click true, then after the ajax request, the value go back to false, and the sub-department part is not rendered. This will not happen if execute is set to @form.

Thanks very much if you have any idea or hint.

1

There are 1 answers

0
Aritz On

I don't have a Richfaces integrated testing environment, however I've achieved what you want in plain JSF (that's why it could be an ajax4jsf specific issue). Here you have a test case which works and follows SSCCE standards. Tested with Mojarra 2.1.26 & Tomcat 6:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head />

<h:body>
    <h:form>
        <h:panelGrid columns="2">
            <ui:repeat value="#{dialog.departments}" var="depart">
                <h:inputText value="#{depart.name}" />
                <h:selectOneRadio value="#{depart.hasSubdepartments}">
                    <f:ajax render="@form" immediate="true" />
                    <f:selectItem itemValue="#{true}" />
                    <f:selectItem itemValue="#{false}" />
                </h:selectOneRadio>

                <h:panelGroup id="subdepartmentPanel"
                    rendered="#{depart.hasSubdepartments}">
                    <ui:repeat value="#{depart.subdepartments}" var="sub">
                        <h:inputText value="#{sub.name}" />
                    </ui:repeat>
                </h:panelGroup>
            </ui:repeat>
        </h:panelGrid>
    </h:form>
</h:body>
</html>
@ManagedBean
@ViewScoped
public class Dialog {

    public class Department {
        private String name;

        private List<Department> subdepartments = new ArrayList<Dialog.Department>();

        private boolean hasSubdepartments;

        public Department(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public List<Department> getSubdepartments() {
            return subdepartments;
        }

        public boolean isHasSubdepartments() {
            return hasSubdepartments;
        }

        public void setHasSubdepartments(boolean hasSubdepartments) {
            this.hasSubdepartments = hasSubdepartments;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setSubdepartments(List<Department> subdepartments) {
            this.subdepartments = subdepartments;
        }
    }

    private List<Department> departments = new ArrayList<Dialog.Department>();

    public Dialog() {
        // Create departments and subdepartments
        departments.add(new Department("First Department"));
        Department d = new Department("Second department");
        d.getSubdepartments().add(new Department("Subdepartment"));
        departments.add(d);
    }

    public List<Department> getDepartments() {
        return departments;
    }

}