web-dev-qa-db-ja.com

ExtJS 4-必須フィールドに赤いアスタリスクをマークします

フィールドに「必須」(またはallowBlank: false)のマークが付けられている場合、fieldLabelの横に赤いアスタリスクを追加する必要があるという問題があります。

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'
        };
    }
});

しかし、これはExtJS4では不可能です。 FormLayoutは適用されなくなり、ラベルは実際にはExt.form.field.Baseと呼ばれるミックスインを使用してExt.form.Labelableによってレンダリングされます。

残念ながら、Ext.form.Labelableを拡張することも、Ext.form.Labelableをオーバーライドすることもできません。 Ext.form.field.Baseの拡張コンポーネントは、それによる影響を受けません。ミックスインを入れ替えても、テンプレートは機能しません。

だからここに私の解決策があります、私は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);


})();

そして、すべての必須フィールドにニースアスタリスクを追加しています。

質問は、このようなものを達成する簡単な方法はありますか?オーバーライドはかなり厳しく、ミックスインを使用できる場合に最適ですが、ミックスインは動作をオーバーライドできません

この背後にある理由は、ベースTextComboFieldContainerから拡張する必要があるカスタマイズされたフィールドがあるためです。 拡張フィールドのMixinはテンプレートを混乱させることさえありません 。彼らはあまりにも頑固です。おそらく今のところ最良の方法は、Baseクラスをオーバーライドすることです... 実際の例を確認してください

23
Lionel Chan

私は少し短い解決策を持っています。次のようなフォームの「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);
    }
});

これが demo です

28
Molecular Man

FieldLayoutがない場合、Ext.layout.Layoutをオーバーライドしたので、extjs3 bunと同様のレイアウトコンポーネントをオーバーライドできます。それは分子マンの解に非常に似ていますが、より一般的です。フォーム以外のコンテナで使用されるフィールドでの作業。

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);
    }
});

これはソリューションよりも単純ですが、必ずしも優れているわけではありません。この例はフィールドセットでも使用されています here

6
nscrob

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);
    }
});
5
Varun Achar

何もオーバーライドして拡張せず、次のようなコントローラーアクションを作成することもできます。

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
            }
        });
    }
});

Extjs 4.1

フィールドにfieldLabelを使用する場合:

fieldLabel: 'Name',
allowBlank: false,    
afterLabelTextTpl: "<span style="color:red;font-weight:bold" data-qtip="Required">*</span>"

フィールドにfieldLabelがない場合は、設定オプションの組み合わせを使用するため、hideLabel設定をfalseにする必要があります。

//hideLabel: false
name: 'lastName',
emptyText: "Last Name",
allowBlank: false,    
labelWidth: 0,
fieldLabel: '',
hideEmptyLabel: false,
afterLabelTextTpl: '<span style="color:red;font-weight:bold" data-qtip="Required">*</span>'

また、このソリューションとDrasillプラグインを組み合わせることで、すべてのフィールドを一度に簡単にカスタマイズできます。

4
Esteban Gatjens

よりエレガントな方法として、allowBlank=falseでマークされたフィールドラベルにcssクラスを追加し、CSSで必須インジケーターをスタイルする方法があります。

Ext.define('Ext.ux.form', {

    extend: 'Ext.form.Panel',

    listeners: {
        'beforeadd': function(){
            if (!field.allowBlank) {
                field.labelClsExtra = 'x-required';
            }
        }
    }

});

次に、:after疑似ユーティリティを使用して、CSSでフィールドラベルのスタイルを設定できます。

.x-required:after {
    content: ' *';
    color: red;
    font-weight: bold;
}
4
Hady

このためのプラグインを作成しました。

このExtJS 4.1で動作します(少なくとも)。

このような場合に使用します:

Ext.create('Ext.form.Panel', {
  ...
  plugins : "formlabelrequired"
  ...
});

または、「アスタリスク」をカスタマイズするには:

Ext.create('Ext.form.Panel', {
  ...
  plugins : [{ptype:"formlabelrequired", asterisk:" (mandatory)"}]
  ...
});

プラグインのコードは次のとおりです。

/**
 * Plugin (ptype = 'formlabelrequired') that adds "asterisk" to labels
 * for Fields with "allowBlank: false".
 */
Ext.define('Ext.ux.plugin.form.LabelRequired', {

        extend: 'Ext.AbstractPlugin',

        alias: 'plugin.formlabelrequired',

        asterisk: ' <span class="required"> *</span>',

        constructor: function() {

            this.callParent(arguments);

        },

        init: function(formPanel) {
            formPanel.on('beforerender', this.onBeforeRender, this);
        },

        /**
         * @private
         * Adds asterisk to labels.
         */
        onBeforeRender: function(formPanel) {

            var i, len, items;

            items = formPanel.query('[allowBlank=false]');

            for (i = 0, len = items.length; i < len; i++) {
                item = items[i];
                item.afterLabelTextTpl = (item.afterLabelTextTpl || "") + this.asterisk;
            }

            return true;

        }

    });
2
Drasill

何もオーバーライドしたくない場合は、labelSeparatorにアスタリスクを入れます。

{
  xtype: 'textfield',
  fieldLabel: 'Name',
  name: 'requestor_name',
  allowBlank: false,
  labelSeparator : ': <span style="color:red">*</span>'
}
1
Evan Siroky

実際、私は fieldSubTpllabelableRenderTpl を使用して*を追加する方が、イベントリスナーを使用するよりもクリーンなアプローチだと思います。イベントを停止したり、リスナーを切り離したりできます。

OP(Lionel Chan)の懸念は、Ext.overrideを使用するのがちょっとハッキーで、100%正しいということだったと思います。しかし、フォーム構成レベルでカスタムtplを渡しても、それほど悪くはありません。

Ext.create('Ext.form.Panel',{
    defaults:{
        fieldSubTpl:['<input id="{id}" type="{type}" ', 
        '<tpl if="name">name="{name}" </tpl>', 
        '<tpl if="size">size="{size}" </tpl>', 
        '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>', 
        'class="{fieldCls} {typeCls}" autocomplete="off" />',
        '<span>',
        '<tpl if="allowBlank==false">*</tpl>',
        '</span>',
        {
            compiled: true, 
            disableFormats: true
    }]},
    items : [{
        xtype : 'textfield',.....

Tplに問題がある可能性があります。試したことがありません。

1
Chao

フィールドラベルに赤*を表示する場合は、これを行うfieldlabelを使用できます。

たとえば、次のコードはラベル名「Name」で新しいテキストフィールドを作成し、赤いアスタリスクが表示されます

var name = new Ext.form.TextField({
    fieldLabel : 'Label<span style=\"color:red;\" ext:qtip=\"This field is required\"> *</span>',
    name : 'name',
    id: 'Name',
    maxLength : 40,
    width : 205,
    allowBlank : false
});
0
sandeep vanama

彼らはこれを行うための非常に多くの方法であり、そのうちのいくつかは上記で見つけることができますが、私が提案しているのは:

 {
    xtype : 'label',
    html:'<span>First Name</span><span style="color: rgb(255, 0, 0); padding-left: 2px;">*</span>',
    width:50,
 }

単に、アスタリスクとラベルの両方のテキストを1つのhtmlプロパティに配置できます。

0
Mayur Gite