I have an Ext.form.field.Text
and I want to override the setValue
function.
What is the recommended way to override this class functionality in ExtJS? Ext.override?
I have an Ext.form.field.Text
and I want to override the setValue
function.
What is the recommended way to override this class functionality in ExtJS? Ext.override?
For clarification: By real class modification I mean a intended permanent modification/extension of a class, which should always be done by extending a class. But it is not a temporary solution for just a specific problem (bug-fix, etc.).
You have at least four options how to override members of (Ext) Classes
prototype I guess is well known and allows you to override a member for all instances of a class. You can use it like
Ext.view.View.prototype.emptyText = "";
While you can't use it like
// callParent is NOT allowed for prototype
Ext.form.field.Text.prototype.setValue = function(val) {
var me = this,
inputEl = me.inputEl;
if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
inputEl.removeCls(me.emptyCls);
me.valueContainsPlaceholder = false;
}
me.callParent(arguments);
me.applyEmptyText();
return me;
};
Here's a JSFiddle
This variant should not be used for real class modifications.
Ext.override does nearly the same then prototype but it fully applies to the ExtJS Class-system which allows you to use callParent()
You can use it like
// callParent is allowed for override
Ext.override('Ext.form.field.Text', {
setValue: function(val) {
this.callParent(['In override']);
return this;
}
});
Here's a JSFiddle (c-p error fixed! Thanks to @nogridbag)
Use case: I faced a (I think still existing) bad behavior of a radiogroup where ExtJS expect a object (key-value-pair) for correct setting of the value. But I have just one integer on my backend. I first applied a fix using Ext.override for the
setValue()
method and afterwards extend from radiogroup. There I just make a Key-Value-Pair from the given value and call the parent method with that.
As @rixo mentioned this can be used for overriding a instance member. And may therefore be qualified for overriding even mixins (I never tested it myself)
var panel = new Ext.Panel({ ... });
Ext.override(panel, {
initComponent: function () {
// extra processing...
this.callParent();
}
});
This variant should not be used for real class modifications.
Extending a existent class to apply additional behavior & rendering. Use this variant to create a subtype that behaves different without loosing the original type.
In the following example we extend the textfield with a method to change the labelcolor when setting a new value called setColored
and override the setValue
method to take care of removing a label color when setValue
is called directly
Ext.define('Ext.ux.field.Text',{
extend: 'Ext.form.field.Text',
widget: 'uxtextfield',
setColored: function(val,color) {
var me = this;
if (me.settedCls) {
me.removeCls(me.settedCls);
}
me.addCls(color);
me.settedCls = color;
me.setValue(val,true);
},
setValue: function(val,take) {
var me = this;
if (!take && me.settedCls) {
me.removeCls(me.settedCls);
}
me.callParent(arguments);
return me;
}
});
Here's a JSFiddle
Overriding per instance will happen in really rare cases and might not be applicable to all properties. In such a case (where I don't have a example at hand) you have a single need for a different behavior and you might consider overriding a setting just per instance. Basically you do such things all times when you apply a config on class creation but most time you just override default values of config properties but you are also able to override properties that references functions. This completely override the implementation and you might allows don't have access to the basetype (if any exist) meaning you cannot use callParent
. You might try it with setValue
to see that it cannot be applied to a existing chain. But again, you might face some rare cases where this is useful, even when it is just while development and get reimplemented for productive. For such a case you should apply the override after you created the specific by using Ext.override as mentioned above.
Important: You don't have access to the class-instance by calling
this
if you don't use Ext.override!
If I missed something or something is (no longer) correct, please comment or feel free to edit.
As commented by @Eric
None of these methods allow you to override mixins (such as Ext.form.field.Field). Since mixin functions are copied into classes at the time you define the class, you have to apply your overrides to the target classes directly
Ext.form.field.Field
). Since mixin functions are copied into classes at the time you define the class, you have to apply your overrides to the target classes directly. –
Philo Ext.define
in combination with the override
param instead of the extend
param. That way you can use the class loading system and require overrides like you can require any other defined class. –
Hyalite override
otherwise you get an error. ExtJS doesn't support this out of the box. But you can add a custom Ext.override
for that, which only applies if the method not exist. I just wouldn't name it override ;) Another way is within the initComponent
after the callParent
call. You can now check if a method exist and and apply it if not. You would use Ext.applyIf
for that. But you will never know if the function with the same name really does the same thing! –
Callboy method_exists
function. Of course you will never know if the function does the exact same thing, but in my case (I want to override the Ext.data.TreeStore
with a commitChanges
method, which doesn't appear to be there in 4.1.3), I am pretty sure that if it is ever implemented in the future, it will do exactly what I need it to do :) –
Intermix Ext.override
on instances -- not only class -- and have callParent
working in overridden methods (as seen in the example in the doc of the function). –
Tim The answer by @sra is great and was very helpful to me in gaining a deeper understanding of the override functionality available in Ext, but it does not include the way that I most commonly implement overrides which looks something like this:
Ext.define('my.application.form.field.Text' {
override: 'Ext.form.field.Text'
getValue: function () {
// your custom functionality here
arguments[1] = false;
// callParent can be used if desired, or the method can be
// re-written without reference to the original
this.callParent(arguments)
}
});
I'm still using Ext 5 so I would then load this file in my Application.js
and add it to the requires array there which applies the override to the app globally. I think Ext 6 projects include an override folder and simply adding this file to that folder ensures the override is applied.
This is the only way that works for me in ExtJS 7.
Example:
app/desktop/overrides/Toast.js
Ext.define(null, {
override: 'Ext.window.Toast',
show : function () {
this.callParent();
// Your custom code here...
}
});
© 2022 - 2024 — McMap. All rights reserved.