diff --git a/Source/Element/Element.Event.js b/Source/Element/Element.Event.js index 06577326a..339f3893d 100644 --- a/Source/Element/Element.Event.js +++ b/Source/Element/Element.Event.js @@ -171,6 +171,15 @@ if ('onmouseenter' in document.documentElement){ } /**/ +var inputClickWatcher = false; +function isBuggyType(e){ + return e.type == 'propertychange' && e.event.propertyName == 'checked'; +} +function isSyntetic(){ + var clicked = inputClickWatcher; + inputClickWatcher = false; // reset the flag + return clicked ? false : true; +} if (!window.addEventListener){ Element.NativeEvents.propertychange = 2; Element.Events.change = { @@ -178,7 +187,17 @@ if (!window.addEventListener){ var type = this.type; return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change'; }, + onAdd: function(event){ + this.addEvent('click', function(event){ + inputClickWatcher = true; + event.stop(); + }); + }, condition: function(event){ + if (isBuggyType(event) && isSyntetic(event)) return false; + var el = event.target; + if (el.type == 'checkbox') el.checked = !el.checked; + if (el.type == 'radio' && !el.checked) el.checked = !el.checked; return event.type != 'propertychange' || event.event.propertyName == 'checked'; } }; diff --git a/Specs/Element/Element.Event.js b/Specs/Element/Element.Event.js index 5a9e061ee..e7efda512 100644 --- a/Specs/Element/Element.Event.js +++ b/Specs/Element/Element.Event.js @@ -334,6 +334,34 @@ describe('Element.Event.change', function(){ }); +describe('Element.Event.change', function(){ + /**/ + + var checked, eventFired; + var input = new Element('input', { + type: 'checkbox' + }); + input.addEvent('change', function(e){ + eventFired = true; + }).inject(document.body); + it('should not fire any event when setting a "checked" property', function(){ + input.set('checked', true); + checked = input.get('checked'); + + expect(checked).toBeTruthy(); + expect(eventFired).not.toBeTruthy(); + }); + + it('should fire a change event when clicking a input[type=checkbox]', function(){ + input.click(); + checked = input.get('checked'); + + expect(checked).not.toBeTruthy(); + expect(eventFired).toBeTruthy(); + }); +}); + /**/ + describe('Element.Event keyup with f', function(){ it('should pass event.key == f2 when pressing f2 on keyup and keydown', function(){