Apply coding conventions for JavaScript
[lhc/web/wiklou.git] / resources / src / jquery / jquery.expandableField.js
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 */
17 ( function ( $ ) {
18
19 $.expandableField = {
20 /**
21 * Expand the field, make the callback
22 */
23 expandField: function ( e, context ) {
24 context.config.beforeExpand.call( context.data.$field, context );
25 context.data.$field
26 .animate( { 'width': context.data.expandedWidth }, 'fast', function () {
27 context.config.afterExpand.call( this, context );
28 } );
29 },
30 /**
31 * Condense the field, make the callback
32 */
33 condenseField: function ( e, context ) {
34 context.config.beforeCondense.call( context.data.$field, context );
35 context.data.$field
36 .animate( { 'width': context.data.condensedWidth }, 'fast', function () {
37 context.config.afterCondense.call( this, context );
38 } );
39 },
40 /**
41 * Sets the value of a property, and updates the widget accordingly
42 * @param property String Name of property
43 * @param value Mixed Value to set property with
44 */
45 configure: function ( context, property, value ) {
46 // TODO: Validate creation using fallback values
47 context.config[property] = value;
48 }
49
50 };
51
52 $.fn.expandableField = function () {
53
54 // Multi-context fields
55 var returnValue,
56 args = arguments;
57
58 $( this ).each( function () {
59 var key, context, timeout;
60
61 /* Construction / Loading */
62
63 context = $( this ).data( 'expandableField-context' );
64
65 // TODO: Do we need to check both null and undefined?
66 if ( context === undefined || context === null ) {
67 context = {
68 config: {
69 // callback function for before collapse
70 beforeCondense: function () {},
71
72 // callback function for before expand
73 beforeExpand: function () {},
74
75 // callback function for after collapse
76 afterCondense: function () {},
77
78 // callback function for after expand
79 afterExpand: function () {},
80
81 // Whether the field should expand to the left or the right -- defaults to left
82 expandToLeft: true
83 }
84 };
85 }
86
87 /* API */
88 // Handle various calling styles
89 if ( args.length > 0 ) {
90 if ( typeof args[0] === 'object' ) {
91 // Apply set of properties
92 for ( key in args[0] ) {
93 $.expandableField.configure( context, key, args[0][key] );
94 }
95 } else if ( typeof args[0] === 'string' ) {
96 if ( args.length > 1 ) {
97 // Set property values
98 $.expandableField.configure( context, args[0], args[1] );
99
100 // TODO: Do we need to check both null and undefined?
101 } else if ( returnValue === null || returnValue === undefined ) {
102 // Get property values, but don't give access to internal data - returns only the first
103 returnValue = ( args[0] in context.config ? undefined : context.config[args[0]] );
104 }
105 }
106 }
107
108 /* Initialization */
109
110 if ( context.data === undefined ) {
111 context.data = {
112 // The width of the field in it's condensed state
113 condensedWidth: $( this ).width(),
114
115 // The width of the field in it's expanded state
116 expandedWidth: $( this ).width() * 2,
117
118 // Reference to the field
119 $field: $( this )
120 };
121
122 $( this )
123 .addClass( 'expandableField' )
124 .focus( function ( e ) {
125 clearTimeout( timeout );
126 $.expandableField.expandField( e, context );
127 } )
128 .blur( function ( e ) {
129 timeout = setTimeout( function () {
130 $.expandableField.condenseField( e, context );
131 }, 250 );
132 } );
133 }
134 // Store the context for next time
135 $( this ).data( 'expandableField-context', context );
136 } );
137 return returnValue !== undefined ? returnValue : $( this );
138 };
139
140 }( jQuery ) );