7 Replies Latest reply on Feb 23, 2009 11:57 AM by Ronan Forker

    Submitting dynamic form in ModalPanel

    Ronan Forker Newbie

      Hi,

      I have created a test case to illustrate a problem I am seeing.

      I am trying to create a forum of dynamically loaded inputs which is presented to the user in a ModalPanel. The form loads with the correct default values however the list containing the values is not set upon form submition.

      JSF:

      <f:view>
       <h:form id="metaForm">
       <div>
       <h:outputText value="#{testBean.listOutput}" id="listOutput" escape="false"/>
       </div>
       <div>
       <a4j:commandLink value="Edit" id="editLink" style="float:right;">
       <a4j:support event="onclick" oncomplete="#{rich:component('metadataEditModelPanel')}.show()"
       reRender="metaEditPanel" eventsQueue="metaEvents" ignoreDupResponses="true"/>
       </a4j:commandLink>
       </div>
       </h:form>
       <f:subview id="metadataEditModelPanelView">
       <h:form id="panelForm2">
       <div>
       <rich:modalPanel id="metadataEditModelPanel" width="300" height="400">
       <f:facet name="header">
       <h:panelGroup>
       <h:outputText value="Edrms alert"></h:outputText>
       </h:panelGroup>
       </f:facet>
       <f:facet name="controls">
       <h:panelGroup>
       <h:graphicImage value="../images/close.png" styleClass="hidelink" id="hidelink"/>
       <rich:componentControl for="metadataEditModelPanel" attachTo="hidelink" operation="hide"
       event="onclick"/>
       </h:panelGroup>
       </f:facet>
      
       <h:panelGroup id="metaEditPanel" binding="#{testBean.metaPanelGroup}"/>
       <div>
       <a4j:commandButton value="Save" id="templateSubmit" action="#{testBean.saveEditedMetadata}"
       style="width:60px" eventsQueue="metaEvents" ignoreDupResponses="true"
       oncomplete="#{rich:component('metadataEditModelPanel')}.hide()"
       reRender="listOutput"/>
       </div>
       </rich:modalPanel>
       </div>
       </h:form>
       </f:subview>
      
      </f:view>
      


      Backing bean:
      public class TestBean {
      
       private HtmlPanelGroup metaPanelGroup;
       private Map<String, Object> metaItemsMap = new HashMap<String, Object>();
      
       private static int staticCount = 0;
      
       public TestBean() {
       populateMetaItemsMap();
       }
      
       private void populateMetaItemsMap() {
       metaItemsMap.put("1", "bob");
       metaItemsMap.put("2", "jim");
       }
      
       public String getListOutput() {
       StringBuilder sBuilder = new StringBuilder();
      
       for (Object o : this.getMetaItemsMap().values()) {
       sBuilder.append(o.toString());
       sBuilder.append("<br/>");
       }
      
       return sBuilder.toString();
       }
      
      
       public HtmlPanelGroup getMetaPanelGroup() {
      
       if (metaPanelGroup == null) {
       metaPanelGroup = new HtmlPanelGroup();
       } else {
       metaPanelGroup.getChildren().clear();
       }
      
       ArrayList<UIComponent> components = new ArrayList<UIComponent>();
      
       int i = 1;
       for (Object item : this.getMetaItemsMap().values()) {
       HtmlInputText htmlInputText = new HtmlInputText();
       htmlInputText.setId("_" + staticClassCounter() + "in");
       htmlInputText.setValueExpression("value", FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(FacesContext.getCurrentInstance().getELContext(), "#{testBean.metaItemsMap['" + i + "']}", String.class));
       components.add(htmlInputText);
      
       i++;
       }
      
       if (components.size() > 0) {
       metaPanelGroup.getChildren().addAll(components);
       }
      
       return metaPanelGroup;
      
       }
      
       public void setMetaPanelGroup(HtmlPanelGroup metaPanelGroup) {
       metaPanelGroup.getChildren().clear();
       HtmlPanelGroup newPanelGroup = this.getMetaPanelGroup();
       metaPanelGroup.getChildren().addAll(newPanelGroup.getChildren());
       }
      
       public Map<String, Object> getMetaItemsMap() {
       return metaItemsMap;
       }
      
       public void setMetaItemsMap(Map<String, Object> metaItemsMap) {
       this.metaItemsMap = metaItemsMap;
       }
      
       public void saveEditedMetadata() {
       System.out.println("Save");
       }
      
       private static int staticClassCounter() {
       return ++staticCount;
       }
      }
      


      Any help in resolving this problem would be much appreciated.

        • 1. Re: Submitting dynamic form in ModalPanel
          Nick Belaevski Master

          Modal panel should have form inside and forms shouldn't be nested.

          There's another solution available since 3.3.0: https://jira.jboss.org/jira/browse/RF-5588

          • 2. Re: Submitting dynamic form in ModalPanel
            Ronan Forker Newbie

            I have tried the following without sucess:

            <f:view>
             <h:form id="metaForm">
             <div>
             <h:outputText value="#{testBean.listOutput}" id="listOutput" escape="false"/>
             </div>
             <div>
             <a4j:commandLink value="Edit" id="editLink" style="float:right;">
             <a4j:support event="onclick" oncomplete="#{rich:component('metadataEditModelPanel')}.show()"
             reRender="metaEditPanel" eventsQueue="metaEvents" ignoreDupResponses="true"/>
             </a4j:commandLink>
             </div>
             </h:form>
             <rich:modalPanel id="metadataEditModelPanel" width="300" height="400">
             <f:facet name="header">
             <h:panelGroup>
             <h:outputText value="Edrms alert"></h:outputText>
             </h:panelGroup>
             </f:facet>
             <f:facet name="controls">
            
             <h:panelGroup>
             <h:graphicImage value="../images/close.png" styleClass="hidelink" id="hidelink"/>
             <rich:componentControl for="metadataEditModelPanel" attachTo="hidelink" operation="hide"
             event="onclick"/>
             </h:panelGroup>
             </f:facet>
             <h:form id="panelForm">
             <a4j:region>
             <h:panelGroup id="metaEditPanel" binding="#{testBean.metaPanelGroup}"/>
             <div>
             <a4j:commandButton value="Save" id="templateSubmit" action="#{testBean.saveEditedMetadata}"
             style="width:60px" eventsQueue="metaEvents" ignoreDupResponses="true"
             oncomplete="#{rich:component('metadataEditModelPanel')}.hide()"
             reRender="listOutput"/>
             </div>
             </a4j:region>
             </h:form>
             </rich:modalPanel>
            
            </f:view>
            


            The set method on the map does not appear to be called.

            Could you explain the the use of the 'domElementAttachment' attribute because the documentation appears to be limited.

            • 3. Re: Submitting dynamic form in ModalPanel
              Ronan Forker Newbie

              What does work is if you do not bind the inputText dynamicaly through the panelGroup and explicitly write them to the modalPanel. Unfortuantly this takes away from what I am trying to achieve.

               <rich:modalPanel id="metadataEditModelPanel" width="300" height="400">
               <f:facet name="header">
               <h:panelGroup>
               <h:outputText value="Edrms alert"></h:outputText>
               </h:panelGroup>
               </f:facet>
               <f:facet name="controls">
              
               <h:panelGroup>
               <h:graphicImage value="../images/close.png" styleClass="hidelink" id="hidelink"/>
               <rich:componentControl for="metadataEditModelPanel" attachTo="hidelink" operation="hide"
               event="onclick"/>
               </h:panelGroup>
               </f:facet>
               <h:form id="panelForm">
               <a4j:region>
               <%--<h:panelGroup id="metaEditPanel" binding="#{testBean.metaPanelGroup}"/>--%>
               <h:inputText value="#{testBean.metaItemsMap['1']}"/>
               <h:inputText value="#{testBean.metaItemsMap['2']}"/>
               <div>
               <a4j:commandButton value="Save" id="templateSubmit" action="#{testBean.saveEditedMetadata}"
               style="width:60px" eventsQueue="metaEvents" ignoreDupResponses="true"
               oncomplete="#{rich:component('metadataEditModelPanel')}.hide()"
               reRender="listOutput"/>
               </div>
               </a4j:region>
               </h:form>
               </rich:modalPanel>
              


              Is there a reason why binding the inputText to a panelGroup would stop the form from submitting the data?

              • 4. Re: Submitting dynamic form in ModalPanel
                Nick Belaevski Master

                Read here: http://www.jboss.org/index.html?module=bb&op=viewtopic&p=4209203 about domElementAttachment attribute.

                What's the scope of TestBean?

                • 5. Re: Submitting dynamic form in ModalPanel
                  Ronan Forker Newbie

                  TestBean is within session scope.

                  • 6. Re: Submitting dynamic form in ModalPanel
                    Nick Belaevski Master

                    It is not recommended to bind components to session-scoped beans. I suggest that you replace dynamic components creation inside bean with a4j:repeat or c:forEach tags.

                    • 7. Re: Submitting dynamic form in ModalPanel
                      Ronan Forker Newbie

                      Thank you very much for the advice. Very much appreciated.

                      For anyone who is interested I used the following solution to my problem:

                      <f:view>
                       <h:form id="metaForm">
                       <div>
                       <h:outputText value="#{testBean.listOutput}" id="listOutput" escape="false"/>
                       </div>
                       <div>
                       <a4j:commandLink value="Edit" id="editLink">
                       <a4j:support event="onclick" oncomplete="#{rich:component('metadataEditModelPanel')}.show()"
                       reRender="metaEditPanel" eventsQueue="metaEvents" ignoreDupResponses="true"/>
                       </a4j:commandLink>
                       </div>
                       </h:form>
                       <rich:modalPanel id="metadataEditModelPanel" width="300" height="400">
                       <f:facet name="header">
                       <h:panelGroup>
                       <h:outputText value="Edrms alert"></h:outputText>
                       </h:panelGroup>
                       </f:facet>
                       <f:facet name="controls">
                      
                       <h:panelGroup>
                       <h:graphicImage value="../images/close.png" styleClass="hidelink" id="hidelink"/>
                       <rich:componentControl for="metadataEditModelPanel" attachTo="hidelink" operation="hide"
                       event="onclick"/>
                       </h:panelGroup>
                       </f:facet>
                       <h:form id="panelForm">
                       <a4j:region>
                       <h:panelGroup id="metaEditPanel">
                       <a4j:repeat value="#{testBean.metaItemsMap}" var="thing" id="metaRepeatPanel">
                       <h:inputText value="#{thing.value}"/>
                       </a4j:repeat>
                       </h:panelGroup>
                       <div>
                       <a4j:commandButton value="Save" id="templateSubmit" action="#{testBean.saveEditedMetadata}"
                       style="width:60px" eventsQueue="metaEvents" ignoreDupResponses="true"
                       oncomplete="#{rich:component('metadataEditModelPanel')}.hide()"
                       reRender="listOutput"/>
                       </div>
                       </a4j:region>
                       </h:form>
                       </rich:modalPanel>
                      
                      </f:view>