forms extjs extjs4 required-field

forms - ExtJS 4: marque un asterisco rojo en un campo obligatorio



extjs4 required-field (11)

Tengo este problema donde necesito agregar un asterisco rojo al lado de una fieldLabel campo cuando un campo está marcado como "requerido" (o allowBlank: false )

En ExtJS3, podemos tener este truco fácilmente anulando Ext.layout.FormLayout siguiente manera:

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

Pero esto es imposible en ExtJS4. FormLayout ya no es aplicable y, de hecho, Ext.form.field.Base representa las Ext.form.field.Base utilizando una Ext.form.Labelable llamada Ext.form.Labelable .

Tristemente, ni extender Ext.form.Labelable o anular Ext.form.Labelable es viable para mí. Los componentes extendidos de Ext.form.field.Base no reciben ningún efecto de ello. Incluso si cambio las mixinas, las plantillas aún no funcionarían.

Así que aquí viene mi solución, donde hice una anulación muy dura sobre Ext.form.field.Base , y funciona de la siguiente manera ( Vea mi ejemplo )

Esto es solo para ExtJS 4.0.7. Para usarlo en ExtJS 4.0.2a, necesita modificar el labelableRenderTpl acuerdo con el que se encuentra en 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); })();

Y entonces tengo el asterisco agradable agregado a todos los campos requeridos.

La pregunta es, ¿hay alguna manera más fácil de lograr algo como esto? Anulación es bastante dura, mejor si podemos usar mixins, pero mixins no puede anular el comportamiento

Nota

La razón detrás de esto se debe a que he personalizado campos que deben ampliarse desde la base Text , Combo , FieldContainer . Mixins en el campo extendido ni siquiera se mete con la plantilla . Ellos son muy tercos. Tal vez la mejor manera por el momento es anulando la clase Base ... Eche un vistazo al ejemplo de trabajo


De hecho, creo que usar fieldSubTpl y labelableRenderTpl para agregar * es un enfoque más limpio que usar el detector de eventos. Los eventos pueden detenerse, los oyentes pueden separarse.

Creo que la preocupación de OP (Lionel Chan) fue que usar Ext.override es un poco hacky y tiene el 100% de razón. Pero si pasamos el tpl personalizado en el nivel de configuración del formulario, no es tan malo:

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'',.....

Podría haber algo mal con el tpl, no lo he intentado.


Extjs 4.1

Cuando el campo tiene una etiqueta de campo use:

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

Si el campo no tiene una etiqueta de campo use una combinación de opciones de configuración, la configuración de hideLabel debe ser falsa:

//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>''

Además, puede mezclar esta solución con el plugin Drasill y tener una manera fácil de personalizar todos los campos a la vez.


Hay muchas formas de hacerlo y pocas de las cuales puedes encontrar arriba, lo que sugiero es:

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

Simplemente puede poner tanto asterisco como texto de etiqueta en una sola propiedad html.


He hecho un complemento para esto.

Funciona este ExtJS 4.1 (al menos).

Úselo así:

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

O bien, para personalizar el "asterisco":

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

Aquí está el código para el complemento:

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


Para Ext JS 4.1.1 esto funciona:

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


Si desea que se muestre el rojo * para una etiqueta de campo, podemos usar la etiqueta de campo que hace esto.

Por ejemplo, el siguiente código crea un nuevo campo de texto con el nombre de etiqueta "Nombre" y se muestra un asterisco rojo

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


Si no desea anular nada, coloque el asterisco en LabelSeparator:

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


También puede anular y ampliar nada y solo crear una acción de controlador como esta:

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


Tengo una solución un poco más corta. Sugiero usar el evento ''beforeadd'' del formulario de esta manera:

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

Aquí está la demo


Todavía puede anular el componente de diseño similar a extjs3 bun dado que no hay fieldLayout, he reemplazado a Ext.layout.Layout . Es bastante similar a la solución del hombre molécula, pero es más general. Trabajando para campos usados ​​en otros contenedores que en formularios.

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

Esto es más simple que su solución, pero no necesariamente mejor, ejemplo que también se usa en conjuntos de campo here


Un enfoque que puede encontrar más elegante es agregar una clase css a cualquier etiqueta de campo que esté marcada con allowBlank=false y allowBlank=false estilo a su indicador obligatorio en CSS.

Ext.define(''Ext.ux.form'', { extend: ''Ext.form.Panel'', listeners: { ''beforeadd'': function(){ if (!field.allowBlank) { field.labelClsExtra = ''x-required''; } } } });

Luego puede darle un estilo a su etiqueta de campo en CSS con una :after pseudo utilidad:

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