7 Replies Latest reply on Dec 9, 2010 11:41 AM by mopper

    rich:comboBox onchange event issue

    mopper

      I recently noticed this in one of my applications: the rich:comboBox always triggers the onchange event if you open the suggestionlist and then make it lose focus. Oddly enough, it only does this the first time around. I made a little testcase for this:

       

       

      {code:xml}

      <?xml version='1.0' encoding='UTF-8' ?>

      <html 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:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j"
          >

          <a4j:form>
            <rich:comboBox value="1" onchange="alert('onchange triggered!');">
                <f:selectItem itemValue="1" itemLabel="1"/>
                <f:selectItem itemValue="2" itemLabel="2"/>
                <f:selectItem itemValue="3" itemLabel="3"/>
            </rich:comboBox>
          </a4j:form>
      </html>

      {code}

       

      If you open this up, then press the arrow to open up the suggestionlist of the combobox, and then click anywhere else in the page, the onchange will trigger. If you repeat the exact same steps, it won't trigger anymore.

       

      I did a search on the richfaces JIRA but could not find this issue.

       

      I'm running Richfaces 3.3.2, but I tried with 3.3.3.Final and it has the same behaviour.

       

      Is there a workaround for this?

        • 1. Re: rich:comboBox onchange event issue
          sivaprasad9394

          I tried your code yes it is a bug i think so.

          • 2. Re: rich:comboBox onchange event issue
            sivaprasad9394

            try this code it works fine.

             

            when you select 1 the event will be fired,if you click outside the combobox it wont fire the event.

             

            rich:effect name="hightlighttext" event="oninputfocus" for="testDateInputDate" type="Highlight" params="duration:0.4"/>

            <rich:comboBox defaultLabel="Please Select...." onchange="alert('onchange triggered!');">   

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

            <f:selectItem itemValue="2" itemLabel="2"/>

            <f:selectItem itemValue="3" itemLabel="3"/>   

            </rich:comboBox> 

             

             

             

             

             

            rich:effect name="hightlighttext" event="oninputfocus" for="testDateInputDate" type="Highlight" params="duration:0.4"/>
            <rich:comboBox defaultLabel="Please Select...." onchange="alert('onchange triggered!');">   
            <f:selectItem itemValue="1" itemLabel="1"/>   
            <f:selectItem itemValue="2" itemLabel="2"/>
            <f:selectItem itemValue="3" itemLabel="3"/>   
            </rich:comboBox> 

            • 3. Re: rich:comboBox onchange event issue
              mopper

              In your case, it's working because you have a defaultLabel set and no initial value (whereas mine had "1" as initial value). My problem is that when there is a value selected in the comboBox, and the user opens it and then just clicks somewhere else, the onchange is triggered. I'm afraid that your example does not really solve that ...

              • 4. Re: rich:comboBox onchange event issue
                ilya_shaikovsky

                I was able to create workaround for that

                      <rich:comboBox value="1" onchange="console.log('changed!');" id="cb">
                                <f:selectItem itemValue="suggestion1"/>
                                <f:selectItem itemValue="suggestion2"/>
                                <f:selectItem itemValue="suggestion3"/>
                                <f:selectItem itemValue="suggestion4"/>
                                <f:selectItem itemValue="suggestion5"/>
                      </rich:comboBox>
                      <script>
                var combo = #{rich:component('cb')};
                if (combo.comboValue.value){
                combo.field.prevValue = combo.comboValue.value;
                }
                      </script>

                      <rich:comboBox value="1" onchange="console.log('changed!');" id="cb">

                                <f:selectItem itemValue="suggestion1"/>

                                <f:selectItem itemValue="suggestion2"/>

                                <f:selectItem itemValue="suggestion3"/>

                                <f:selectItem itemValue="suggestion4"/>

                                <f:selectItem itemValue="suggestion5"/>

                      </rich:comboBox>

                      <script>

                          var combo = #{rich:component('cb')};

                          if (combo.comboValue.value){

                               combo.field.prevValue = combo.comboValue.value;

                          }

                      </script>

                so you could create custom facelet tag for comboBox with that script in order it to be properly initialized if contains initial value.
                Let me know if there are any problems with the workaround.  I done some testing but there is always chance of missing something

                • 5. Re: rich:comboBox onchange event issue
                  mopper

                  That does indeed solve the problem, thanks! But I think I'll make a small script that does this for each rich:comboBox on the page, that will be easier than creating a customer facelet tag on which I would have to duplicate all the attributes that can be set on a rich:comboBox and pass them through to the rich:comboBox

                  • 6. Re: rich:comboBox onchange event issue
                    ilya_shaikovsky

                    I just used simpler way to illustrate the idea And agree that script you intended to write - will looks much more cool

                    • 7. Re: rich:comboBox onchange event issue
                      mopper

                      Right, if anyone else ever runs into this, this is what I came up with in the end:

                       

                      {code}
                          function fixOnChangeIssue() {
                              jQuery('.rich-combobox ').each(function() {
                                  var combo = jQuery(this).closest('[component]');
                                  if(combo.length!=0) {
                                      combo = combo[0].component;
                                      if(combo.comboValue.value) {
                                          combo.field.prevValue = combo.comboValue.value;
                                      }
                                         
                                  }
                              })
                          }
                      {code}

                       

                      Then you have this execute whenever your page loads.