Upgrade to ExtJS 4.0.1 - Released 05/18/2011
[extjs.git] / docs / source / Picker.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-form-field-Picker-method-constructor'><span id='Ext-form-field-Picker'>/**
19 </span></span> * @class Ext.form.field.Picker
20  * @extends Ext.form.field.Trigger
21  * &lt;p&gt;An abstract class for fields that have a single trigger which opens a &quot;picker&quot; popup below
22  * the field, e.g. a combobox menu list or a date picker. It provides a base implementation for
23  * toggling the picker's visibility when the trigger is clicked, as well as keyboard navigation
24  * and some basic events. Sizing and alignment of the picker can be controlled via the {@link #matchFieldWidth}
25  * and {@link #pickerAlign}/{@link #pickerOffset} config properties respectively.&lt;/p&gt;
26  * &lt;p&gt;You would not normally use this class directly, but instead use it as the parent class for
27  * a specific picker field implementation. Subclasses must implement the {@link #createPicker} method
28  * to create a picker component appropriate for the field.&lt;/p&gt;
29  *
30  * @xtype pickerfield
31  * @constructor
32  * Create a new picker field
33  * @param {Object} config
34  */
35 Ext.define('Ext.form.field.Picker', {
36     extend: 'Ext.form.field.Trigger',
37     alias: 'widget.pickerfield',
38     alternateClassName: 'Ext.form.Picker',
39     requires: ['Ext.util.KeyNav'],
40
41 <span id='Ext-form-field-Picker-cfg-matchFieldWidth'>    /**
42 </span>     * @cfg {Boolean} matchFieldWidth
43      * Whether the picker dropdown's width should be explicitly set to match the width of the field.
44      * Defaults to &lt;tt&gt;true&lt;/tt&gt;.
45      */
46     matchFieldWidth: true,
47
48 <span id='Ext-form-field-Picker-cfg-pickerAlign'>    /**
49 </span>     * @cfg {String} pickerAlign
50      * The {@link Ext.core.Element#alignTo alignment position} with which to align the picker. Defaults
51      * to &lt;tt&gt;&quot;tl-bl?&quot;&lt;/tt&gt;
52      */
53     pickerAlign: 'tl-bl?',
54
55 <span id='Ext-form-field-Picker-cfg-pickerOffset'>    /**
56 </span>     * @cfg {Array} pickerOffset
57      * An offset [x,y] to use in addition to the {@link #pickerAlign} when positioning the picker.
58      * Defaults to undefined.
59      */
60
61 <span id='Ext-form-field-Picker-cfg-openCls'>    /**
62 </span>     * @cfg {String} openCls
63      * A class to be added to the field's {@link #bodyEl} element when the picker is opened. Defaults
64      * to 'x-pickerfield-open'.
65      */
66     openCls: Ext.baseCSSPrefix + 'pickerfield-open',
67
68 <span id='Ext-form-field-Picker-property-isExpanded'>    /**
69 </span>     * @property isExpanded
70      * @type Boolean
71      * True if the picker is currently expanded, false if not.
72      */
73
74 <span id='Ext-form-field-Picker-cfg-editable'>    /**
75 </span>     * @cfg {Boolean} editable &lt;tt&gt;false&lt;/tt&gt; to prevent the user from typing text directly into the field;
76      * the field can only have its value set via selecting a value from the picker. In this state, the picker
77      * can also be opened by clicking directly on the input field itself.
78      * (defaults to &lt;tt&gt;true&lt;/tt&gt;).
79      */
80     editable: true,
81
82
83     initComponent: function() {
84         this.callParent();
85
86         // Custom events
87         this.addEvents(
88 <span id='Ext-form-field-Picker-event-expand'>            /**
89 </span>             * @event expand
90              * Fires when the field's picker is expanded.
91              * @param {Ext.form.field.Picker} field This field instance
92              */
93             'expand',
94 <span id='Ext-form-field-Picker-event-collapse'>            /**
95 </span>             * @event collapse
96              * Fires when the field's picker is collapsed.
97              * @param {Ext.form.field.Picker} field This field instance
98              */
99             'collapse',
100 <span id='Ext-form-field-Picker-event-select'>            /**
101 </span>             * @event select
102              * Fires when a value is selected via the picker.
103              * @param {Ext.form.field.Picker} field This field instance
104              * @param {Mixed} value The value that was selected. The exact type of this value is dependent on
105              * the individual field and picker implementations.
106              */
107             'select'
108         );
109     },
110
111
112     initEvents: function() {
113         var me = this;
114         me.callParent();
115
116         // Add handlers for keys to expand/collapse the picker
117         me.keyNav = Ext.create('Ext.util.KeyNav', me.inputEl, {
118             down: function() {
119                 if (!me.isExpanded) {
120                     // Don't call expand() directly as there may be additional processing involved before
121                     // expanding, e.g. in the case of a ComboBox query.
122                     me.onTriggerClick();
123                 }
124             },
125             esc: me.collapse,
126             scope: me,
127             forceKeyDown: true
128         });
129
130         // Non-editable allows opening the picker by clicking the field
131         if (!me.editable) {
132             me.mon(me.inputEl, 'click', me.onTriggerClick, me);
133         }
134
135         // Disable native browser autocomplete
136         if (Ext.isGecko) {
137             me.inputEl.dom.setAttribute('autocomplete', 'off');
138         }
139     },
140
141
142 <span id='Ext-form-field-Picker-method-expand'>    /**
143 </span>     * Expand this field's picker dropdown.
144      */
145     expand: function() {
146         var me = this,
147             bodyEl, picker, collapseIf;
148
149         if (me.rendered &amp;&amp; !me.isExpanded &amp;&amp; !me.isDestroyed) {
150             bodyEl = me.bodyEl;
151             picker = me.getPicker();
152             collapseIf = me.collapseIf;
153
154             // show the picker and set isExpanded flag
155             picker.show();
156             me.isExpanded = true;
157             me.alignPicker();
158             bodyEl.addCls(me.openCls);
159
160             // monitor clicking and mousewheel
161             me.mon(Ext.getDoc(), {
162                 mousewheel: collapseIf,
163                 mousedown: collapseIf,
164                 scope: me
165             });
166             Ext.EventManager.onWindowResize(me.alignPicker, me);
167             me.fireEvent('expand', me);
168             me.onExpand();
169         }
170     },
171
172     onExpand: Ext.emptyFn,
173
174 <span id='Ext-form-field-Picker-method-alignPicker'>    /**
175 </span>     * @protected
176      * Aligns the picker to the
177      */
178     alignPicker: function() {
179         var me = this,
180             picker, isAbove,
181             aboveSfx = '-above';
182
183         if (this.isExpanded) {
184             picker = me.getPicker();
185             if (me.matchFieldWidth) {
186                 // Auto the height (it will be constrained by min and max width) unless there are no records to display.
187                 picker.setSize(me.bodyEl.getWidth(), picker.store &amp;&amp; picker.store.getCount() ? null : 0);
188             }
189             if (picker.isFloating()) {
190                 picker.alignTo(me.inputEl, me.pickerAlign, me.pickerOffset);
191
192                 // add the {openCls}-above class if the picker was aligned above
193                 // the field due to hitting the bottom of the viewport
194                 isAbove = picker.el.getY() &lt; me.inputEl.getY();
195                 me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);
196                 picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
197             }
198         }
199     },
200
201 <span id='Ext-form-field-Picker-method-collapse'>    /**
202 </span>     * Collapse this field's picker dropdown.
203      */
204     collapse: function() {
205         if (this.isExpanded &amp;&amp; !this.isDestroyed) {
206             var me = this,
207                 openCls = me.openCls,
208                 picker = me.picker,
209                 doc = Ext.getDoc(),
210                 collapseIf = me.collapseIf,
211                 aboveSfx = '-above';
212
213             // hide the picker and set isExpanded flag
214             picker.hide();
215             me.isExpanded = false;
216
217             // remove the openCls
218             me.bodyEl.removeCls([openCls, openCls + aboveSfx]);
219             picker.el.removeCls(picker.baseCls + aboveSfx);
220
221             // remove event listeners
222             doc.un('mousewheel', collapseIf, me);
223             doc.un('mousedown', collapseIf, me);
224             Ext.EventManager.removeResizeListener(me.alignPicker, me);
225             me.fireEvent('collapse', me);
226             me.onCollapse();
227         }
228     },
229
230     onCollapse: Ext.emptyFn,
231
232
233 <span id='Ext-form-field-Picker-method-collapseIf'>    /**
234 </span>     * @private
235      * Runs on mousewheel and mousedown of doc to check to see if we should collapse the picker
236      */
237     collapseIf: function(e) {
238         var me = this;
239         if (!me.isDestroyed &amp;&amp; !e.within(me.bodyEl, false, true) &amp;&amp; !e.within(me.picker.el, false, true)) {
240             me.collapse();
241         }
242     },
243
244 <span id='Ext-form-field-Picker-method-getPicker'>    /**
245 </span>     * Return a reference to the picker component for this field, creating it if necessary by
246      * calling {@link #createPicker}.
247      * @return {Ext.Component} The picker component
248      */
249     getPicker: function() {
250         var me = this;
251         return me.picker || (me.picker = me.createPicker());
252     },
253
254 <span id='Ext-form-field-Picker-property-createPicker'>    /**
255 </span>     * Create and return the component to be used as this field's picker. Must be implemented
256      * by subclasses of Picker.
257      * @return {Ext.Component} The picker component
258      */
259     createPicker: Ext.emptyFn,
260
261 <span id='Ext-form-field-Picker-method-onTriggerClick'>    /**
262 </span>     * Handles the trigger click; by default toggles between expanding and collapsing the
263      * picker component.
264      */
265     onTriggerClick: function() {
266         var me = this;
267         if (!me.readOnly &amp;&amp; !me.disabled) {
268             if (me.isExpanded) {
269                 me.collapse();
270             } else {
271                 me.expand();
272             }
273             me.inputEl.focus();
274         }
275     },
276
277     mimicBlur: function(e) {
278         var me = this,
279             picker = me.picker;
280         // ignore mousedown events within the picker element
281         if (!picker || !e.within(picker.el, false, true)) {
282             me.callParent(arguments);
283         }
284     },
285
286     onDestroy : function(){
287         var me = this;
288         Ext.EventManager.removeResizeListener(me.alignPicker, me);
289         Ext.destroy(me.picker, me.keyNav);
290         me.callParent();
291     }
292
293 });
294
295 </pre>
296 </body>
297 </html>