Last active
July 26, 2019 07:48
-
-
Save cmcnulty/7036509 to your computer and use it in GitHub Desktop.
Allows you to listen for propertychange on setting disabled to true on form elements. Very useful for resolving some select2 issues.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( function( $ ) { | |
"use strict"; | |
$.fn.fireOnDisable = function( settings ) { | |
// Only perform this DOM change if we have to watch changes with propertychange | |
// Also only perform if getOwnPropertyDescriptor exists - IE>=8 | |
// I suppose I could test for "propertychange fires, but not when form element is disabled" - but it would be overkill | |
if( !( 'onpropertychange' in document.createElement( 'input' ) ) || Object.getOwnPropertyDescriptor === undefined ) { | |
return this; | |
} | |
// IE9-10 use HTMLElement proto, IE8 uses Element proto | |
var someProto = window.HTMLElement === undefined ? window.Element.prototype : window.HTMLElement.prototype, | |
someTrigger = function(){}, | |
origDisabled = Object.getOwnPropertyDescriptor( someProto, 'disabled' ); | |
if( document.createEvent ) { | |
someTrigger = function( newVal ){ | |
var event = document.createEvent('MutationEvent'); | |
/* | |
Instantiate the event as close to native as possible: | |
event.initMutationEvent(eventType, canBubble, cancelable, relatedNodeArg, prevValueArg, newValueArg, attrNameArg, attrChangeArg); | |
*/ | |
event.initMutationEvent( 'DOMAttrModified', true, false, this.getAttributeNode('disabled'), '', '', 'disabled', 1 ); | |
this.dispatchEvent( event ); | |
}; | |
} else if( document.fireEvent ) { | |
someTrigger = function(){ | |
this.fireEvent( 'onpropertychange' ); | |
}; | |
} | |
return this.each( function() { | |
// call prototype's set, and then trigger the change. | |
Object.defineProperty( this, 'disabled', { | |
set: function( isDisabled ) { | |
// We store preDisabled here, so that when we inquire as to the result after throwing the event, it will be accurate | |
// We can't throw the event after the native send, because it won't be be sent. | |
// We must do a native fire/dispatch, because native listeners don't catch jquery trigger 'propertychange' events | |
$.data( this, 'preDisabled', isDisabled ); | |
if ( isDisabled ) { | |
// Trigger with dispatchEvent | |
someTrigger.call( this, isDisabled ); | |
} | |
return origDisabled.set.call( this, isDisabled ); | |
}, | |
get: function() { | |
var isDisabled = $.data( this, 'preDisabled' ); | |
if( isDisabled === undefined ) { | |
isDisabled = origDisabled.get.call( this ); | |
} | |
return isDisabled; | |
} | |
}); | |
}); | |
}; | |
})( jQuery ); |
What licence have you released this under? I can't find one.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Should note that disabling a field with .setAttribute('disabled') does not trigger DOMAttrModified, which means that this won't work in in IE8-10.