8 Replies Latest reply on Jan 22, 2009 8:21 AM by mvitenkov

    Ensure input gets submitted via a4j:support in any case

      Hello,

      I'm struggling with the following problem:

      Assume two components, a tree that represents a model and a detail view with input fields for the selected tree node, aka the currently selected model item. Each input field gets submitted via a4j:support. When a click on another treenode occurs, the detail view gets rerendered, effectively replacing all existing input fields. That means that the onchange handler of the last edited input won't be called. The same effect can be observed when using a htmlCommand instead of the tree.

      Is there a way to make sure, that the input gets submitted prior to sending the request toggled by the click in the tree?

        • 1. Re: Ensure input gets submitted via a4j:support in any case
          nbelaevski

          Hello,

          Not sure that I understand the problem well. Can you please post page code?

          • 2. Re: Ensure input gets submitted via a4j:support in any case

            Thanks for your time. I tried to construct an example:
            Assume you have two forms, the first contains a tree, the second has two input fields that get rendered according to the selected node (one input field per node). Now, if you select the first node and leave the field (change the focus away to toggle the onchange event) or click the link, the node name gets updated. Works like a charm.

            But if you change the name and select the other tree node immediately afterwards, the onchange is not triggered and the model doesn't get updated.

            The rationale behind this is: We have a tree that describes a model and some detail views (individual forms that get rendered per selected tree node). Changes in the detail view forms may lead to changes in the tree and selections in the tree lead to rendering of different views. Now, if you change some input in a detail view AND immediately select another node, there will be no ajax request.


            Pagecode:

            <a4j:form id="form">
             <rich:tree nodeSelectListener="#{simpleTreeBean.processSelection}"
             ajaxSubmitSelection="true" switchType="ajax"
             value="#{simpleTreeBean.treeNode}" var="item" ajaxKeys="#{null}"
             reRender="theOtherForm,currentNodeText">
             </rich:tree>
             <h:outputText escape="false"
             value="Selected Node: #{simpleTreeBean.nodeTitle}"
             id="currentNodeText" />
            </a4j:form>
            
            <a4j:form id="theOtherForm">
             <h:inputText id="myInput1"
             rendered="#{!simpleTreeBean.secondNodeSelected}"
             value="#{simpleTreeBean.nodeTitle}">
             <a4j:support event="onchange" reRender="form"/>
             </h:inputText>
             <h:inputText id="myInput2"
             rendered="#{simpleTreeBean.secondNodeSelected}"
             value="#{simpleTreeBean.nodeTitle}">
             <a4j:support event="onchange" reRender="form"/>
             </h:inputText>
            
             <a4j:htmlCommandLink reRender="form" eventsQueue="sidinput">
             <a4j:outputPanel>
             <h:outputText value="click me" />
             </a4j:outputPanel>
             </a4j:htmlCommandLink>
            </a4j:form>
            

            Treebean: (adapted from org.richfaces.demo.tree.SimpleTreeBean)
            import org.richfaces.component.html.HtmlTree;
            import org.richfaces.event.NodeSelectedEvent;
            import org.richfaces.model.TreeNode;
            import org.richfaces.model.TreeNodeImpl;
            
            public class SimpleTreeBean {
            
             private TreeNode currentNode;
             private TreeNodeImpl firstNode;
             private String nodeTitle;
             private TreeNode rootNode;
             private TreeNodeImpl secondNode;
            
             public String getNodeTitle() {
             if (currentNode != null) {
             return (String) currentNode.getData();
             } else {
             return "unknown";
             }
             }
            
             public TreeNode getTreeNode() {
             if (rootNode == null) {
             createTree();
             }
             return rootNode;
             }
             public boolean isSecondNodeSelected() {
             return currentNode == secondNode;
             }
             public void processSelection(final NodeSelectedEvent event) {
             final HtmlTree tree = (HtmlTree) event.getComponent();
             nodeTitle = (String) tree.getRowData();
             currentNode = tree.getModelTreeNode(tree.getRowKey());
             }
             public void setNodeTitle(final String title) {
             if (currentNode != null) {
             currentNode.setData(title);
             }
             }
            
             private void createTree() {
             int idx = 0;
             rootNode = new TreeNodeImpl();
            
             firstNode = new TreeNodeImpl();
             firstNode.setData("Node 1");
             rootNode.addChild(new Integer(idx++), firstNode);
            
             secondNode = new TreeNodeImpl();
             secondNode.setData("Node 2");
             rootNode.addChild(new Integer(idx++), secondNode);
             }
            }
            


            If we put all components in one form, everything works, but sadly that is no option for our page at the moment.

            Thanks for any pointers.

            • 3. Re: Ensure input gets submitted via a4j:support in any case
              nbelaevski

              Hello,

              Use eventsQueue attribute.

              • 4. Re: Ensure input gets submitted via a4j:support in any case

                Sorry, but if I add an eventsQueue attribute to the tree and both a4j:supports nothing changes. Any other suggestions?

                <a4j:form id="form" eventsQueue="queue">
                 <rich:tree
                 nodeSelectListener="#{simpleTreeBean.processSelection}"
                 ajaxSubmitSelection="true" switchType="ajax"
                 value="#{simpleTreeBean.treeNode}" var="item" ajaxKeys="#{null}"
                 reRender="theOtherForm,currentNodeText" eventsQueue="queue">
                 </rich:tree>
                 <h:outputText
                 escape="false"
                 value="Selected Node: #{simpleTreeBean.nodeTitle}"
                 id="currentNodeText" />
                </a4j:form>
                <a4j:form id="theOtherForm">
                 <h:inputText id="myInput1"
                 rendered="#{!simpleTreeBean.secondNodeSelected}"
                 value="#{simpleTreeBean.nodeTitle}">
                 <a4j:support
                 event="onchange"
                 reRender="form" eventsQueue="queue" />
                 </h:inputText>
                 <h:inputText id="myInput2"
                 rendered="#{simpleTreeBean.secondNodeSelected}"
                 value="#{simpleTreeBean.nodeTitle}">
                 <a4j:support
                 event="onchange"
                 reRender="form" eventsQueue="queue" />
                 </h:inputText>
                 <a4j:htmlCommandLink reRender="form" eventsQueue="queue">
                 <a4j:outputPanel>
                 <h:outputText value="click me" />
                 </a4j:outputPanel>
                 </a4j:htmlCommandLink>
                </a4j:form>
                


                • 5. Re: Ensure input gets submitted via a4j:support in any case
                  ilya_shaikovsky

                  which RF version you using?

                  and b.t.w. could you please place for example outputPanel inside the forms and update the panel instead of form itself. There where problems in the past during form element update.

                  Also if there are any client side errors?

                  • 6. Re: Ensure input gets submitted via a4j:support in any case

                    The problem happens on all versions from RF 3.2.0 upto 3.3.0.GA. If I nest <a4j:outputPanel...> into each form and change all reRender attributes accordingly the problem persists. There are no client side errors.


                    <a4j:form id="form" eventsQueue="queue">
                     <a4j:outputPanel id="panel1" layout="block">
                     ...
                     reRender="panel2,panel1"
                     ...
                     </a4j:outputPanel>
                    </a4j:form>
                    <a4j:form id="theOtherForm">
                     <a4j:outputPanel id="panel2" layout="block">
                     ...
                     reRender="panel1"
                     ...
                     </a4j:outputPanel>
                    </a4j:form>
                    


                    • 7. Re: Ensure input gets submitted via a4j:support in any case

                      Hello,

                      is the behaviour I described as specified or is this a bug that should be opened?

                      Maybe I could use the new a4j:queue feature to reorder requests to ensure, that "dirty" input fields with an attached a4j:support get submitted prior to any other ajax requests happen?


                      • 8. Re: Ensure input gets submitted via a4j:support in any case

                        Issue was posted in JIRA. See https://jira.jboss.org/jira/browse/RF-5842
                        Thanks for the participation.