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; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-form-field-Trigger-method-constructor'><span id='Ext-form-field-Trigger'>/**
19 </span></span> * @class Ext.form.field.Trigger
20 * @extends Ext.form.field.Text
21 * <p>Provides a convenient wrapper for TextFields that adds a clickable trigger button (looks like a combobox by default).
22 * The trigger has no default action, so you must assign a function to implement the trigger click handler by
23 * overriding {@link #onTriggerClick}. You can create a Trigger field directly, as it renders exactly like a combobox
24 * for which you can provide a custom implementation.
25 * {@img Ext.form.field.Trigger/Ext.form.field.Trigger.png Ext.form.field.Trigger component}
26 * For example:</p>
27 * <pre><code>
28 Ext.define('Ext.ux.CustomTrigger', {
29 extend: 'Ext.form.field.Trigger',
30 alias: 'widget.customtrigger',
32 // override onTriggerClick
33 onTriggerClick: function() {
34 Ext.Msg.alert('Status', 'You clicked my trigger!');
38 Ext.create('Ext.form.FormPanel', {
39 title: 'Form with TriggerField',
42 renderTo: Ext.getBody(),
44 xtype: 'customtrigger',
45 fieldLabel: 'Sample Trigger',
46 emptyText: 'click the trigger',
49 </code></pre>
51 * <p>However, in general you will most likely want to use Trigger as the base class for a reusable component.
52 * {@link Ext.form.field.Date} and {@link Ext.form.field.ComboBox} are perfect examples of this.</p>
55 * Create a new Trigger field.
56 * @param {Object} config Configuration options (valid {@Ext.form.field.Text} config options will also be applied
57 * to the base Text field)
59 Ext.define('Ext.form.field.Trigger', {
60 extend:'Ext.form.field.Text',
61 alias: ['widget.triggerfield', 'widget.trigger'],
62 requires: ['Ext.core.DomHelper', 'Ext.util.ClickRepeater', 'Ext.layout.component.field.Trigger'],
63 alternateClassName: ['Ext.form.TriggerField', 'Ext.form.TwinTriggerField', 'Ext.form.Trigger'],
66 '<input id="{id}" type="{type}" ',
67 '<tpl if="name">name="{name}" </tpl>',
68 '<tpl if="size">size="{size}" </tpl>',
69 '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
70 'class="{fieldCls} {typeCls}" autocomplete="off" />',
71 '<div class="{triggerWrapCls}" role="presentation">',
73 '<div class="{clearCls}" role="presentation"></div>',
81 <span id='Ext-form-field-Trigger-cfg-triggerCls'> /**
82 </span> * @cfg {String} triggerCls
83 * An additional CSS class used to style the trigger button. The trigger will always get the
84 * {@link #triggerBaseCls} by default and <tt>triggerCls</tt> will be <b>appended</b> if specified.
85 * Defaults to undefined.
88 <span id='Ext-form-field-Trigger-cfg-triggerBaseCls'> /**
89 </span> * @cfg {String} triggerBaseCls
90 * The base CSS class that is always added to the trigger button. The {@link #triggerCls} will be
91 * appended in addition to this class.
93 triggerBaseCls: Ext.baseCSSPrefix + 'form-trigger',
95 <span id='Ext-form-field-Trigger-cfg-triggerWrapCls'> /**
96 </span> * @cfg {String} triggerWrapCls
97 * The CSS class that is added to the div wrapping the trigger button(s).
99 triggerWrapCls: Ext.baseCSSPrefix + 'form-trigger-wrap',
101 <span id='Ext-form-field-Trigger-cfg-hideTrigger'> /**
102 </span> * @cfg {Boolean} hideTrigger <tt>true</tt> to hide the trigger element and display only the base
103 * text field (defaults to <tt>false</tt>)
107 <span id='Ext-form-field-Trigger-cfg-editable'> /**
108 </span> * @cfg {Boolean} editable <tt>false</tt> to prevent the user from typing text directly into the field;
109 * the field can only have its value set via an action invoked by the trigger. (defaults to <tt>true</tt>).
113 <span id='Ext-form-field-Trigger-cfg-readOnly'> /**
114 </span> * @cfg {Boolean} readOnly <tt>true</tt> to prevent the user from changing the field, and
115 * hides the trigger. Supercedes the editable and hideTrigger options if the value is true.
116 * (defaults to <tt>false</tt>)
120 <span id='Ext-form-field-Trigger-cfg-selectOnFocus'> /**
121 </span> * @cfg {Boolean} selectOnFocus <tt>true</tt> to select any existing text in the field immediately on focus.
122 * Only applies when <tt>{@link #editable editable} = true</tt> (defaults to <tt>false</tt>).
125 <span id='Ext-form-field-Trigger-cfg-repeatTriggerClick'> /**
126 </span> * @cfg {Boolean} repeatTriggerClick <tt>true</tt> to attach a {@link Ext.util.ClickRepeater click repeater}
127 * to the trigger. Defaults to <tt>false</tt>.
129 repeatTriggerClick: false,
132 <span id='Ext-form-field-Trigger-method-autoSize'> /**
136 autoSize: Ext.emptyFn,
142 triggerIndexRe: /trigger-index-(\d+)/,
144 componentLayout: 'triggerfield',
146 initComponent: function() {
147 this.wrapFocusCls = this.triggerWrapCls + '-focus';
148 this.callParent(arguments);
152 onRender: function(ct, position) {
155 triggerBaseCls = me.triggerBaseCls,
156 triggerWrapCls = me.triggerWrapCls,
160 // triggerCls is a synonym for trigger1Cls, so copy it.
161 // TODO this trigger<n>Cls API design doesn't feel clean, especially where it butts up against the
162 // single triggerCls config. Should rethink this, perhaps something more structured like a list of
163 // trigger config objects that hold cls, handler, etc.
164 if (!me.trigger1Cls) {
165 me.trigger1Cls = me.triggerCls;
168 // Create as many trigger elements as we have trigger<n>Cls configs, but always at least one
169 for (i = 0; (triggerCls = me['trigger' + (i + 1) + 'Cls']) || i < 1; i++) {
170 triggerConfigs.push({
171 cls: [Ext.baseCSSPrefix + 'trigger-index-' + i, triggerBaseCls, triggerCls].join(' '),
175 triggerConfigs[i - 1].cls += ' ' + triggerBaseCls + '-last';
177 Ext.applyIf(me.renderSelectors, {
178 <span id='Ext-form-field-Trigger-property-triggerWrap'> /**
179 </span> * @property triggerWrap
180 * @type Ext.core.Element
181 * A reference to the div element wrapping the trigger button(s). Only set after the field has been rendered.
183 triggerWrap: '.' + triggerWrapCls
185 Ext.applyIf(me.subTplData, {
186 triggerWrapCls: triggerWrapCls,
187 triggerEl: Ext.core.DomHelper.markup(triggerConfigs),
188 clearCls: me.clearCls
191 me.callParent(arguments);
193 <span id='Ext-form-field-Trigger-property-triggerEl'> /**
194 </span> * @property triggerEl
195 * @type Ext.CompositeElement
196 * A composite of all the trigger button elements. Only set after the field has been rendered.
198 me.triggerEl = Ext.select('.' + triggerBaseCls, true, me.triggerWrap.dom);
200 me.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
204 onEnable: function() {
206 this.triggerWrap.unmask();
209 onDisable: function() {
211 this.triggerWrap.mask();
214 afterRender: function() {
216 this.updateEditState();
219 updateEditState: function() {
221 inputEl = me.inputEl,
222 triggerWrap = me.triggerWrap,
223 noeditCls = Ext.baseCSSPrefix + 'trigger-noedit',
229 inputEl.addCls(noeditCls);
234 inputEl.removeCls(noeditCls);
237 inputEl.addCls(noeditCls);
240 displayed = !me.hideTrigger;
243 triggerWrap.setDisplayed(displayed);
244 inputEl.dom.readOnly = readOnly;
245 me.doComponentLayout();
249 <span id='Ext-form-field-Trigger-method-getTriggerWidth'> /**
250 </span> * Get the total width of the trigger button area. Only useful after the field has been rendered.
251 * @return {Number} The trigger width
253 getTriggerWidth: function() {
255 triggerWrap = me.triggerWrap,
256 totalTriggerWidth = 0;
257 if (triggerWrap && !me.hideTrigger && !me.readOnly) {
258 me.triggerEl.each(function(trigger) {
259 totalTriggerWidth += trigger.getWidth();
261 totalTriggerWidth += me.triggerWrap.getFrameWidth('lr');
263 return totalTriggerWidth;
266 setHideTrigger: function(hideTrigger) {
267 if (hideTrigger != this.hideTrigger) {
268 this.hideTrigger = hideTrigger;
269 this.updateEditState();
273 <span id='Ext-form-field-Trigger-method-setEditable'> /**
274 </span> * @param {Boolean} editable True to allow the user to directly edit the field text
275 * Allow or prevent the user from directly editing the field text. If false is passed,
276 * the user will only be able to modify the field using the trigger. Will also add
277 * a click event to the text field which will call the trigger. This method
278 * is the runtime equivalent of setting the 'editable' config option at config time.
280 setEditable: function(editable) {
281 if (editable != this.editable) {
282 this.editable = editable;
283 this.updateEditState();
287 <span id='Ext-form-field-Trigger-method-setReadOnly'> /**
288 </span> * @param {Boolean} readOnly True to prevent the user changing the field and explicitly
290 * Setting this to true will superceed settings editable and hideTrigger.
291 * Setting this to false will defer back to editable and hideTrigger. This method
292 * is the runtime equivalent of setting the 'readOnly' config option at config time.
294 setReadOnly: function(readOnly) {
295 if (readOnly != this.readOnly) {
296 this.readOnly = readOnly;
297 this.updateEditState();
302 initTrigger: function() {
304 triggerWrap = me.triggerWrap,
305 triggerEl = me.triggerEl;
307 if (me.repeatTriggerClick) {
308 me.triggerRepeater = Ext.create('Ext.util.ClickRepeater', triggerWrap, {
309 preventDefault: true,
310 handler: function(cr, e) {
311 me.onTriggerWrapClick(e);
315 me.mon(me.triggerWrap, 'click', me.onTriggerWrapClick, me);
318 triggerEl.addClsOnOver(me.triggerBaseCls + '-over');
319 triggerEl.each(function(el, c, i) {
320 el.addClsOnOver(me['trigger' + (i + 1) + 'Cls'] + '-over');
322 triggerEl.addClsOnClick(me.triggerBaseCls + '-click');
323 triggerEl.each(function(el, c, i) {
324 el.addClsOnClick(me['trigger' + (i + 1) + 'Cls'] + '-click');
329 onDestroy: function() {
331 Ext.destroyMembers(me, 'triggerRepeater', 'triggerWrap', 'triggerEl');
337 onFocus: function() {
341 me.bodyEl.addCls(me.wrapFocusCls);
343 me.mon(me.doc, 'mousedown', me.mimicBlur, me, {
347 me.on('specialkey', me.checkTab, me);
353 checkTab: function(me, e) {
354 if (!this.ignoreMonitorTab && e.getKey() == e.TAB) {
363 mimicBlur: function(e) {
364 if (!this.isDestroyed && !this.bodyEl.contains(e.target) && this.validateBlur(e)) {
370 triggerBlur: function() {
373 me.mun(me.doc, 'mousedown', me.mimicBlur, me);
374 if (me.monitorTab && me.inputEl) {
375 me.un('specialkey', me.checkTab, me);
377 Ext.form.field.Trigger.superclass.onBlur.call(me);
379 me.bodyEl.removeCls(me.wrapFocusCls);
383 beforeBlur: Ext.emptyFn,
386 // This should be overridden by any subclass that needs to check whether or not the field can be blurred.
387 validateBlur: function(e) {
392 // process clicks upon triggers.
393 // determine which trigger index, and dispatch to the appropriate click handler
394 onTriggerWrapClick: function(e) {
396 t = e && e.getTarget('.' + Ext.baseCSSPrefix + 'form-trigger', null),
397 match = t && t.className.match(me.triggerIndexRe),
401 if (match && !me.readOnly) {
402 idx = parseInt(match[1], 10);
403 triggerClickMethod = me['onTrigger' + (idx + 1) + 'Click'] || me.onTriggerClick;
404 if (triggerClickMethod) {
405 triggerClickMethod.call(me, e);
410 <span id='Ext-form-field-Trigger-method-onTriggerClick'> /**
411 </span> * The function that should handle the trigger's click event. This method does nothing by default
412 * until overridden by an implementing function. See Ext.form.field.ComboBox and Ext.form.field.Date for
413 * sample implementations.
415 * @param {Ext.EventObject} e
417 onTriggerClick: Ext.emptyFn
419 <span id='Ext-form-field-Trigger-cfg-grow'> /**
420 </span> * @cfg {Boolean} grow @hide
422 <span id='Ext-form-field-Trigger-cfg-growMin'> /**
423 </span> * @cfg {Number} growMin @hide
425 <span id='Ext-form-field-Trigger-cfg-growMax'> /**
426 </span> * @cfg {Number} growMax @hide