'Common function is not being called from listeners in ext js

I am trying to call 'ControlFocus' method from drop down focus event but it gives me error. I know it is some scoping issue but not sure how to do it.

So basically structure is as follow:

 Ext.define('Panel', {
 extend: 'Ext.Panel.panel',
   
    items: [       
        {
            xtype: 'container', 
            items: []
        },
        {
            xtype: 'fieldcontainer', 
            itemId: 'namefields',          
            items[]  
        },
        {
            xtype: 'fieldcontainer',
            itemId: 'namefieldsRow2',          
            items: []
        },
    
    ],

controlFocus: function(field) {  
     // I want to use this function in several controls
} 
});

Actual code

Ext.define('Panel', {
    extend: 'Ext.Panel.panel',
   
    items: [
        {
            xtype: 'hiddenfield',
            name: 'ID',
            itemId: 'id',
            value: 0
        },
        {
            xtype: 'container',          
            style: 'padding: 18px 0 10px 0;',
            defaults: {
                padding: '0 10 0 0',
                style: 'padding-left: 0;'
            },
            items: [
                {
                    name: 'ExportCode',
                    xtype: 'hiddenfield'
                },
                {
                    fieldLabel: 'BusinessStructure'),
                    name: 'BusinessStructureId',
                    itemId: 'BusinessStructureId',
                    lookupName: 'Structure',
                    xtype: 'combo',
                    id: 'BusinessStructureId',                                     
                    listeners: {                           
                        change: function(field) {                                                   
                        },

                        focus:function(combo, e, opts){                           
                        },
                        // scope: this,     // not working
                        blur: function(field,ev) {                                                  
                           
                        },                          
                    },                        
                },
                {
                    fieldLabel: 'ClientType',
                    name: 'ClientTypeId',
                    itemId: 'ClientTypeId',
                    lookupName: 'ClientType',
                    xtype: 'combo',                   
                },              
            ]
        },
        {
            xtype: 'fieldcontainer',
            itemId: 'namefields',
            layout: 'hbox',
            fieldDefaults: {
                labelCls: 'h-bold'
            },
            cls: 'u-hr-bottom-light',
            items: [
                {
                    fieldLabel:'Name'),
                    labelClsExtra: 'x-form-item-label x-required',
                    name: 'Name',
                    itemId: 'Name',
                    xtype: 'textfield',
                    fieldCls: 'big',
                    width: 650,
                    listeners: { 
                        focus: function(field, ev) {    
                        },
                        blur: function(field,ev) {  
                        },                  
                    }             
                },                   
                {
                    fieldLabel: 'FirstName'),
                    labelClsExtra: 'x-form-item-label x-required',
                    name: 'FirstName',
                    itemId: 'FirstName',
                    xtype: 'textfield',      
                    listeners: { 
                        focus: function(field) {
                        },
                        blur: function(field, ev) {  
                        },                                                  
                    }            
                },               
            ]
        },
        {
            xtype: 'fieldcontainer',
            itemId: 'namefieldsRow2',
            claims: [req.pm, req.au, req.autax],
            layout: 'hbox',
            fieldDefaults: {
                labelCls: 'h-bold'
            },
            cls: 'u-hr-bottom-light',
            items: [
                {
                    fieldLabel: 'ClientTitle',
                    name: 'Title',
                    itemId: 'Title',                  
                    xtype: 'editablecombo',                   
                },
                ]
        },
    
    ],

controlFocus: function(field) {  
     // I want to use this function in several controls
} 
});


Solution 1:[1]

The focus event gives you direct access to the combo.

You could just add the function directly to your listeners config like this:

listeners: {
    focus: function(combo, event, eOpts){ 
        //Add code here
    }
}

Since you don't want to add the function directly (You mentioned you wanted to use it in several components in your comment in the method) you should check out the view controller.
That way you can use just a String reference for the function in the view controller.

Here is a working sencha fiddle example: example

EDIT:

Since you don't want to use MVVM:

Another solution would be to have a "global" class with statics like this:

    Ext.define('Global.class.Listeners', {
        extend: 'Ext.Base',
        statics: {
            controlFocus: function (field) {
                debugger;
                //do some work here
                // I want to use this function in several controls
                Ext.toast('Global static class');
            }
        }
    });

In that case you could add the listener like this:

                listeners: {
                    change: function (field) {},
                    
                    focus: Global.class.Listeners.controlFocus,

                    blur: function (field, ev) {
                        //blur logic
                    }
                }

I modified my sencha fiddle for you: example

Oh and btw:

Never overwrite the @cfg id -> Alway use the itemId. Otherwise you might run into duplicate errors!

Solution 2:[2]

Have you tried a simpler approach?

The focus event of the combobox gives you a reference to the combobox that has launched it, so you can use the standard approach with the listeners config as below:

// Combobox
{       
    xtype: 'combo', 
    ...
    listeners: {
        focus: function(combo, e, opts){ 
            combo.up("panel").controlFocus(combo); 
        }
    }
}

Note! There is for sure a typo or missing/wrong brackets in the code you posted, so it is hard to know the scope of your controlFocus method (the container, the panel,...)

---EDIT---

Now that I got the code of your "Panel" I created a fiddle that shows how it works.

Solution 3:[3]

The error is thrown, because you did not specify the scope property in your listener configuration. As stated in the docs, it defaults to the component firing the event, in your case the combo box, see docs for details.

Your solution should be:

// combobox
{       
    xtype: 'combo', 
     ...
    listeners: {
        focus: 'controlFocus',
        scope: this
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Gotthard_w