<!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-FieldContainer'>/**
|
</span> * FieldContainer is a derivation of {@link Ext.container.Container Container} that implements the
|
* {@link Ext.form.Labelable Labelable} mixin. This allows it to be configured so that it is rendered with
|
* a {@link #fieldLabel field label} and optional {@link #msgTarget error message} around its sub-items.
|
* This is useful for arranging a group of fields or other components within a single item in a form, so
|
* that it lines up nicely with other fields. A common use is for grouping a set of related fields under
|
* a single label in a form.
|
*
|
* The container's configured {@link #cfg-items} will be layed out within the field body area according to the
|
* configured {@link #layout} type. The default layout is `'autocontainer'`.
|
*
|
* Like regular fields, FieldContainer can inherit its decoration configuration from the
|
* {@link Ext.form.Panel#fieldDefaults fieldDefaults} of an enclosing FormPanel. In addition,
|
* FieldContainer itself can pass {@link #fieldDefaults} to any {@link Ext.form.Labelable fields}
|
* it may itself contain.
|
*
|
* If you are grouping a set of {@link Ext.form.field.Checkbox Checkbox} or {@link Ext.form.field.Radio Radio}
|
* fields in a single labeled container, consider using a {@link Ext.form.CheckboxGroup}
|
* or {@link Ext.form.RadioGroup} instead as they are specialized for handling those types.
|
*
|
* # Example
|
*
|
* @example
|
* Ext.create('Ext.form.Panel', {
|
* title: 'FieldContainer Example',
|
* width: 550,
|
* bodyPadding: 10,
|
*
|
* items: [{
|
* xtype: 'fieldcontainer',
|
* fieldLabel: 'Last Three Jobs',
|
* labelWidth: 100,
|
*
|
* // The body area will contain three text fields, arranged
|
* // horizontally, separated by draggable splitters.
|
* layout: 'hbox',
|
* items: [{
|
* xtype: 'textfield',
|
* flex: 1
|
* }, {
|
* xtype: 'splitter'
|
* }, {
|
* xtype: 'textfield',
|
* flex: 1
|
* }, {
|
* xtype: 'splitter'
|
* }, {
|
* xtype: 'textfield',
|
* flex: 1
|
* }]
|
* }],
|
* renderTo: Ext.getBody()
|
* });
|
*
|
* # Usage of fieldDefaults
|
*
|
* @example
|
* Ext.create('Ext.form.Panel', {
|
* title: 'FieldContainer Example',
|
* width: 350,
|
* bodyPadding: 10,
|
*
|
* items: [{
|
* xtype: 'fieldcontainer',
|
* fieldLabel: 'Your Name',
|
* labelWidth: 75,
|
* defaultType: 'textfield',
|
*
|
* // Arrange fields vertically, stretched to full width
|
* layout: 'anchor',
|
* defaults: {
|
* layout: '100%'
|
* },
|
*
|
* // These config values will be applied to both sub-fields, except
|
* // for Last Name which will use its own msgTarget.
|
* fieldDefaults: {
|
* msgTarget: 'under',
|
* labelAlign: 'top'
|
* },
|
*
|
* items: [{
|
* fieldLabel: 'First Name',
|
* name: 'firstName'
|
* }, {
|
* fieldLabel: 'Last Name',
|
* name: 'lastName',
|
* msgTarget: 'under'
|
* }]
|
* }],
|
* renderTo: Ext.getBody()
|
* });
|
*
|
* @docauthor Jason Johnston <jason@sencha.com>
|
*/
|
Ext.define('Ext.form.FieldContainer', {
|
extend: 'Ext.container.Container',
|
mixins: {
|
labelable: 'Ext.form.Labelable',
|
fieldAncestor: 'Ext.form.FieldAncestor'
|
},
|
requires: 'Ext.layout.component.field.FieldContainer',
|
|
alias: 'widget.fieldcontainer',
|
|
<span id='Ext-form-FieldContainer-cfg-componentLayout'> componentLayout: 'fieldcontainer',
|
</span>
|
<span id='Ext-form-FieldContainer-cfg-componentCls'> componentCls: Ext.baseCSSPrefix + 'form-fieldcontainer',
|
</span>
|
<span id='Ext-form-FieldContainer-property-customOverflowEl'> // Used by the layout system, typically the scrolling el is the targetEl, however we need
|
</span> // to let it know we're using something different
|
customOverflowEl: 'containerEl',
|
|
<span id='Ext-form-FieldContainer-property-childEls'> childEls: [
|
</span> 'containerEl'
|
],
|
|
<span id='Ext-form-FieldContainer-cfg-autoScroll'> /**
|
</span> * @cfg autoScroll @hide
|
*/
|
|
<span id='Ext-form-FieldContainer-cfg-combineLabels'> /**
|
</span> * @cfg {Boolean} combineLabels
|
* If set to true, and there is no defined {@link #fieldLabel}, the field container will automatically
|
* generate its label by combining the labels of all the fields it contains. Defaults to false.
|
*/
|
combineLabels: false,
|
|
//<locale>
|
<span id='Ext-form-FieldContainer-cfg-labelConnector'> /**
|
</span> * @cfg {String} labelConnector
|
* The string to use when joining the labels of individual sub-fields, when {@link #combineLabels} is
|
* set to true. Defaults to ', '.
|
*/
|
labelConnector: ', ',
|
//</locale>
|
|
<span id='Ext-form-FieldContainer-cfg-combineErrors'> /**
|
</span> * @cfg {Boolean} combineErrors
|
* If set to true, the field container will automatically combine and display the validation errors from
|
* all the fields it contains as a single error on the container, according to the configured
|
* {@link #msgTarget}. Defaults to false.
|
*/
|
combineErrors: false,
|
|
<span id='Ext-form-FieldContainer-property-maskOnDisable'> maskOnDisable: false,
|
</span><span id='Ext-form-FieldContainer-cfg-invalidCls'> // If we allow this to mark with the invalidCls it will cascade to all
|
</span> // child fields, let them handle themselves
|
invalidCls: '',
|
|
<span id='Ext-form-FieldContainer-property-fieldSubTpl'> fieldSubTpl: '<div id="{id}-containerEl" class="{containerElCls}">{%this.renderContainer(out,values)%}</div>',
|
</span>
|
<span id='Ext-form-FieldContainer-method-initComponent'> initComponent: function() {
|
</span> var me = this;
|
|
// Init mixins
|
me.initLabelable();
|
me.initFieldAncestor();
|
|
me.callParent();
|
me.initMonitor();
|
},
|
|
<span id='Ext-form-FieldContainer-method-getOverflowEl'> getOverflowEl: function(){
|
</span> return this.containerEl;
|
},
|
|
<span id='Ext-form-FieldContainer-method-onAdd'> /**
|
</span> * @protected Called when a {@link Ext.form.Labelable} instance is added to the container's subtree.
|
* @param {Ext.form.Labelable} labelable The instance that was added
|
*/
|
onAdd: function(labelable) {
|
var me = this;
|
|
// Fix for https://sencha.jira.com/browse/EXTJSIV-6424
|
// In FF, positioning absolutely within a TD positions relative to the TR!
|
// So we must add the width of a visible, left-aligned label cell to the x coordinate.
|
if (Ext.isGecko && me.layout.type === 'absolute' && !me.hideLabel && me.labelAlign !== 'top') {
|
labelable.x += (me.labelWidth + me.labelPad);
|
}
|
me.callParent(arguments);
|
if (me.combineLabels) {
|
labelable.oldHideLabel = labelable.hideLabel;
|
labelable.hideLabel = true;
|
}
|
me.updateLabel();
|
},
|
|
<span id='Ext-form-FieldContainer-method-onRemove'> /**
|
</span> * @protected Called when a {@link Ext.form.Labelable} instance is removed from the container's subtree.
|
* @param {Ext.form.Labelable} labelable The instance that was removed
|
*/
|
onRemove: function(labelable, isDestroying) {
|
var me = this;
|
me.callParent(arguments);
|
if (!isDestroying) {
|
if (me.combineLabels) {
|
labelable.hideLabel = labelable.oldHideLabel;
|
}
|
me.updateLabel();
|
}
|
},
|
|
<span id='Ext-form-FieldContainer-method-initRenderTpl'> initRenderTpl: function() {
|
</span> var me = this;
|
if (!me.hasOwnProperty('renderTpl')) {
|
me.renderTpl = me.getTpl('labelableRenderTpl');
|
}
|
return me.callParent();
|
},
|
|
<span id='Ext-form-FieldContainer-method-initRenderData'> initRenderData: function() {
|
</span> var me = this,
|
data = me.callParent();
|
|
data.containerElCls = me.containerElCls;
|
return Ext.applyIf(data, me.getLabelableRenderData());
|
},
|
|
<span id='Ext-form-FieldContainer-method-getFieldLabel'> /**
|
</span> * Returns the combined field label if {@link #combineLabels} is set to true and if there is no
|
* set {@link #fieldLabel}. Otherwise returns the fieldLabel like normal. You can also override
|
* this method to provide a custom generated label.
|
* @template
|
* @return {String} The label, or empty string if none.
|
*/
|
getFieldLabel: function() {
|
var label = this.fieldLabel || '';
|
if (!label && this.combineLabels) {
|
label = Ext.Array.map(this.query('[isFieldLabelable]'), function(field) {
|
return field.getFieldLabel();
|
}).join(this.labelConnector);
|
}
|
return label;
|
},
|
|
<span id='Ext-form-FieldContainer-method-getSubTplData'> getSubTplData: function() {
|
</span> var ret = this.initRenderData();
|
|
Ext.apply(ret, this.subTplData);
|
return ret;
|
},
|
|
<span id='Ext-form-FieldContainer-method-getSubTplMarkup'> getSubTplMarkup: function() {
|
</span> var me = this,
|
tpl = me.getTpl('fieldSubTpl'),
|
html;
|
|
if (!tpl.renderContent) {
|
me.setupRenderTpl(tpl);
|
}
|
|
html = tpl.apply(me.getSubTplData());
|
return html;
|
},
|
|
<span id='Ext-form-FieldContainer-method-updateLabel'> /**
|
</span> * @private Updates the content of the labelEl if it is rendered
|
*/
|
updateLabel: function() {
|
var me = this,
|
label = me.labelEl;
|
|
if (label) {
|
me.setFieldLabel(me.getFieldLabel());
|
}
|
},
|
|
|
<span id='Ext-form-FieldContainer-method-onFieldErrorChange'> /**
|
</span> * @private Fired when the error message of any field within the container changes, and updates the
|
* combined error message to match.
|
*/
|
onFieldErrorChange: function(field, activeError) {
|
if (this.combineErrors) {
|
var me = this,
|
oldError = me.getActiveError(),
|
invalidFields = Ext.Array.filter(me.query('[isFormField]'), function(field) {
|
return field.hasActiveError();
|
}),
|
newErrors = me.getCombinedErrors(invalidFields);
|
|
if (newErrors) {
|
me.setActiveErrors(newErrors);
|
} else {
|
me.unsetActiveError();
|
}
|
|
if (oldError !== me.getActiveError()) {
|
me.doComponentLayout();
|
}
|
}
|
},
|
|
<span id='Ext-form-FieldContainer-method-getCombinedErrors'> /**
|
</span> * Takes an Array of invalid {@link Ext.form.field.Field} objects and builds a combined list of error
|
* messages from them. Defaults to prepending each message by the field name and a colon. This
|
* can be overridden to provide custom combined error message handling, for instance changing
|
* the format of each message or sorting the array (it is sorted in order of appearance by default).
|
* @param {Ext.form.field.Field[]} invalidFields An Array of the sub-fields which are currently invalid.
|
* @return {String[]} The combined list of error messages
|
*/
|
getCombinedErrors: function(invalidFields) {
|
var errors = [],
|
f,
|
fLen = invalidFields.length,
|
field,
|
activeErrors, a, aLen,
|
error, label;
|
|
for (f = 0; f < fLen; f++) {
|
field = invalidFields[f];
|
activeErrors = field.getActiveErrors();
|
aLen = activeErrors.length;
|
|
for (a = 0; a < aLen; a++) {
|
error = activeErrors[a];
|
label = field.getFieldLabel();
|
|
errors.push((label ? label + ': ' : '') + error);
|
}
|
}
|
|
return errors;
|
},
|
|
<span id='Ext-form-FieldContainer-method-getTargetEl'> getTargetEl: function() {
|
</span> return this.containerEl;
|
},
|
|
<span id='Ext-form-FieldContainer-method-applyTargetCls'> applyTargetCls: function(targetCls) {
|
</span> var containerElCls = this.containerElCls;
|
|
this.containerElCls = containerElCls ? containerElCls + ' ' + targetCls : targetCls;
|
}
|
});
|
</pre>
|
</body>
|
</html>
|