Question

I'm using Prototype to monitor checkboxes, so I can add javascript checks to them. When the tr or td in which the checkbox is located is clicked, the checkbox should be checked.
When you click directly on a checkbox, the onchange event is fired, so you'll get an alert. When the checkbox' value is changed by javascript (when you click on the tr or td), onchange is not fired. Why is onchange not fired when the checkbox is changed indirectly?

This is the javascript I'm using.

Element.observe(window, 'load', function() {
        /* If a tr or td is clicked, change the value of the checkbox. */
        $$('#results tr').each(function(el) { 
            el.observe('click', function(e) {
                if(!e.target) { e.target = e.srcElement; }
                if(e.target.nodeName == 'TD' || e.target.nodeName == 'TR') {
                    $('compare-product'+this.id).checked = ($('compare-product'+this.id).checked === false) ? true : false;
                }
            });
        });
        /* Monitor if the status of a checkbox has changed. */
        $$('#results tr td input').each(function(el) {
                el.observe('change', function(e) {
                        alert('!');
                    }
                );
            }
        );
    }
);

I've tested it in Firefox and IE7, both are not working. I'm not looking for a workaround, I'm just curious to know why this doesn't work.

Was it helpful?

Solution

This isn't uncommon in UI frameworks in general. If you change the state of a control programmatically, it's assumed that you're also capable of programmatically triggering whatever side-effects it's supposed to have. It gives programmers more flexibility, and it avoids bugs where the state is in flux during initialization or teardown. (For example, during initialization, you might set the state of one control before setting the state of several dependent ones. If the change handler for the first control fires immediately, it will execute while the other controls are in an inconsistent state.)

OTHER TIPS

The real reason you can't do this is because it's security issue in the programming model. Events that were not user initiated are usually not chained. So although setting a value is fine, it's not fine to go ahead and fire any events that were set on that control.

What jamesdlin has said makes no sense.

Jamesdlin:

"For example, during initialization, you might set the state of one control before setting the state of several dependent ones. If the change handler for the first control fires immediately, it will execute while the other controls are in an inconsistent state."

This is true no matter if you set it programmatically change a value or whether you click on the control. In either case you may have dependent other controls.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top