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