<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
<style type="text/css">
|
.highlight { display: block; background-color: #ddd; }
|
</style>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js"><span id='Ext-form-field-Picker'>/**
|
</span> * An abstract class for fields that have a single trigger which opens a "picker" popup below the field, e.g. a combobox
|
* menu list or a date picker. It provides a base implementation for toggling the picker's visibility when the trigger
|
* is clicked, as well as keyboard navigation and some basic events. Sizing and alignment of the picker can be
|
* controlled via the {@link #matchFieldWidth} and {@link #pickerAlign}/{@link #pickerOffset} config properties
|
* respectively.
|
*
|
* You would not normally use this class directly, but instead use it as the parent class for a specific picker field
|
* implementation. Subclasses must implement the {@link #createPicker} method to create a picker component appropriate
|
* for the field.
|
*/
|
Ext.define('Ext.form.field.Picker', {
|
extend: 'Ext.form.field.Trigger',
|
alias: 'widget.pickerfield',
|
alternateClassName: 'Ext.form.Picker',
|
requires: ['Ext.util.KeyNav'],
|
|
<span id='Ext-form-field-Picker-cfg-matchFieldWidth'> /**
|
</span> * @cfg {Boolean} matchFieldWidth
|
* Whether the picker dropdown's width should be explicitly set to match the width of the field. Defaults to true.
|
*/
|
matchFieldWidth: true,
|
|
<span id='Ext-form-field-Picker-cfg-pickerAlign'> /**
|
</span> * @cfg {String} pickerAlign
|
* The {@link Ext.util.Positionable#alignTo alignment position} with which to align the picker. Defaults to "tl-bl?"
|
*/
|
pickerAlign: 'tl-bl?',
|
|
<span id='Ext-form-field-Picker-cfg-pickerOffset'> /**
|
</span> * @cfg {Number[]} pickerOffset
|
* An offset [x,y] to use in addition to the {@link #pickerAlign} when positioning the picker.
|
* Defaults to undefined.
|
*/
|
|
<span id='Ext-form-field-Picker-cfg-openCls'> /**
|
</span> * @cfg {String} [openCls='x-pickerfield-open']
|
* A class to be added to the field's {@link #bodyEl} element when the picker is opened.
|
*/
|
openCls: Ext.baseCSSPrefix + 'pickerfield-open',
|
|
<span id='Ext-form-field-Picker-property-isExpanded'> /**
|
</span> * @property {Boolean} isExpanded
|
* True if the picker is currently expanded, false if not.
|
*/
|
|
<span id='Ext-form-field-Picker-cfg-editable'> /**
|
</span> * @cfg {Boolean} editable
|
* False to prevent the user from typing text directly into the field; the field can only have its value set via
|
* selecting a value from the picker. In this state, the picker can also be opened by clicking directly on the input
|
* field itself.
|
*/
|
editable: true,
|
|
|
<span id='Ext-form-field-Picker-method-initComponent'> initComponent: function() {
|
</span> this.callParent();
|
|
// Custom events
|
this.addEvents(
|
<span id='Ext-form-field-Picker-event-expand'> /**
|
</span> * @event expand
|
* Fires when the field's picker is expanded.
|
* @param {Ext.form.field.Picker} field This field instance
|
*/
|
'expand',
|
<span id='Ext-form-field-Picker-event-collapse'> /**
|
</span> * @event collapse
|
* Fires when the field's picker is collapsed.
|
* @param {Ext.form.field.Picker} field This field instance
|
*/
|
'collapse',
|
<span id='Ext-form-field-Picker-event-select'> /**
|
</span> * @event select
|
* Fires when a value is selected via the picker.
|
* @param {Ext.form.field.Picker} field This field instance
|
* @param {Object} value The value that was selected. The exact type of this value is dependent on
|
* the individual field and picker implementations.
|
*/
|
'select'
|
);
|
},
|
|
|
<span id='Ext-form-field-Picker-method-initEvents'> initEvents: function() {
|
</span> var me = this;
|
me.callParent();
|
|
// Add handlers for keys to expand/collapse the picker
|
me.keyNav = new Ext.util.KeyNav(me.inputEl, {
|
down: me.onDownArrow,
|
esc: {
|
handler: me.onEsc,
|
scope: me,
|
defaultEventAction: false
|
},
|
scope: me,
|
forceKeyDown: true
|
});
|
|
// Non-editable allows opening the picker by clicking the field
|
if (!me.editable) {
|
me.mon(me.inputEl, 'click', me.onTriggerClick, me);
|
}
|
|
// Disable native browser autocomplete
|
if (Ext.isGecko) {
|
me.inputEl.dom.setAttribute('autocomplete', 'off');
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-onEsc'> // private
|
</span> onEsc: function(e) {
|
if (Ext.isIE) {
|
// Stop the esc key from "restoring" the previous value in IE
|
// For example, type "foo". Highlight all the text, hit backspace.
|
// Hit esc, "foo" will be restored. This behaviour doesn't occur
|
// in any other browsers
|
e.preventDefault();
|
}
|
|
if (this.isExpanded) {
|
this.collapse();
|
e.stopEvent();
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-onDownArrow'> onDownArrow: function(e) {
|
</span> if (!this.isExpanded) {
|
// Don't call expand() directly as there may be additional processing involved before
|
// expanding, e.g. in the case of a ComboBox query.
|
this.onTriggerClick();
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-expand'> /**
|
</span> * Expands this field's picker dropdown.
|
*/
|
expand: function() {
|
var me = this,
|
bodyEl, picker, collapseIf;
|
|
if (me.rendered && !me.isExpanded && !me.isDestroyed) {
|
me.expanding = true;
|
bodyEl = me.bodyEl;
|
picker = me.getPicker();
|
collapseIf = me.collapseIf;
|
|
// show the picker and set isExpanded flag
|
picker.show();
|
me.isExpanded = true;
|
me.alignPicker();
|
bodyEl.addCls(me.openCls);
|
|
// monitor clicking and mousewheel
|
me.mon(Ext.getDoc(), {
|
mousewheel: collapseIf,
|
mousedown: collapseIf,
|
scope: me
|
});
|
Ext.EventManager.onWindowResize(me.alignPicker, me);
|
me.fireEvent('expand', me);
|
me.onExpand();
|
delete me.expanding;
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-onExpand'> onExpand: Ext.emptyFn,
|
</span>
|
<span id='Ext-form-field-Picker-method-alignPicker'> /**
|
</span> * Aligns the picker to the input element
|
* @protected
|
*/
|
alignPicker: function() {
|
var me = this,
|
picker = me.getPicker();
|
|
if (me.isExpanded) {
|
if (me.matchFieldWidth) {
|
// Auto the height (it will be constrained by min and max width) unless there are no records to display.
|
picker.setWidth(me.bodyEl.getWidth());
|
}
|
if (picker.isFloating()) {
|
me.doAlign();
|
}
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-doAlign'> /**
|
</span> * Performs the alignment on the picker using the class defaults
|
* @private
|
*/
|
doAlign: function(){
|
var me = this,
|
picker = me.picker,
|
aboveSfx = '-above',
|
isAbove;
|
|
// Align to the trigger wrap because the border isn't always on the input element, which
|
// can cause the offset to be off
|
me.picker.alignTo(me.triggerWrap, me.pickerAlign, me.pickerOffset);
|
// add the {openCls}-above class if the picker was aligned above
|
// the field due to hitting the bottom of the viewport
|
isAbove = picker.el.getY() < me.inputEl.getY();
|
me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);
|
picker[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
|
},
|
|
<span id='Ext-form-field-Picker-method-collapse'> /**
|
</span> * Collapses this field's picker dropdown.
|
*/
|
collapse: function() {
|
if (this.isExpanded && !this.isDestroyed) {
|
var me = this,
|
openCls = me.openCls,
|
picker = me.picker,
|
doc = Ext.getDoc(),
|
collapseIf = me.collapseIf,
|
aboveSfx = '-above';
|
|
// hide the picker and set isExpanded flag
|
picker.hide();
|
me.isExpanded = false;
|
|
// remove the openCls
|
me.bodyEl.removeCls([openCls, openCls + aboveSfx]);
|
picker.el.removeCls(picker.baseCls + aboveSfx);
|
|
// remove event listeners
|
doc.un('mousewheel', collapseIf, me);
|
doc.un('mousedown', collapseIf, me);
|
Ext.EventManager.removeResizeListener(me.alignPicker, me);
|
me.fireEvent('collapse', me);
|
me.onCollapse();
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-onCollapse'> onCollapse: Ext.emptyFn,
|
</span>
|
|
<span id='Ext-form-field-Picker-method-collapseIf'> /**
|
</span> * @private
|
* Runs on mousewheel and mousedown of doc to check to see if we should collapse the picker
|
*/
|
collapseIf: function(e) {
|
var me = this;
|
|
if (!me.isDestroyed && !e.within(me.bodyEl, false, true) && !e.within(me.picker.el, false, true) && !me.isEventWithinPickerLoadMask(e)) {
|
me.collapse();
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-getPicker'> /**
|
</span> * Returns a reference to the picker component for this field, creating it if necessary by
|
* calling {@link #createPicker}.
|
* @return {Ext.Component} The picker component
|
*/
|
getPicker: function() {
|
var me = this;
|
return me.picker || (me.picker = me.createPicker());
|
},
|
|
<span id='Ext-form-field-Picker-method-createPicker'> /**
|
</span> * @method
|
* Creates and returns the component to be used as this field's picker. Must be implemented by subclasses of Picker.
|
* The current field should also be passed as a configuration option to the picker component as the pickerField
|
* property.
|
*/
|
createPicker: Ext.emptyFn,
|
|
<span id='Ext-form-field-Picker-method-onTriggerClick'> /**
|
</span> * Handles the trigger click; by default toggles between expanding and collapsing the picker component.
|
* @protected
|
*/
|
onTriggerClick: function() {
|
var me = this;
|
if (!me.readOnly && !me.disabled) {
|
if (me.isExpanded) {
|
me.collapse();
|
} else {
|
me.expand();
|
}
|
me.inputEl.focus();
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-triggerBlur'> triggerBlur: function() {
|
</span> var picker = this.picker;
|
|
this.callParent(arguments);
|
if (picker && picker.isVisible()) {
|
picker.hide();
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-mimicBlur'> mimicBlur: function(e) {
|
</span> var me = this,
|
picker = me.picker;
|
// ignore mousedown events within the picker element
|
if (!picker || !e.within(picker.el, false, true) && !me.isEventWithinPickerLoadMask(e)) {
|
me.callParent(arguments);
|
}
|
},
|
|
<span id='Ext-form-field-Picker-method-onDestroy'> onDestroy : function(){
|
</span> var me = this,
|
picker = me.picker;
|
|
Ext.EventManager.removeResizeListener(me.alignPicker, me);
|
Ext.destroy(me.keyNav);
|
if (picker) {
|
delete picker.pickerField;
|
picker.destroy();
|
}
|
me.callParent();
|
},
|
|
<span id='Ext-form-field-Picker-method-isEventWithinPickerLoadMask'> /**
|
</span> * returns true if the picker has a load mask and the passed event is within the load mask
|
* @private
|
* @param {Ext.EventObject} e
|
* @return {Boolean}
|
*/
|
isEventWithinPickerLoadMask: function(e) {
|
var loadMask = this.picker.loadMask;
|
|
return loadMask ? e.within(loadMask.maskEl, false, true) || e.within(loadMask.el, false, true) : false;
|
}
|
|
});
|
|
</pre>
|
</body>
|
</html>
|