2 * This plugin provides functionality to expand a text box on focus to double it's current width
7 * $('#textbox').expandableField( { option1: value1, option2: value2 } );
8 * $('#textbox').expandableField( option, value );
10 * value = $('#textbox').expandableField( option );
12 * $('#textbox').expandableField();
21 * Expand the field, make the callback
23 expandField: function ( e, context ) {
24 context.config.beforeExpand.call( context.data.$field, context );
26 .animate( { width: context.data.expandedWidth }, 'fast', function () {
27 context.config.afterExpand.call( this, context );
31 * Condense the field, make the callback
33 condenseField: function ( e, context ) {
34 context.config.beforeCondense.call( context.data.$field, context );
36 .animate( { width: context.data.condensedWidth }, 'fast', function () {
37 context.config.afterCondense.call( this, context );
41 * Sets the value of a property, and updates the widget accordingly
43 * @param {Object} context
44 * @param {string} property Name of property
45 * @param {Mixed} value Value to set property with
47 configure: function ( context, property, value ) {
48 // TODO: Validate creation using fallback values
49 context.config[ property ] = value;
54 $.fn.expandableField = function () {
56 // Multi-context fields
60 $( this ).each( function () {
61 var key, context, timeout;
63 /* Construction / Loading */
65 context = $( this ).data( 'expandableField-context' );
67 // TODO: Do we need to check both null and undefined?
68 if ( context === undefined || context === null ) {
71 // callback function for before collapse
72 beforeCondense: function () {},
74 // callback function for before expand
75 beforeExpand: function () {},
77 // callback function for after collapse
78 afterCondense: function () {},
80 // callback function for after expand
81 afterExpand: function () {},
83 // Whether the field should expand to the left or the right -- defaults to left
90 // Handle various calling styles
91 if ( args.length > 0 ) {
92 if ( typeof args[ 0 ] === 'object' ) {
93 // Apply set of properties
94 for ( key in args[ 0 ] ) {
95 $.expandableField.configure( context, key, args[ 0 ][ key ] );
97 } else if ( typeof args[ 0 ] === 'string' ) {
98 if ( args.length > 1 ) {
99 // Set property values
100 $.expandableField.configure( context, args[ 0 ], args[ 1 ] );
102 // TODO: Do we need to check both null and undefined?
103 } else if ( returnValue === null || returnValue === undefined ) {
104 // Get property values, but don't give access to internal data - returns only the first
105 returnValue = ( args[ 0 ] in context.config ? undefined : context.config[ args[ 0 ] ] );
112 if ( context.data === undefined ) {
114 // The width of the field in it's condensed state
115 condensedWidth: $( this ).width(),
117 // The width of the field in it's expanded state
118 expandedWidth: $( this ).width() * 2,
120 // Reference to the field
125 .addClass( 'expandableField' )
126 .focus( function ( e ) {
127 clearTimeout( timeout );
128 $.expandableField.expandField( e, context );
130 .blur( function ( e ) {
131 timeout = setTimeout( function () {
132 $.expandableField.condenseField( e, context );
136 // Store the context for next time
137 $( this ).data( 'expandableField-context', context );
139 return returnValue !== undefined ? returnValue : $( this );