views:

33

answers:

1

I have a form with 2 text inputs and 2 span controls. Normally, when textbox A is changed an event is fired to change span A, and when textbox B is changed, an event is fired to change span B.

However, in one particualar case I would like a change either textbox A or textbox B to update both span A and B. I tried wiring the events up to the corresponding controls in this case, but it didn't work because there is much state that is set up in the event building code (not to mention each event calls 'this', which would make the logic use the wrong control if it were fired from a different one than it was intended).

To make things easy, it would be best to pass a string (representing the other text input id) to the event handler at the time it is created, and then calling the change() event manually on the second control. However, this puts things in an infinite loop of recursion. I thought of a way to get around the recursion, but it reqires a global variable.

Is there a better way than this, preferably one that doesn't require a global variable?

ml_inEvent = false;



   $ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event) {
        // Other processing happens here...

        if (event.data.controlToFire != '') {
            var $controlToFire = $('#' + event.data.controlToFire);
            if ($controlToFire.length) {
                // Use a global variable to ensure this event is not fired again
                // as a result of calling the other one
                if (!ml_inEvent) {
                    ml_inEvent = true;
                    $controlToFire.change();
                    ml_inEvent = false;
                }
            }
        }
    });
+2  A: 

You can use the extraParameters argument on .trigger() to break out, for example:

$ctlToVal.bind('keyup change', {feedbackCtl: ml_feedback, controlsToMonitor: ary, validationGroup: this.validationGroup, controlToFire: ctlToFire}, function(event, fire) {
  // Other processing happens here...
  if(fire !== false)  $('#' + event.data.controlToFire).trigger('change', false);
});

You can give it a try here. What this does is the event handler callback not only receives the event object but also any other arguments you pass in, in this case we're just using a simple false and a !=== check this in important so undefined (the parameter not passed at all) still changes both controls. So for instance $("#control").change() would change both controls, but still not loop...you can test that here.

Nick Craver
Thanks - I thought it should be simple like this!
NightOwl888