TriggerField_wev8.js
12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
/*!
* Ext JS Library 3.0.0
* Copyright(c) 2006-2009 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
/**
* @class Ext.form.TriggerField
* @extends Ext.form.TextField
* Provides a convenient wrapper for TextFields that adds a clickable trigger button (looks like a combobox by default).
* The trigger has no default action, so you must assign a function to implement the trigger click handler by
* overriding {@link #onTriggerClick}. You can create a TriggerField directly, as it renders exactly like a combobox
* for which you can provide a custom implementation. For example:
* <pre><code>
var trigger = new Ext.form.TriggerField();
trigger.onTriggerClick = myTriggerFn;
trigger.applyToMarkup('my-field');
</code></pre>
*
* However, in general you will most likely want to use TriggerField as the base class for a reusable component.
* {@link Ext.form.DateField} and {@link Ext.form.ComboBox} are perfect examples of this.
*
* @constructor
* Create a new TriggerField.
* @param {Object} config Configuration options (valid {@Ext.form.TextField} config options will also be applied
* to the base TextField)
* @xtype trigger
*/
Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
/**
* @cfg {String} triggerClass
* An additional CSS class used to style the trigger button. The trigger will always get the
* class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.
*/
/**
* @cfg {Mixed} triggerConfig
* <p>A {@link Ext.DomHelper DomHelper} config object specifying the structure of the
* trigger element for this Field. (Optional).</p>
* <p>Specify this when you need a customized element to act as the trigger button for a TriggerField.</p>
* <p>Note that when using this option, it is the developer's responsibility to ensure correct sizing, positioning
* and appearance of the trigger. Defaults to:</p>
* <pre><code>{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass}</code></pre>
*/
/**
* @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or true for a default
* element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.
* See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details. Defaults to:</p>
* <pre><code>{tag: "input", type: "text", size: "16", autocomplete: "off"}</code></pre>
*/
defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
/**
* @cfg {Boolean} hideTrigger <tt>true</tt> to hide the trigger element and display only the base
* text field (defaults to <tt>false</tt>)
*/
hideTrigger:false,
/**
* @cfg {Boolean} editable <tt>false</tt> to prevent the user from typing text directly into the field,
* the field will only respond to a click on the trigger to set the value. (defaults to <tt>true</tt>)
*/
editable: true,
/**
* @cfg {String} wrapFocusClass The class added to the to the wrap of the trigger element. Defaults to
* <tt>x-trigger-wrap-focus</tt>.
*/
wrapFocusClass: 'x-trigger-wrap-focus',
/**
* @hide
* @method autoSize
*/
autoSize: Ext.emptyFn,
// private
monitorTab : true,
// private
deferHeight : true,
// private
mimicing : false,
actionMode: 'wrap',
// private
onResize : function(w, h){
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
if(typeof w == 'number'){
this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
}
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
},
// private
adjustSize : Ext.BoxComponent.prototype.adjustSize,
// private
getResizeEl : function(){
return this.wrap;
},
// private
getPositionEl : function(){
return this.wrap;
},
// private
alignErrorIcon : function(){
if(this.wrap){
this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
}
},
// private
onRender : function(ct, position){
Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
this.trigger = this.wrap.createChild(this.triggerConfig ||
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
if(this.hideTrigger){
this.trigger.setDisplayed(false);
}
this.initTrigger();
if(!this.width){
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
}
if(!this.editable){
this.editable = true;
this.setEditable(false);
}
},
afterRender : function(){
Ext.form.TriggerField.superclass.afterRender.call(this);
},
// private
initTrigger : function(){
this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
this.trigger.addClassOnOver('x-form-trigger-over');
this.trigger.addClassOnClick('x-form-trigger-click');
},
// private
onDestroy : function(){
Ext.destroy(this.trigger, this.wrap);
if (this.mimicing){
Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
}
Ext.form.TriggerField.superclass.onDestroy.call(this);
},
// private
onFocus : function(){
Ext.form.TriggerField.superclass.onFocus.call(this);
if(!this.mimicing){
this.wrap.addClass(this.wrapFocusClass);
this.mimicing = true;
Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
if(this.monitorTab){
this.el.on('keydown', this.checkTab, this);
}
}
},
// private
checkTab : function(e){
if(e.getKey() == e.TAB){
this.triggerBlur();
}
},
// private
onBlur : function(){
// do nothing
},
// private
mimicBlur : function(e){
if(!this.wrap.contains(e.target) && this.validateBlur(e)){
this.triggerBlur();
}
},
// private
triggerBlur : function(){
this.mimicing = false;
Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
if(this.monitorTab && this.el){
this.el.un("keydown", this.checkTab, this);
}
Ext.form.TriggerField.superclass.onBlur.call(this);
if(this.wrap){
this.wrap.removeClass(this.wrapFocusClass);
}
},
beforeBlur : Ext.emptyFn,
/**
* Allow or prevent the user from directly editing the field text. If false is passed,
* the user will only be able to modify the field using the trigger. This method
* is the runtime equivalent of setting the 'editable' config option at config time.
* @param {Boolean} value True to allow the user to directly edit the field text
*/
setEditable : function(value){
if(value == this.editable){
return;
}
this.editable = value;
if(!value){
this.el.addClass('x-trigger-noedit').on('click', this.onTriggerClick, this).dom.setAttribute('readOnly', true);
}else{
this.el.removeClass('x-trigger-noedit').un('click', this.onTriggerClick, this).dom.removeAttribute('readOnly');
}
},
// private
// This should be overriden by any subclass that needs to check whether or not the field can be blurred.
validateBlur : function(e){
return true;
},
/**
* The function that should handle the trigger's click event. This method does nothing by default
* until overridden by an implementing function. See Ext.form.ComboBox and Ext.form.DateField for
* sample implementations.
* @method
* @param {EventObject} e
*/
onTriggerClick : Ext.emptyFn
/**
* @cfg {Boolean} grow @hide
*/
/**
* @cfg {Number} growMin @hide
*/
/**
* @cfg {Number} growMax @hide
*/
});
/**
* @class Ext.form.TwinTriggerField
* @extends Ext.form.TriggerField
* TwinTriggerField is not a public class to be used directly. It is meant as an abstract base class
* to be extended by an implementing class. For an example of implementing this class, see the custom
* SearchField implementation here:
* <a href="http://extjs.com/deploy/ext/examples/form/custom.html">http://extjs.com/deploy/ext/examples/form/custom.html</a>
*/
Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
/**
* @cfg {Mixed} triggerConfig
* <p>A {@link Ext.DomHelper DomHelper} config object specifying the structure of the trigger elements
* for this Field. (Optional).</p>
* <p>Specify this when you need a customized element to contain the two trigger elements for this Field.
* Each trigger element must be marked by the CSS class <tt>x-form-trigger</tt> (also see
* <tt>{@link #trigger1Class}</tt> and <tt>{@link #trigger2Class}</tt>).</p>
* <p>Note that when using this option, it is the developer's responsibility to ensure correct sizing,
* positioning and appearance of the triggers.</p>
*/
/**
* @cfg {String} trigger1Class
* An additional CSS class used to style the trigger button. The trigger will always get the
* class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.
*/
/**
* @cfg {String} trigger2Class
* An additional CSS class used to style the trigger button. The trigger will always get the
* class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.
*/
initComponent : function(){
Ext.form.TwinTriggerField.superclass.initComponent.call(this);
this.triggerConfig = {
tag:'span', cls:'x-form-twin-triggers', cn:[
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
]};
},
getTrigger : function(index){
return this.triggers[index];
},
initTrigger : function(){
var ts = this.trigger.select('.x-form-trigger', true);
this.wrap.setStyle('overflow', 'hidden');
var triggerField = this;
ts.each(function(t, all, index){
t.hide = function(){
var w = triggerField.wrap.getWidth();
this.dom.style.display = 'none';
triggerField.el.setWidth(w-triggerField.trigger.getWidth());
};
t.show = function(){
var w = triggerField.wrap.getWidth();
this.dom.style.display = '';
triggerField.el.setWidth(w-triggerField.trigger.getWidth());
};
var triggerIndex = 'Trigger'+(index+1);
if(this['hide'+triggerIndex]){
t.dom.style.display = 'none';
}
this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
t.addClassOnOver('x-form-trigger-over');
t.addClassOnClick('x-form-trigger-click');
}, this);
this.triggers = ts.elements;
},
/**
* The function that should handle the trigger's click event. This method does nothing by default
* until overridden by an implementing function. See {@link Ext.form.TriggerField#onTriggerClick}
* for additional information.
* @method
* @param {EventObject} e
*/
onTrigger1Click : Ext.emptyFn,
/**
* The function that should handle the trigger's click event. This method does nothing by default
* until overridden by an implementing function. See {@link Ext.form.TriggerField#onTriggerClick}
* for additional information.
* @method
* @param {EventObject} e
*/
onTrigger2Click : Ext.emptyFn
});
Ext.reg('trigger', Ext.form.TriggerField);