5 Replies Latest reply on Jan 5, 2010 7:35 AM by seamprogrammer

    Action method not called after Javascript modifies selectonemenu

    haxwell
      I did a cursory search for this issue, but it seems the more search terms I added, the more results I got. Anyway, I had an issue with my Seam project yesterday. In case some lucky soul stumbles across the same issue, (and the appropriate search terms) maybe this will help them.

      To reproduce the issue, you need a working project created by Seam-Gen. Then, add a form to the project. Next, add this code to the body of the .xhtml file:

      `       <script type="text/javascript">
              //<![CDATA[
                      function doTheBug() {          
                              var so = document.getElementById("<SELECTONEMENU_ID>");

                              var v = document.createElement('option');
                              v.text = "Test";
                              v.value = "Test";
                             
                              so.add(v, null);

                              var noop = "";
                      }
              // ]]>
              </script>
      `

      -- Replace the <h:form> section with this:

      `
          <h:form id="form">
              <rich:panel>
                  <f:facet name="header">FORM NAME</f:facet>
                              <s:decorate id="buggy">
                                      <h:outputLabel id="label" value="Do The Bug" onclick="javascript:doTheBug()"/>
                              <h:selectOneMenu id="som"></h:selectOneMenu>                               
                  </s:decorate>
                  <div style="clear:both"/>
              </rich:panel>
              <div class="actionButtons">
                  <h:commandButton id="BUTTON_ID" value="Hit The Breakpoint" action="#{SESSIONBEAN.ACTIONMETHOD}"/>
              </div>
          </h:form>
      `

      In your IDE, set a breakpoint on the Action method that is called on the back end. In Firebug (in your browser), set a breakpoint at the beginning of the Javascript.

      Now to see the bug, run this form in your new Seam-Gen app. If you click on the Action button for your form (lower left, named after your form), you will see that the breakpoint in your IDE is reached. Let it run through normally. Now, click on the label that says 'Do The Bug'. It adds an option to your SelectOneMenu. Cool. Now, click on the Action button again. This time, it should not reach your IDE breakpoint. This is because the page, even though refreshing/submitting, is not calling the Action method.

      The reason for this is that the SelectOneMenu has no initial Options. The Javascript at |so.add(v, null)| is returning/causing an error which keeps the Action method from being called. If you add the following line,

      `       <f:selectItem itemLabel="Option 1" itemValue="1"></f:selectItem>
      `

      so that the h:selectOneMenu definition looks like

      `        <h:selectOneMenu id="som">
                       <f:selectItem itemLabel="Option 1" itemValue="1"></f:selectItem>
              </h:selectOneMenu>                               
      `

      Then re-run that page, you will see that you can run the Javascript, and click the Action button, which will hit your IDE breakpoint as expected.

      It caused me a lot of grief figuring out why my Action method was not being called after the Javascript had run. But hopefully, you'll read this and save yourself some when/if it happens to you.

      Johnathan
        • 1. Re: Action method not called after Javascript modifies selectonemenu
          haxwell

          Aaaargh...


          So it seems my above posting was only one issue. If you look at my above post, in the Javascript, I create an option element named 'v'. If you set the newly created Option to 'selected true', the new item will be selected as expected, but once again, when you click your Action button, the page will be refreshed/submitted, but will not call Action method.


          The Javascript looks like..


           <script type="text/javascript">
                  //<![CDATA[
                          function doTheBug() {
                                  var so = document.getElementById("<SELECTONEMENU_ID>");
          
                                  var v = document.createElement('option');
                                  v.text = "Test";
                                  v.value = "Test";
                                  v.selected = true; // THIS CAUSES THE ERROR
                                                           so.add(v, null);
          
                                  var noop = "";
                          }
                  // ]]>
                  </script>
          



          Anybody have an idea what I am doing wrong? This Mozilla documentation says selected is an available attribute, and the select does happen without error in Firebug. But WHY(!!!) is it then not calling the Action method?


          help!


          Johnathan

          • 2. Re: Action method not called after Javascript modifies selectonemenu
            haxwell

            As an update, I have found the problem.. Unfortunately, not a solution, but I am sure the problem is Validation by Mojarra (JSF). In Javascript, when I add the option to the SelectOneMenu, it is fine on the client side. The parent/child relationships are set as expected.


            But when you get to the server, and Validation (HTMLSelectOneMenu.validateValue(ctx, value)), the child option that I added is not present, and that causes Validation to fail. Unfortunately, it doesn't matter if immediate is set to true or false; it won't skip validation.


            I have tried using '.appendChild()' instead of '.add()'. Both functions seem to work fine on the client side, the newly added element has its parent/child relationships as expected.


            I have tried this with Mojarra 1.212, 1.214, and 2.0.2. All have the same result.


            I hope I don't have to patch my build, but its looking that way.

            • 3. Re: Action method not called after Javascript modifies selectonemenu
              niox.nikospara.yahoo.com

              Hello,


              This behaviour is inconvenient but correct. The client should not be allowed to change a server-generated list, it would be a potential security problem.


              If what you want is a client-generated (or client-modifiable) drop-list, you could create a custom renderer for the standard UIInput or HtmlInputText that renders it as a <select> and also knows how to render any children <f:selectItems>. Then you may have to implement some kind of server-side validation for this input.


              Alternatively, each client interaction that will add an <option> must first call the server, the server will add the option to the JSF UISelectOne component and reRender it back to the client.

              • 4. Re: Action method not called after Javascript modifies selectonemenu
                haxwell

                Nikos,


                Thank you for your reply. I can see that this might be a potential security risk, albeit a minor one. The options that I am adding are valid, there is no arbitrary code being run in them or anything out of the ordinary. In cases like this, I should be able to say to the backend 'Do not validate this component!' or at a minimum 'Use this class I've provided to do the validation'.


                So, in solution, I did patch my Mojarra to look for an attribute on the HTML UI component. If found, it will not continue with the validation.


                Its a hack, but damnit, I had to get around that issue.


                I have since found Google Webtoolkit which seems to allow me to do all this, without the patch.


                Johnathan

                • 5. Re: Action method not called after Javascript modifies selectonemenu
                  seamprogrammer

                  Ni Nikos


                  Im also facing same problem with dynamic drop down list, can please send the patch to me or put in the post?


                  Please helpme seamprogrammer@gmail.com


                  thanking you in advacnce'


                  seam!!