1

I want to create dynamic forms with ajax update on event. Therefore dynamic-id is important. However, binding the id attribute to a bean value causes Empty Id exception. I saw one of the stackoverflow questions that suggests use html. So I used span.

The xhtml code is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:p="http://primefaces.org/ui" template="../../templates/ui.xhtml">

    <ui:define name="content">
        <h:form id="testform">
            <ui:repeat value="#{repeat.questions}" var="question">
                <p:panelGrid columns="2">
                    <p:outputLabel value="#{question.label}"/>

                    <span id="#{question.questionCode}">
                        <p:inputText value="#{repeat.values[question.questionCode]}"
                                     rendered="#{question.type == 'TEXT'}">
                            <p:ajax event="blur" update="#{question.dependentQuestionCode}"
                                    disabled="#{empty question.dependentQuestionCode}"/>
                        </p:inputText>

                        <p:password value="#{repeat.values[question.questionCode]}"
                                    rendered="#{question.type == 'SECRET'}">
                        </p:password>

                        <p:inputTextarea value="#{repeat.values[question.questionCode]}"
                                         rendered="#{question.type == 'TEXTAREA'}">
                        </p:inputTextarea>

                        <p:selectOneRadio value="#{repeat.values[question.questionCode]}"
                                          rendered="#{question.type == 'RADIO'}" layout="grid" columns="1">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectOneRadio>

                        <p:selectOneMenu value="#{repeat.values[question.questionCode]}"
                                         rendered="#{question.type == 'SELECTONE'}">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectOneMenu>

                        <p:selectManyMenu value="#{repeat.values[question.questionCode]}"
                                          rendered="#{question.type == 'SELECTMANY'}">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectManyMenu>

                        <p:selectBooleanCheckbox
                                value="#{repeat.values[question.questionCode]}"
                                rendered="#{question.type == 'CHECKONE'}"/>

                        <p:selectManyCheckbox value="#{repeat.values[question.questionCode]}"
                                              rendered="#{question.type == 'CHECKMANY'}">
                            <f:selectItems value="#{question.options}"/>
                        </p:selectManyCheckbox>
                     </span>
                </p:panelGrid>
            </ui:repeat>

            <p:commandButton value="Submit" actionListener="#{repeat.submit}"/>
        </h:form>
    </ui:define>
</ui:composition>

However, the display is weird. It closed the span in each iteration. Why the span closed unreasonably before span close tag? enter image description here

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
st.
  • 166
  • 6
  • 24

1 Answers1

2

The <h|p:panelGrid> only divides real JSF component children into columns, not plain HTML elements.

Put that <span> (or better, <div>) as immediate child of <ui:repeat>.

<ui:repeat value="#{bean.questions}" var="question">
    <div id="#{question.code}">
        <p:panelGrid>
            ...
        </p:panelGrid>
    </div>
</ui:repeat>
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I try to update the `
    ` with `update="@(.#{question.dependentQuestionCode})"` but it couldn't update the dependent div. However, when I tried one of these `update=":testform:#{question.dependentQuestionCode}"` or `update="@(form)"` it could update. But, it is not a good approach to update the dependent div by its exact id from the parent form since I cannot know the form id it will be used. Updating the whole form is again a very bad option. Is there a way to relatively update the component?
    – st. Jun 22 '15 at 14:50
  • A `
    ` is not a JSF component. Refer a real JSF component instead. E.g. that ``.
    – BalusC Jun 22 '15 at 14:50
  • Well, I actually came here because of the need for dynamic id to update a specific component. Selecting class(styleClass in primefaces) solved my previous dynamic id problem also. On the other hand, it let me to another problem. if I staticly typed in `update="@(.q5)"` it updates, however if I put `update="@(.#{question.dependentQuestionCode})"` ajax hangs for a couple of seconds and throws exception `Error: Syntax error, unrecognized expression: .` Sorry for many problems, but I couldn't find a way debug ajax update js code behind the scene. – st. Jun 22 '15 at 16:47
  • By the way, as you suggested I changed the `
    ` part(actually removed and add a styleClass to the panelGrid): ` `
    – st. Jun 22 '15 at 16:58