Labelable.html
36.4 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
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
<!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-Labelable'>/**
</span> * A mixin which allows a component to be configured and decorated with a label and/or error message as is
* common for form fields. This is used by e.g. Ext.form.field.Base and Ext.form.FieldContainer
* to let them be managed by the Field layout.
*
* NOTE: This mixin is mainly for internal library use and most users should not need to use it directly. It
* is more likely you will want to use one of the component classes that import this mixin, such as
* Ext.form.field.Base or Ext.form.FieldContainer.
*
* Use of this mixin does not make a component a field in the logical sense, meaning it does not provide any
* logic or state related to values or validation; that is handled by the related Ext.form.field.Field
* mixin. These two mixins may be used separately (for example Ext.form.FieldContainer is Labelable but not a
* Field), or in combination (for example Ext.form.field.Base implements both and has logic for connecting the
* two.)
*
* Component classes which use this mixin should use the Field layout
* or a derivation thereof to properly size and position the label and message according to the component config.
* They must also call the {@link #initLabelable} method during component initialization to ensure the mixin gets
* set up correctly.
*
* @docauthor Jason Johnston <jason@sencha.com>
*/
Ext.define("Ext.form.Labelable", {
requires: ['Ext.XTemplate'],
autoEl: {
tag: 'table',
cellpadding: 0
},
childEls: [
<span id='Ext-form-Labelable-property-labelCell'> /**
</span> * @property {Ext.Element} labelCell
* The `<TD>` Element which contains the label Element for this component. Only available after the component has been rendered.
*/
'labelCell',
<span id='Ext-form-Labelable-property-labelEl'> /**
</span> * @property {Ext.Element} labelEl
* The label Element for this component. Only available after the component has been rendered.
*/
'labelEl',
<span id='Ext-form-Labelable-property-bodyEl'> /**
</span> * @property {Ext.Element} bodyEl
* The div Element wrapping the component's contents. Only available after the component has been rendered.
*/
'bodyEl',
// private - the TD which contains the msgTarget: 'side' error icon
'sideErrorCell',
<span id='Ext-form-Labelable-property-errorEl'> /**
</span> * @property {Ext.Element} errorEl
* The div Element that will contain the component's error message(s). Note that depending on the configured
* {@link #msgTarget}, this element may be hidden in favor of some other form of presentation, but will always
* be present in the DOM for use by assistive technologies.
*/
'errorEl',
'inputRow',
'bottomPlaceHolder'
],
<span id='Ext-form-Labelable-cfg-labelableRenderTpl'> /**
</span> * @cfg {String/String[]/Ext.XTemplate} labelableRenderTpl
* The rendering template for the field decorations. Component classes using this mixin
* should include logic to use this as their {@link Ext.AbstractComponent#renderTpl renderTpl},
* and implement the {@link #getSubTplMarkup} method to generate the field body content.
*
* The structure of a field is a table as follows:
*
* If `labelAlign: 'left', `msgTarget: 'side'`
*
* +----------------------+----------------------+-------------+
* | Label: | InputField | sideErrorEl |
* +----------------------+----------------------+-------------+
*
* If `labelAlign: 'left', `msgTarget: 'under'`
*
* +----------------------+------------------------------------+
* | Label: | InputField (colspan=2) |
* | | underErrorEl |
* +----------------------+------------------------------------+
*
* If `labelAlign: 'top', `msgTarget: 'side'`
*
* +---------------------------------------------+-------------+
* | label | |
* | InputField | sideErrorEl |
* +---------------------------------------------+-------------+
*
* If `labelAlign: 'top', `msgTarget: 'under'`
*
* +-----------------------------------------------------------+
* | label |
* | InputField (colspan=2) |
* | underErrorEl |
* +-----------------------------------------------------------+
*
* The total columns always the same for fields with each setting of {@link #labelAlign} because when
* rendered into a {@link Ext.layout.container.Form} layout, just the `TR` of the table
* will be placed into the form's main `TABLE`, and the columns of all the siblings
* must match so that they all line up. In a {@link Ext.layout.container.Form} layout, different
* settings of {@link #labelAlign} are not supported because of the incompatible column structure.
*
* When the triggerCell or side error cell are hidden or shown, the input cell's colspan
* is recalculated to maintain the correct 3 visible column count.
* @private
*/
labelableRenderTpl: [
// body row. If a heighted Field (eg TextArea, HtmlEditor, this must greedily consume height.
'<tr id="{id}-inputRow" <tpl if="inFormLayout">id="{id}"</tpl>>',
// Label cell
'<tpl if="labelOnLeft">',
'<td id="{id}-labelCell" style="{labelCellStyle}" {labelCellAttrs}>',
'{beforeLabelTpl}',
'<label id="{id}-labelEl" {labelAttrTpl}<tpl if="inputId"> for="{inputId}"</tpl> class="{labelCls}"',
'<tpl if="labelStyle"> style="{labelStyle}"</tpl>>',
'{beforeLabelTextTpl}',
'<tpl if="fieldLabel">{fieldLabel}{labelSeparator}</tpl>',
'{afterLabelTextTpl}',
'</label>',
'{afterLabelTpl}',
'</td>',
'</tpl>',
// Body of the input. That will be an input element, or, from a TriggerField, a table containing an input cell and trigger cell(s)
'<td class="{baseBodyCls} {fieldBodyCls}" id="{id}-bodyEl" colspan="{bodyColspan}" role="presentation">',
'{beforeBodyEl}',
// Label just sits on top of the input field if labelAlign === 'top'
'<tpl if="labelAlign==\'top\'">',
'{beforeLabelTpl}',
'<div id="{id}-labelCell" style="{labelCellStyle}">',
'<label id="{id}-labelEl" {labelAttrTpl}<tpl if="inputId"> for="{inputId}"</tpl> class="{labelCls}"',
'<tpl if="labelStyle"> style="{labelStyle}"</tpl>>',
'{beforeLabelTextTpl}',
'<tpl if="fieldLabel">{fieldLabel}{labelSeparator}</tpl>',
'{afterLabelTextTpl}',
'</label>',
'</div>',
'{afterLabelTpl}',
'</tpl>',
'{beforeSubTpl}',
'{[values.$comp.getSubTplMarkup()]}',
'{afterSubTpl}',
// Final TD. It's a side error element unless there's a floating external one
'<tpl if="msgTarget===\'side\'">',
'{afterBodyEl}',
'</td>',
'<td id="{id}-sideErrorCell" vAlign="{[values.labelAlign===\'top\' && !values.hideLabel ? \'bottom\' : \'middle\']}" style="{[values.autoFitErrors ? \'display:none\' : \'\']}" width="{errorIconWidth}">',
'<div id="{id}-errorEl" class="{errorMsgCls}" style="display:none;width:{errorIconWidth}px"></div>',
'</td>',
'<tpl elseif="msgTarget==\'under\'">',
'<div id="{id}-errorEl" class="{errorMsgClass}" colspan="2" style="display:none"></div>',
'{afterBodyEl}',
'</td>',
'</tpl>',
'</tr>',
{
disableFormats: true
}
],
<span id='Ext-form-Labelable-cfg-activeErrorsTpl'> /**
</span> * @cfg {String/String[]/Ext.XTemplate} activeErrorsTpl
* The template used to format the Array of error messages passed to {@link #setActiveErrors} into a single HTML
* string. By default this renders each message as an item in an unordered list.
*/
activeErrorsTpl: [
'<tpl if="errors && errors.length">',
'<ul><tpl for="errors"><li>{.}</li></tpl></ul>',
'</tpl>'
],
<span id='Ext-form-Labelable-property-isFieldLabelable'> /**
</span> * @property {Boolean} isFieldLabelable
* Flag denoting that this object is labelable as a field. Always true.
*/
isFieldLabelable: true,
<span id='Ext-form-Labelable-cfg-formItemCls'> /**
</span> * @cfg {String} formItemCls
* A CSS class to be applied to the outermost element to denote that it is participating in the form field layout.
*/
formItemCls: Ext.baseCSSPrefix + 'form-item',
<span id='Ext-form-Labelable-cfg-labelCls'> /**
</span> * @cfg {String} labelCls
* The CSS class to be applied to the label element. This (single) CSS class is used to formulate the renderSelector
* and drives the field layout where it is concatenated with a hyphen ('-') and {@link #labelAlign}. To add
* additional classes, use {@link #labelClsExtra}.
*/
labelCls: Ext.baseCSSPrefix + 'form-item-label',
<span id='Ext-form-Labelable-cfg-labelClsExtra'> /**
</span> * @cfg {String} labelClsExtra
* An optional string of one or more additional CSS classes to add to the label element. Defaults to empty.
*/
<span id='Ext-form-Labelable-cfg-errorMsgCls'> /**
</span> * @cfg {String} errorMsgCls
* The CSS class to be applied to the error message element.
*/
errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg',
<span id='Ext-form-Labelable-cfg-baseBodyCls'> /**
</span> * @cfg {String} baseBodyCls
* The CSS class to be applied to the body content element.
*/
baseBodyCls: Ext.baseCSSPrefix + 'form-item-body',
<span id='Ext-form-Labelable-cfg-fieldBodyCls'> /**
</span> * @cfg {String} fieldBodyCls
* An extra CSS class to be applied to the body content element in addition to {@link #baseBodyCls}.
*/
fieldBodyCls: '',
<span id='Ext-form-Labelable-cfg-clearCls'> /**
</span> * @cfg {String} clearCls
* The CSS class to be applied to the special clearing div rendered directly after the field contents wrapper to
* provide field clearing.
*/
clearCls: Ext.baseCSSPrefix + 'clear',
<span id='Ext-form-Labelable-cfg-invalidCls'> /**
</span> * @cfg {String} invalidCls
* The CSS class to use when marking the component invalid.
*/
invalidCls : Ext.baseCSSPrefix + 'form-invalid',
<span id='Ext-form-Labelable-cfg-fieldLabel'> /**
</span> * @cfg {String} fieldLabel
* The label for the field. It gets appended with the {@link #labelSeparator}, and its position and sizing is
* determined by the {@link #labelAlign}, {@link #labelWidth}, and {@link #labelPad} configs.
*/
fieldLabel: undefined,
<span id='Ext-form-Labelable-cfg-labelAlign'> /**
</span> * @cfg {String} labelAlign
* Controls the position and alignment of the {@link #fieldLabel}. Valid values are:
*
* - "left" (the default) - The label is positioned to the left of the field, with its text aligned to the left.
* Its width is determined by the {@link #labelWidth} config.
* - "top" - The label is positioned above the field.
* - "right" - The label is positioned to the left of the field, with its text aligned to the right.
* Its width is determined by the {@link #labelWidth} config.
*/
labelAlign : 'left',
<span id='Ext-form-Labelable-cfg-labelWidth'> /**
</span> * @cfg {Number} labelWidth
* The width of the {@link #fieldLabel} in pixels. Only applicable if the {@link #labelAlign} is set to "left" or
* "right".
*/
labelWidth: 100,
<span id='Ext-form-Labelable-cfg-labelPad'> /**
</span> * @cfg {Number} labelPad
* The amount of space in pixels between the {@link #fieldLabel} and the input field.
*/
labelPad : 5,
//<locale>
<span id='Ext-form-Labelable-cfg-labelSeparator'> /**
</span> * @cfg {String} labelSeparator
* Character(s) to be inserted at the end of the {@link #fieldLabel label text}.
*
* Set to empty string to hide the separator completely.
*/
labelSeparator : ':',
//</locale>
<span id='Ext-form-Labelable-cfg-labelStyle'> /**
</span> * @cfg {String} labelStyle
* A CSS style specification string to apply directly to this field's label.
*/
<span id='Ext-form-Labelable-cfg-hideLabel'> /**
</span> * @cfg {Boolean} hideLabel
* Set to true to completely hide the label element ({@link #fieldLabel} and {@link #labelSeparator}). Also see
* {@link #hideEmptyLabel}, which controls whether space will be reserved for an empty fieldLabel.
*/
hideLabel: false,
<span id='Ext-form-Labelable-cfg-hideEmptyLabel'> /**
</span> * @cfg {Boolean} hideEmptyLabel
* When set to true, the label element ({@link #fieldLabel} and {@link #labelSeparator}) will be automatically
* hidden if the {@link #fieldLabel} is empty. Setting this to false will cause the empty label element to be
* rendered and space to be reserved for it; this is useful if you want a field without a label to line up with
* other labeled fields in the same form.
*
* If you wish to unconditionall hide the label even if a non-empty fieldLabel is configured, then set the
* {@link #hideLabel} config to true.
*/
hideEmptyLabel: true,
<span id='Ext-form-Labelable-cfg-preventMark'> /**
</span> * @cfg {Boolean} preventMark
* true to disable displaying any {@link #setActiveError error message} set on this object.
*/
preventMark: false,
<span id='Ext-form-Labelable-cfg-autoFitErrors'> /**
</span> * @cfg {Boolean} autoFitErrors
* Whether to adjust the component's body area to make room for 'side' or 'under' {@link #msgTarget error messages}.
*/
autoFitErrors: true,
<span id='Ext-form-Labelable-cfg-msgTarget'> /**
</span> * @cfg {String} msgTarget
* The location where the error message text should display. Must be one of the following values:
*
* - `qtip` Display a quick tip containing the message when the user hovers over the field.
* This is the default.
*
* **{@link Ext.tip.QuickTipManager#init} must have been called for this setting to work.**
*
* - `title` Display the message in a default browser title attribute popup.
* - `under` Add a block div beneath the field containing the error message.
* - `side` Add an error icon to the right of the field, displaying the message in a popup on hover.
* - `none` Don't display any error message. This might be useful if you are implementing custom error display.
* - `[element id]` Add the error message directly to the innerHTML of the specified element.
*/
msgTarget: 'qtip',
<span id='Ext-form-Labelable-cfg-activeError'> /**
</span> * @cfg {String} activeError
* If specified, then the component will be displayed with this value as its active error when first rendered. Use
* {@link #setActiveError} or {@link #unsetActiveError} to change it after component creation.
*/
<span id='Ext-form-Labelable-property-noWrap'> /**
</span> * @private
* Tells the layout system that the height can be measured immediately because the width does not need setting.
*/
noWrap: true,
labelableInsertions: [
<span id='Ext-form-Labelable-cfg-beforeBodyEl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} beforeBodyEl
* An optional string or `XTemplate` configuration to insert in the field markup
* at the beginning of the input containing element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
* serves as the context.
*/
'beforeBodyEl',
<span id='Ext-form-Labelable-cfg-afterBodyEl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} afterBodyEl
* An optional string or `XTemplate` configuration to insert in the field markup
* at the end of the input containing element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
* serves as the context.
*/
'afterBodyEl',
<span id='Ext-form-Labelable-cfg-beforeLabelTpl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} beforeLabelTpl
* An optional string or `XTemplate` configuration to insert in the field markup
* before the label element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
* serves as the context.
*/
'beforeLabelTpl',
<span id='Ext-form-Labelable-cfg-afterLabelTpl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} afterLabelTpl
* An optional string or `XTemplate` configuration to insert in the field markup
* after the label element. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
* serves as the context.
*/
'afterLabelTpl',
<span id='Ext-form-Labelable-cfg-beforeSubTpl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} beforeSubTpl
* An optional string or `XTemplate` configuration to insert in the field markup
* before the {@link #getSubTplMarkup subTpl markup}. If an `XTemplate` is used, the
* component's {@link Ext.AbstractComponent#renderData render data} serves as the context.
*/
'beforeSubTpl',
<span id='Ext-form-Labelable-cfg-afterSubTpl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} afterSubTpl
* An optional string or `XTemplate` configuration to insert in the field markup
* after the {@link #getSubTplMarkup subTpl markup}. If an `XTemplate` is used, the
* component's {@link Ext.AbstractComponent#renderData render data} serves as the context.
*/
'afterSubTpl',
<span id='Ext-form-Labelable-cfg-beforeLabelTextTpl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} beforeLabelTextTpl
* An optional string or `XTemplate` configuration to insert in the field markup
* before the label text. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
* serves as the context.
*/
'beforeLabelTextTpl',
<span id='Ext-form-Labelable-cfg-afterLabelTextTpl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} afterLabelTextTpl
* An optional string or `XTemplate` configuration to insert in the field markup
* after the label text. If an `XTemplate` is used, the component's {@link Ext.AbstractComponent#renderData render data}
* serves as the context.
*/
'afterLabelTextTpl',
<span id='Ext-form-Labelable-cfg-labelAttrTpl'> /**
</span> * @cfg {String/Array/Ext.XTemplate} labelAttrTpl
* An optional string or `XTemplate` configuration to insert in the field markup
* inside the label element (as attributes). If an `XTemplate` is used, the component's
* {@link Ext.AbstractComponent#renderData render data} serves as the context.
*/
'labelAttrTpl'
],
// This is an array to avoid a split on every call to Ext.copyTo
labelableRenderProps: [ 'allowBlank', 'id', 'labelAlign', 'fieldBodyCls', 'baseBodyCls',
'clearCls', 'labelSeparator', 'msgTarget' ],
<span id='Ext-form-Labelable-method-initLabelable'> /**
</span> * Performs initialization of this mixin. Component classes using this mixin should call this method during their
* own initialization.
*/
initLabelable: function() {
var me = this,
padding = me.padding;
// This Component is rendered as a table. Padding doesn't work on tables
// Before padding can be applied to the encapsulating table element, copy the padding into
// an extraMargins property which is to be added to all computed margins post render :(
if (padding) {
me.padding = undefined;
me.extraMargins = Ext.Element.parseBox(padding);
}
me.addCls(me.formItemCls);
// Prevent first render of active error, at Field render time from signalling a change from undefined to "
me.lastActiveError = '';
me.addEvents(
<span id='Ext-form-Labelable-event-errorchange'> /**
</span> * @event errorchange
* Fires when the active error message is changed via {@link #setActiveError}.
* @param {Ext.form.Labelable} this
* @param {String} error The active error message
*/
'errorchange'
);
},
<span id='Ext-form-Labelable-method-trimLabelSeparator'> /**
</span> * Returns the trimmed label by slicing off the label separator character. Can be overridden.
* @return {String} The trimmed field label, or empty string if not defined
*/
trimLabelSeparator: function() {
var me = this,
separator = me.labelSeparator,
label = me.fieldLabel || '',
lastChar = label.substr(label.length - 1);
// if the last char is the same as the label separator then slice it off otherwise just return label value
return lastChar === separator ? label.slice(0, -1) : label;
},
<span id='Ext-form-Labelable-method-getFieldLabel'> /**
</span> * Returns the label for the field. Defaults to simply returning the {@link #fieldLabel} config. Can be overridden
* to provide a custom generated label.
* @template
* @return {String} The configured field label, or empty string if not defined
*/
getFieldLabel: function() {
return this.trimLabelSeparator();
},
<span id='Ext-form-Labelable-method-setFieldLabel'> /**
</span> * Set the label of this field.
* @param {String} label The new label. The {@link #labelSeparator} will be automatically appended to the label
* string.
*/
setFieldLabel: function(label){
label = label || '';
var me = this,
separator = me.labelSeparator,
labelEl = me.labelEl;
me.fieldLabel = label;
if (me.rendered) {
if (Ext.isEmpty(label) && me.hideEmptyLabel) {
labelEl.parent().setDisplayed('none');
} else {
if (separator) {
label = me.trimLabelSeparator() + separator;
}
labelEl.update(label);
labelEl.parent().setDisplayed('');
}
me.updateLayout();
}
},
getInsertionRenderData: function (data, names) {
var i = names.length,
name, value;
while (i--) {
name = names[i];
value = this[name];
if (value) {
if (typeof value != 'string') {
if (!value.isTemplate) {
value = Ext.XTemplate.getTpl(this, name);
}
value = value.apply(data);
}
}
data[name] = value || '';
}
return data;
},
<span id='Ext-form-Labelable-method-getLabelableRenderData'> /**
</span> * Generates the arguments for the field decorations {@link #labelableRenderTpl rendering template}.
* @return {Object} The template arguments
* @protected
*/
getLabelableRenderData: function() {
var me = this,
data,
tempEl,
topLabel = me.labelAlign === 'top';
if (!Ext.form.Labelable.errorIconWidth) {
Ext.form.Labelable.errorIconWidth = (tempEl = Ext.resetElement.createChild({style: 'position:absolute', cls: Ext.baseCSSPrefix + 'form-invalid-icon'})).getWidth();
tempEl.remove();
}
data = Ext.copyTo({
inFormLayout : me.ownerLayout && me.ownerLayout.type === 'form',
inputId : me.getInputId(),
labelOnLeft : !topLabel,
hideLabel : !me.hasVisibleLabel(),
fieldLabel : me.getFieldLabel(),
labelCellStyle : me.getLabelCellStyle(),
labelCellAttrs : me.getLabelCellAttrs(),
labelCls : me.getLabelCls(),
labelStyle : me.getLabelStyle(),
bodyColspan : me.getBodyColspan(),
externalError : !me.autoFitErrors,
errorMsgCls : me.getErrorMsgCls(),
errorIconWidth : Ext.form.Labelable.errorIconWidth
},
me, me.labelableRenderProps, true);
me.getInsertionRenderData(data, me.labelableInsertions);
return data;
},
beforeLabelableRender: function() {
var me = this;
if (me.ownerLayout) {
me.addCls(Ext.baseCSSPrefix + me.ownerLayout.type + '-form-item');
}
},
onLabelableRender: function() {
var me = this,
margins,
side,
style = {};
if (me.extraMargins) {
margins = me.el.getMargin();
for (side in margins) {
if (margins.hasOwnProperty(side)) {
style['margin-' + side] = (margins[side] + me.extraMargins[side]) + 'px';
}
}
me.el.setStyle(style);
}
},
<span id='Ext-form-Labelable-method-hasVisibleLabel'> /**
</span> * Checks if the field has a visible label
* @return {Boolean} True if the field has a visible label
*/
hasVisibleLabel: function(){
if (this.hideLabel) {
return false;
}
return !(this.hideEmptyLabel && !this.getFieldLabel());
},
<span id='Ext-form-Labelable-method-getBodyColspan'> /**
</span> * @private
* Calculates the colspan value for the body cell - the cell which contains the input field.
*
* The field table structure contains 4 columns:
*/
getBodyColspan: function() {
var me = this,
result;
if (me.msgTarget === 'side' && (!me.autoFitErrors || me.hasActiveError())) {
result = 1;
} else {
result = 2;
}
if (me.labelAlign !== 'top' && !me.hasVisibleLabel()) {
result++;
}
return result;
},
getLabelCls: function() {
var labelCls = this.labelCls,
labelClsExtra = this.labelClsExtra;
if (this.labelAlign === 'top') {
labelCls += '-top';
}
return labelClsExtra ? labelCls + ' ' + labelClsExtra : labelCls;
},
getLabelCellStyle: function() {
var me = this,
hideLabelCell = me.hideLabel || (!me.fieldLabel && me.hideEmptyLabel);
return hideLabelCell ? 'display:none;' : '';
},
getErrorMsgCls: function() {
var me = this,
hideLabelCell = (me.hideLabel || (!me.fieldLabel && me.hideEmptyLabel));
return me.errorMsgCls + (!hideLabelCell && me.labelAlign === 'top' ? ' ' + Ext.baseCSSPrefix + 'lbl-top-err-icon' : '');
},
getLabelCellAttrs: function() {
var me = this,
labelAlign = me.labelAlign,
result = '';
if (labelAlign !== 'top') {
result = 'valign="top" halign="' + labelAlign + '" width="' + (me.labelWidth + me.labelPad) + '"';
}
return result + ' class="' + Ext.baseCSSPrefix + 'field-label-cell"';
},
<span id='Ext-form-Labelable-method-getLabelStyle'> /**
</span> * Gets any label styling for the labelEl
* @private
* @return {String} The label styling
*/
getLabelStyle: function(){
var me = this,
labelPad = me.labelPad,
labelStyle = '';
// Calculate label styles up front rather than in the Field layout for speed; this
// is safe because label alignment/width/pad are not expected to change.
if (me.labelAlign !== 'top') {
if (me.labelWidth) {
labelStyle = 'width:' + me.labelWidth + 'px;';
}
labelStyle += 'margin-right:' + labelPad + 'px;';
}
return labelStyle + (me.labelStyle || '');
},
<span id='Ext-form-Labelable-method-getSubTplMarkup'> /**
</span> * Gets the markup to be inserted into the outer template's bodyEl. Defaults to empty string, should be implemented
* by classes including this mixin as needed.
* @return {String} The markup to be inserted
* @protected
*/
getSubTplMarkup: function() {
return '';
},
<span id='Ext-form-Labelable-method-getInputId'> /**
</span> * Get the input id, if any, for this component. This is used as the "for" attribute on the label element.
* Implementing subclasses may also use this as e.g. the id for their own input element.
* @return {String} The input id
*/
getInputId: function() {
return '';
},
<span id='Ext-form-Labelable-method-getActiveError'> /**
</span> * Gets the active error message for this component, if any. This does not trigger validation on its own, it merely
* returns any message that the component may already hold.
* @return {String} The active error message on the component; if there is no error, an empty string is returned.
*/
getActiveError : function() {
return this.activeError || '';
},
<span id='Ext-form-Labelable-method-hasActiveError'> /**
</span> * Tells whether the field currently has an active error message. This does not trigger validation on its own, it
* merely looks for any message that the component may already hold.
* @return {Boolean}
*/
hasActiveError: function() {
return !!this.getActiveError();
},
<span id='Ext-form-Labelable-method-setActiveError'> /**
</span> * Sets the active error message to the given string. This replaces the entire error message contents with the given
* string. Also see {@link #setActiveErrors} which accepts an Array of messages and formats them according to the
* {@link #activeErrorsTpl}. Note that this only updates the error message element's text and attributes, you'll
* have to call doComponentLayout to actually update the field's layout to match. If the field extends {@link
* Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
* @param {String} msg The error message
*/
setActiveError: function(msg) {
this.setActiveErrors(msg);
},
<span id='Ext-form-Labelable-method-getActiveErrors'> /**
</span> * Gets an Array of any active error messages currently applied to the field. This does not trigger validation on
* its own, it merely returns any messages that the component may already hold.
* @return {String[]} The active error messages on the component; if there are no errors, an empty Array is
* returned.
*/
getActiveErrors: function() {
return this.activeErrors || [];
},
<span id='Ext-form-Labelable-method-setActiveErrors'> /**
</span> * Set the active error message to an Array of error messages. The messages are formatted into a single message
* string using the {@link #activeErrorsTpl}. Also see {@link #setActiveError} which allows setting the entire error
* contents with a single string. Note that this only updates the error message element's text and attributes,
* you'll have to call doComponentLayout to actually update the field's layout to match. If the field extends
* {@link Ext.form.field.Base} you should call {@link Ext.form.field.Base#markInvalid markInvalid} instead.
* @param {String[]} errors The error messages
*/
setActiveErrors: function(errors) {
errors = Ext.Array.from(errors);
this.activeError = errors[0];
this.activeErrors = errors;
this.activeError = this.getTpl('activeErrorsTpl').apply({errors: errors});
this.renderActiveError();
},
<span id='Ext-form-Labelable-method-unsetActiveError'> /**
</span> * Clears the active error message(s). Note that this only clears the error message element's text and attributes,
* you'll have to call doComponentLayout to actually update the field's layout to match. If the field extends {@link
* Ext.form.field.Base} you should call {@link Ext.form.field.Base#clearInvalid clearInvalid} instead.
*/
unsetActiveError: function() {
delete this.activeError;
delete this.activeErrors;
this.renderActiveError();
},
<span id='Ext-form-Labelable-method-renderActiveError'> /**
</span> * @private
* Updates the rendered DOM to match the current activeError. This only updates the content and
* attributes, you'll have to call doComponentLayout to actually update the display.
*/
renderActiveError: function() {
var me = this,
activeError = me.getActiveError(),
hasError = !!activeError;
if (activeError !== me.lastActiveError) {
me.fireEvent('errorchange', me, activeError);
me.lastActiveError = activeError;
}
if (me.rendered && !me.isDestroyed && !me.preventMark) {
// Add/remove invalid class
me.el[hasError ? 'addCls' : 'removeCls'](me.invalidCls);
// Update the aria-invalid attribute
me.getActionEl().dom.setAttribute('aria-invalid', hasError);
// Update the errorEl (There will only be one if msgTarget is 'side' or 'under') with the error message text
if (me.errorEl) {
me.errorEl.dom.innerHTML = activeError;
}
}
},
<span id='Ext-form-Labelable-method-setFieldDefaults'> /**
</span> * Applies a set of default configuration values to this Labelable instance. For each of the properties in the given
* object, check if this component hasOwnProperty that config; if not then it's inheriting a default value from its
* prototype and we should apply the default value.
* @param {Object} defaults The defaults to apply to the object.
*/
setFieldDefaults: function(defaults) {
var me = this,
val, key;
for (key in defaults) {
if (defaults.hasOwnProperty(key)) {
val = defaults[key];
if (!me.hasOwnProperty(key)) {
me[key] = val;
}
}
}
}
});
</pre>
</body>
</html>