I have this problem where I need to add a red asterisk beside a fieldLabel
when a field is marked as \"required\" (or allowBlank: false
)
In
You can still override the layout component similar to extjs3 bun given that there is no fieldLayout, I've overriden Ext.layout.Layout
. It's quite similar to molecule man's solution but it's more general. Working for fields used in other containers than forms.
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);
}
});
This is simpler than your solution but not necesarely better, se example also used in fieldsets here
I've made a plugin for this.
Works this ExtJS 4.1 (at least).
Use if like this :
Ext.create('Ext.form.Panel', {
...
plugins : "formlabelrequired"
...
});
Or, to customize the "asterisk":
Ext.create('Ext.form.Panel', {
...
plugins : [{ptype:"formlabelrequired", asterisk:" (mandatory)"}]
...
});
Here is the code for the plugin :
/**
* 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;
}
});
If you want red * to be displayed for a field label we can use fieldlabel which does this.
For example the below code creates new text field with label name "Name" and red asterisk is displayed
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
});
You can also override and extend nothing and just create a controller action like so:
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
}
});
}
});
For Ext JS 4.1.1 this works:
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);
}
});
Actually I think using fieldSubTpl and/or labelableRenderTpl to add the * is a cleaner approach than using the event listener. Events can be stopped, listeners can be detached.
I think OP(Lionel Chan)'s concern was that using Ext.override is kinda hacky and he's 100% right. But if we pass the custom tpl in at the form configuration level it's not that bad:
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',.....
There could be something wrong with the tpl, i haven't tried.