X-Git-Url: https://scripts.mit.edu/gitweb/autoinstallsdev/mediawiki.git/blobdiff_plain/19e297c21b10b1b8a3acad5e73fc71dcb35db44a..6932310fd58ebef145fa01eb76edf7150284d8ea:/resources/src/jquery/jquery.expandableField.js diff --git a/resources/src/jquery/jquery.expandableField.js b/resources/src/jquery/jquery.expandableField.js new file mode 100644 index 00000000..c3d39daf --- /dev/null +++ b/resources/src/jquery/jquery.expandableField.js @@ -0,0 +1,147 @@ +/** + * This plugin provides functionality to expand a text box on focus to double it's current width + * + * Usage: + * + * Set options: + * $('#textbox').expandableField( { option1: value1, option2: value2 } ); + * $('#textbox').expandableField( option, value ); + * Get option: + * value = $('#textbox').expandableField( option ); + * Initialize: + * $('#textbox').expandableField(); + * + * Options: + */ +( function ( $ ) { + + $.expandableField = { + /** + * Expand the field, make the callback + * + * @param {jQuery.Event} e Event + * @param {Object} context + */ + expandField: function ( e, context ) { + context.config.beforeExpand.call( context.data.$field, context ); + context.data.$field + .animate( { width: context.data.expandedWidth }, 'fast', function () { + context.config.afterExpand.call( this, context ); + } ); + }, + /** + * Condense the field, make the callback + * + * @param {jQuery.Event} e Event + * @param {Object} context + */ + condenseField: function ( e, context ) { + context.config.beforeCondense.call( context.data.$field, context ); + context.data.$field + .animate( { width: context.data.condensedWidth }, 'fast', function () { + context.config.afterCondense.call( this, context ); + } ); + }, + /** + * Sets the value of a property, and updates the widget accordingly + * + * @param {Object} context + * @param {string} property Name of property + * @param {Mixed} value Value to set property with + */ + configure: function ( context, property, value ) { + // TODO: Validate creation using fallback values + context.config[ property ] = value; + } + + }; + + $.fn.expandableField = function () { + + // Multi-context fields + var returnValue, + args = arguments; + + $( this ).each( function () { + var key, context, timeout; + + /* Construction / Loading */ + + context = $( this ).data( 'expandableField-context' ); + + // TODO: Do we need to check both null and undefined? + if ( context === undefined || context === null ) { + context = { + config: { + // callback function for before collapse + beforeCondense: function () {}, + + // callback function for before expand + beforeExpand: function () {}, + + // callback function for after collapse + afterCondense: function () {}, + + // callback function for after expand + afterExpand: function () {}, + + // Whether the field should expand to the left or the right -- defaults to left + expandToLeft: true + } + }; + } + + /* API */ + // Handle various calling styles + if ( args.length > 0 ) { + if ( typeof args[ 0 ] === 'object' ) { + // Apply set of properties + for ( key in args[ 0 ] ) { + $.expandableField.configure( context, key, args[ 0 ][ key ] ); + } + } else if ( typeof args[ 0 ] === 'string' ) { + if ( args.length > 1 ) { + // Set property values + $.expandableField.configure( context, args[ 0 ], args[ 1 ] ); + + // TODO: Do we need to check both null and undefined? + } else if ( returnValue === null || returnValue === undefined ) { + // Get property values, but don't give access to internal data - returns only the first + returnValue = ( args[ 0 ] in context.config ? undefined : context.config[ args[ 0 ] ] ); + } + } + } + + /* Initialization */ + + if ( context.data === undefined ) { + context.data = { + // The width of the field in it's condensed state + condensedWidth: $( this ).width(), + + // The width of the field in it's expanded state + expandedWidth: $( this ).width() * 2, + + // Reference to the field + $field: $( this ) + }; + + $( this ) + .addClass( 'expandableField' ) + .focus( function ( e ) { + clearTimeout( timeout ); + $.expandableField.expandField( e, context ); + } ) + .blur( function ( e ) { + timeout = setTimeout( function () { + $.expandableField.condenseField( e, context ); + }, 250 ); + } ); + } + // Store the context for next time + $( this ).data( 'expandableField-context', context ); + } ); + return returnValue !== undefined ? returnValue : $( this ); + }; + +}( jQuery ) );