6 Replies Latest reply on Jun 21, 2007 10:10 AM by damianharvey

    a4j vs valuechangelistener

    sammy8306

      I started out with the following code:

      <div class="input">
       <ui:repeat var="listvar" value="#{NewBlogEntryComponent.blogEntry_be.tags}">
       <h:outputText value="#{listvar} "/>
       <h:commandButton value="Delete" action="#{NewBlogEntryComponent.remove(listvar)}"/>
       <br />
       </ui:repeat>
       <br />
       <s:decorate>
       <h:selectOneMenu id="tags1" value="#{dev.nulll}" onchange="submit()" valueChangeListener="#{NewBlogEntryComponent.listener}">
       <s:selectItems var="field" label="#{field.toString}" value="#{AllTag}" noSelectionLabel="Please select : " />
       <s:convertEntity/>
       </h:selectOneMenu>
       </s:decorate>
      </div>
      

      This is part of a larger form, where I'm letting the user fill an entity. The depicted part is my stab at trying to input a list of references to other entities. In the valuechangelistener I retrieve the selected entity directly (thank you s:convertEntity!) and add it to the list. Works like charm, except that when the onchange event occurs, the complete form is submitted (and thus validated), whereas I'm only interested in updating the list. So, my next move was to use Ajax4Jsf (since I'm not willing to extract this part into its own separate form):

      .. skipped ui:repeat part, is the same ..
       <s:decorate>
       <h:selectOneMenu id="tags1" value="#{dev.nulll}">
       <s:selectItems var="field" label="#{field.toString}" value="#{AllTag}" noSelectionLabel="Please select : " />
       <s:convertEntity/>
       <a:support event="onchange" reRender="relevantid" bypassUpdates="true" action="#{NewBlogEntryComponent.listener(field)}"/>
       </h:selectOneMenu>
       </s:decorate>
      


      However, the parameter I'm receiving in listener() is always null. How can I access the selected value in the action method called by a:support? I guess field is not really in scope anymore for the a:support tag, but what are my options?

        • 1. Re: a4j vs valuechangelistener
          pmuir

          Unfortunately thats not the way s:selectItems works - it doesn't make the var attribute available outside of itself (you would have to nest the a:support anyway). I'm not really convinced of a good arguement for changing this.

          I would suggest using an valueChangeListener style approach, where you get the valueChangeEvent with the altered property. I'm not sure what the magic combinations of a4j tags is I'm afraid :(

          • 2. Re: a4j vs valuechangelistener
            sammy8306

            Indeed. Ok, after some more experimenting I have:

            <a:region>
             <ui:repeat id="listt" var="listvar" value="#{NewBlogEntryComponent.blogEntry_be.tags}">
             <h:outputText value="#{listvar} "/>
             <a:commandButton value="Delete" reRender="foo" action="#{NewBlogEntryComponent.remove(listvar)}"/>
             <br />
             </a:repeat>
             <br />
             <s:decorate>
             <h:selectOneMenu id="tags1" value="#{dev.nulll}" valueChangeListener="#{NewBlogEntryComponent.listener}">
             <s:selectItems var="field" label="#{field.toString}" value="#{AllTag}" noSelectionLabel="Please select : " />
             <s:convertEntity/>
             <a:support event="onchange" reRender="listt" bypassUpdates="true" />
             </h:selectOneMenu>
             </s:decorate>
            </a:region>
            


            This actually works (as in: the list gets updated perfectly), but... my ui:repeat is not re-rendered. The page must be reloaded manually to reflect the new data. I tried switching it to an a:repeat which I found somewhere in the A4J docs, allegedly it should do the magic, but that didn't work. Am I missing something?

            • 3. Re: a4j vs valuechangelistener
              pmuir

              Try reRendering the a:region rather than the ui:repeat. This is really in the region of a4j and you can probably get more help on their forums :)

              • 4. Re: a4j vs valuechangelistener
                sammy8306

                I'll give it a try, meanwhile I found <a:log /> which warns me:

                error[12:18:16,544]: New node for ID _id29:listt is not present in response

                So there's definetely something up there. This message leads me to believe that all information for re-rendering must be in the Ajax response? I'd rather have the bindings re-evaluated automatically :-)

                Anyway, I'll take it to the A4J forums indeed if I can't fix this.

                • 5. Re: a4j vs valuechangelistener
                  sammy8306

                   

                  "Sammy8306" wrote:

                  Anyway, I'll take it to the A4J forums indeed if I can't fix this.


                  Well, turns out I can't (yet), so for anyone interested: http://jboss.com/index.html?module=bb&op=viewtopic&p=4056407#4056407

                  • 6. Re: a4j vs valuechangelistener
                    damianharvey

                    What you were pointed to in the A4j forum was a link to reRender only part of your ui:repeat. If you'd just like to reRender the whole thing, I find wrapping things like this in <s:div> to be very helpful. eg.

                    <a:region>
                     <s:div id="blogEntriesDiv">
                     <ui:repeat id="listt" var="listvar" value="#{NewBlogEntryComponent.blogEntry_be.tags}">
                     <h:outputText value="#{listvar} "/>
                     <a:commandButton value="Delete" reRender="foo" action="#{NewBlogEntryComponent.remove(listvar)}"/>
                     <br />
                     </ui:repeat>
                     </s:div>
                     <br />
                     <s:decorate>
                     <h:selectOneMenu id="tags1" value="#{dev.nulll}" valueChangeListener="#{NewBlogEntryComponent.listener}">
                     <s:selectItems var="field" label="#{field.toString}" value="#{AllTag}" noSelectionLabel="Please select : " />
                     <s:convertEntity/>
                     <a:support event="onchange" reRender="blogEntriesDiv" bypassUpdates="true" />
                     </h:selectOneMenu>
                     </s:decorate>
                    </a:region>