ExtJS 4 - 在必填字段上标记红色星号

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)

这是演示


nsc*_*rob 6

你仍然可以覆盖类似于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)

这比你的解决方案简单,但不是更好,例如这里也用于字段集


Chr*_*eek 5

你也可以覆盖和扩展任何东西,只需创建一个控制器动作,如下所示:

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)


Var*_*har 5

对于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)