views:

673

answers:

4

Hello, I've faced strange problem. While user change of check box input element on form produces adequate event programmatic change don't. How should I face this challenge? Code following:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
<html xmlns="http://www.w3.org/1999/xhtml"&gt;
<head>
  <title></title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"&gt;&lt;/script&gt;
  <script type="text/javascript">
    jQuery(document).ready(
      function() {        
        jQuery("#cb").change(
          function() {
            alert("Changed!"); 
            return true;
          }
        );
        jQuery("#b").click(
          function() {
            var newState = !jQuery("#cb").attr('checked');
            jQuery("#cb").attr('checked', newState);
          });
      });
  </script>
</head>
<body>
  <form action="#">
    <p>
      <input type="button" id="b" />
      <input type="checkbox" id="cb" />
    </p>
  </form>
</body>
</html>

Update I do not control element changes, I just need to handle them. It's general-propose code I write.

+1  A: 

In this case you should not code logic in the event handler function itself. You should place any such logic in a separate function. Similarly you should not place code that manipulates the check boxes value programatically directly in other sequences of code but abstract it into another function:-

jQuery(document).ready(
  function() {

    jQuery("#cb").change(
      function() {
        changeLogicForcb.call(this);
         return true; 
     }
    );

    jQuery("#b").click(
      function() {
         togglecb();            
      });

    function changeLogicForcb()
    {
         //something actually sensible here
         alert("changed!");
    }

    function togglecb()
    {
        var cb = jQuery("#cb");
        var newState = !cb.attr('checked');
        cb.attr('checked', newState);
        changeLogicForcb.call(cb.get(0));         
    }  

  });
AnthonyWJones
+1  A: 

use the trigger function to trigger a click event on the checkbox. You won't need to grab the existing state as the checkbox will just be toggled by the click.

jQuery("#cb").trigger('click');
tvanfosson
A: 

The jQuery core library method .val() does not fire the change event. If you serve your own copy of jQuery, you could modify the library method, but that would probably not be wise. Instead, you could add your own value-setter that leverages .val() while also firing the change event with something along the following lines:

jQuery.fn.xVal = (function() {
    return function(value) {
        // Use core functionality
        result = this.val.apply(this, arguments);
        // trigger change event
        if (result instanceof jQuery) {
              result.change();
        }
        return result;
    };
})();
mfwesq
A: 

It's impossible to track object's state within javascript language as it could be done in Objective-C (KVO). Nor it possible using DOM features - DOM do not fire events on every property change - instead it only fires events on certain user actions: mouse clicks, key presses, or page life cycle and their derivatives.

One could achieve that only firing event every time she modifies some property. Certainly this could be encapsulated in a function as AnthonyWJones had mentioned.

Artem Tikhomirov