Merge "Improve sorting on SpecialWanted*-Pages"
[mediawiki.git] / resources / src / jquery / jquery.expandableField.js
blobc3d39dafaf8efec8bd19c2f900e91209e4b954c5
1 /**
2  * This plugin provides functionality to expand a text box on focus to double it's current width
3  *
4  * Usage:
5  *
6  * Set options:
7  *              $('#textbox').expandableField( { option1: value1, option2: value2 } );
8  *              $('#textbox').expandableField( option, value );
9  * Get option:
10  *              value = $('#textbox').expandableField( option );
11  * Initialize:
12  *              $('#textbox').expandableField();
13  *
14  * Options:
15  */
16 ( function ( $ ) {
18         $.expandableField = {
19                 /**
20                  * Expand the field, make the callback
21                  *
22                  * @param {jQuery.Event} e Event
23                  * @param {Object} context
24                  */
25                 expandField: function ( e, context ) {
26                         context.config.beforeExpand.call( context.data.$field, context );
27                         context.data.$field
28                                 .animate( { width: context.data.expandedWidth }, 'fast', function () {
29                                         context.config.afterExpand.call( this, context );
30                                 } );
31                 },
32                 /**
33                  * Condense the field, make the callback
34                  *
35                  * @param {jQuery.Event} e Event
36                  * @param {Object} context
37                  */
38                 condenseField: function ( e, context ) {
39                         context.config.beforeCondense.call( context.data.$field, context );
40                         context.data.$field
41                                 .animate( { width: context.data.condensedWidth }, 'fast', function () {
42                                         context.config.afterCondense.call( this, context );
43                                 } );
44                 },
45                 /**
46                  * Sets the value of a property, and updates the widget accordingly
47                  *
48                  * @param {Object} context
49                  * @param {string} property Name of property
50                  * @param {Mixed} value Value to set property with
51                  */
52                 configure: function ( context, property, value ) {
53                         // TODO: Validate creation using fallback values
54                         context.config[ property ] = value;
55                 }
57         };
59         $.fn.expandableField = function () {
61                 // Multi-context fields
62                 var returnValue,
63                         args = arguments;
65                 $( this ).each( function () {
66                         var key, context, timeout;
68                         /* Construction / Loading */
70                         context = $( this ).data( 'expandableField-context' );
72                         // TODO: Do we need to check both null and undefined?
73                         if ( context === undefined || context === null ) {
74                                 context = {
75                                         config: {
76                                                 // callback function for before collapse
77                                                 beforeCondense: function () {},
79                                                 // callback function for before expand
80                                                 beforeExpand: function () {},
82                                                 // callback function for after collapse
83                                                 afterCondense: function () {},
85                                                 // callback function for after expand
86                                                 afterExpand: function () {},
88                                                 // Whether the field should expand to the left or the right -- defaults to left
89                                                 expandToLeft: true
90                                         }
91                                 };
92                         }
94                         /* API */
95                         // Handle various calling styles
96                         if ( args.length > 0 ) {
97                                 if ( typeof args[ 0 ] === 'object' ) {
98                                         // Apply set of properties
99                                         for ( key in args[ 0 ] ) {
100                                                 $.expandableField.configure( context, key, args[ 0 ][ key ] );
101                                         }
102                                 } else if ( typeof args[ 0 ] === 'string' ) {
103                                         if ( args.length > 1 ) {
104                                                 // Set property values
105                                                 $.expandableField.configure( context, args[ 0 ], args[ 1 ] );
107                                         // TODO: Do we need to check both null and undefined?
108                                         } else if ( returnValue === null || returnValue === undefined ) {
109                                                 // Get property values, but don't give access to internal data - returns only the first
110                                                 returnValue = ( args[ 0 ] in context.config ? undefined : context.config[ args[ 0 ] ] );
111                                         }
112                                 }
113                         }
115                         /* Initialization */
117                         if ( context.data === undefined ) {
118                                 context.data = {
119                                         // The width of the field in it's condensed state
120                                         condensedWidth: $( this ).width(),
122                                         // The width of the field in it's expanded state
123                                         expandedWidth: $( this ).width() * 2,
125                                         // Reference to the field
126                                         $field: $( this )
127                                 };
129                                 $( this )
130                                         .addClass( 'expandableField' )
131                                         .focus( function ( e ) {
132                                                 clearTimeout( timeout );
133                                                 $.expandableField.expandField( e, context );
134                                         } )
135                                         .blur( function ( e ) {
136                                                 timeout = setTimeout( function () {
137                                                         $.expandableField.condenseField( e, context );
138                                                 }, 250 );
139                                         } );
140                         }
141                         // Store the context for next time
142                         $( this ).data( 'expandableField-context', context );
143                 } );
144                 return returnValue !== undefined ? returnValue : $( this );
145         };
147 }( jQuery ) );