Lio*_*han 23 forms extjs required-field extjs4
我有这个问题,fieldLabel当一个字段标记为"必需"(或allowBlank: false)时,我需要在旁边添加一个红色星号
在ExtJS3中,我们可以通过覆盖轻松实现此攻击Ext.layout.FormLayout,如下所示:
Ext.override(Ext.layout.FormLayout, {
getTemplateArgs: function(field) {
var noLabelSep = !field.fieldLabel || field.hideLabel;
var labelSep = (typeof field.labelSeparator == 'undefined' ? this.labelSeparator : field.labelSeparator);
if (!field.allowBlank) labelSep += '<span style="color: rgb(255, 0, 0); padding-left: 2px;">*</span>';
return {
id: field.id,
label: field.fieldLabel,
labelStyle: field.labelStyle||this.labelStyle||'',
elementStyle: this.elementStyle||'',
labelSeparator: noLabelSep ? '' : labelSep,
itemCls: (field.itemCls||this.container.itemCls||'') + (field.hideLabel ? ' x-hide-label' : ''),
clearCls: field.clearCls || 'x-form-clear-left'
};
}
});
Run Code Online (Sandbox Code Playgroud)
但这在ExtJS4中是不可能的.FormLayout不再适用,标签实际上是Ext.form.field.Base通过使用调用的mixins来呈现的Ext.form.Labelable.
可悲的是,无论是扩展Ext.form.Labelable还是超越Ext.form.Labelable都不适用于我.扩展组件Ext.form.field.Base不会从中受到任何影响.即使我交换了mixins,模板仍然无效.
所以这里是我的解决方案,我做了一个非常严厉的覆盖Ext.form.field.Base,它的工作原理如下(查看我的例子)
这仅适用于ExtJS 4.0.7.要在ExtJS 4.0.2a上使用它,您需要labelableRenderTpl根据4.0.2a中的修改进行修改/src/form/Labelable.js
(function() {
var overrides = {
labelableRenderTpl: [
'<tpl if="!hideLabel && !(!fieldLabel && hideEmptyLabel)">',
'<label id="{id}-labelEl"<tpl if="inputId"> for="{inputId}"</tpl> class="{labelCls}"',
'<tpl if="labelStyle"> style="{labelStyle}"</tpl>>',
'<tpl if="fieldLabel">{fieldLabel}{labelSeparator}</tpl>',
'<tpl if="!allowBlank"><span style="color:red">*</span></tpl>',
'</label>',
'</tpl>',
'<div class="{baseBodyCls} {fieldBodyCls}" id="{id}-bodyEl" role="presentation">{subTplMarkup}</div>',
'<div id="{id}-errorEl" class="{errorMsgCls}" style="display:none"></div>',
'<div class="{clearCls}" role="presentation"><!-- --></div>',
{
compiled: true,
disableFormats: true
}
],
/**
* @protected
* Generates the arguments for the field decorations {@link #labelableRenderTpl rendering template}.
* @return {Object} The template arguments
*/
getLabelableRenderData: function() {
var me = this,
labelAlign = me.labelAlign,
labelCls = me.labelCls,
labelClsExtra = me.labelClsExtra,
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 (labelAlign === 'top') {
labelStyle = 'margin-bottom:' + labelPad + 'px;';
} else {
labelStyle = 'margin-right:' + labelPad + 'px;';
// Add the width for border-box browsers; will be set by the Field layout for content-box
if (Ext.isBorderBox) {
labelStyle += 'width:' + me.labelWidth + 'px;';
}
}
return Ext.copyTo(
{
inputId: me.getInputId(),
fieldLabel: me.getFieldLabel(),
labelCls: labelClsExtra ? labelCls + ' ' + labelClsExtra : labelCls,
labelStyle: labelStyle + (me.labelStyle || ''),
subTplMarkup: me.getSubTplMarkup(),
allowBlank: me.allowBlank
},
me,
'hideLabel,hideEmptyLabel,fieldBodyCls,baseBodyCls,errorMsgCls,clearCls,labelSeparator',
true
);
}
};
//Both field.Base and FieldContainer are affected, so need to cater for.
Ext.override(Ext.form.field.Base, overrides);
Ext.override(Ext.form.FieldContainer, overrides);
})();
Run Code Online (Sandbox Code Playgroud)
所以我在所有必填字段中添加了漂亮的星号.
问题是,有没有更简单的方法来实现这样的事情?覆盖非常苛刻,如果我们可以使用mixin,那么最好,但mixin不能覆盖行为
注意
这背后的原因是因为我已经定制了需要从基地扩展字段Text,Combo,FieldContainer.扩展字段中的Mixins甚至不会弄乱模板.他们太固执了.也许现在最好的方法是覆盖Base类... 查看工作示例
Mol*_*Man 28
我有一个更短的解决方案.我建议使用form的'beforeadd'事件,如下所示:
Ext.define('Ext.ux.form', {
extend: 'Ext.form.Panel',
initComponent: function() {
this.on('beforeadd', function(me, field){
if (!field.allowBlank)
field.labelSeparator += '<span style="color: rgb(255, 0, 0); padding-left: 2px;">*</span>';
});
this.callParent(arguments);
}
});
Run Code Online (Sandbox Code Playgroud)
这是演示
你仍然可以覆盖类似于extjs3 bun的布局组件,因为没有fieldLayout,我已经覆盖了Ext.layout.Layout.它与分子人的解决方案非常相似,但它更为通用.适用于除表单之外的其他容器中使用的字段.
Ext.override(Ext.layout.Layout, {
renderItem: function(item, target, position) {
if (item && !item.rendered && item.isFieldLabelable && item.fieldLabel && item.allowBlank == false) {
item.fieldLabel += ' <span class="req" style="color:red">*</span>';
}
this.callOverridden(arguments);
}
});
Run Code Online (Sandbox Code Playgroud)
这比你的解决方案简单,但不是更好,例如这里也用于字段集
你也可以覆盖和扩展任何东西,只需创建一个控制器动作,如下所示:
Ext.define('MyApp.controller.MyForm', {
extend: 'Ext.app.Controller',
markMandatoryFields: function(field, options) {
if (field && field.isFieldLabelable && field.fieldLabel && field.allowBlank == false) {
field.fieldLabel += ' <span class="req" style="color:red">*</span>';
}
},
init: function() {
this.control({
"field": {
beforerender: this.markMandatoryFields
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
对于Ext JS 4.1.1,这适用于:
Ext.define('com.ideas.widgets.Base', {
override : 'Ext.form.field.Base',
initComponent : function()
{
if(this.allowBlank!==undefined && !this.allowBlank)
{
if(!this.labelSeparator)
{
this.labelSeparator = "";
}
this.labelSeparator += '<span style="color:red">*</span>';
}
this.callParent(arguments);
}
});
Run Code Online (Sandbox Code Playgroud)