1

For ExtJS 6.5+ Modern, how do you add a click event to an component so that you can access it in a view controller.

The example below doesn't work. I have also tried adding a listener directly to the sub-element.

Example Template:

Ext.define('TestController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.test-controller',

    control: {
        '[reference=someComponent]': {
            click: 'someComponentClick'
        }
    },

    someComponentClick: function() { 
       console.log('it worked!')
    }
})


Ext.define('TestContainer', {
    extend: 'Ext.Container',
    xtype: 'test-container',
    controller: 'test-controller',
    items: [
        {
            xtype: 'component',
            reference: 'someComponent'
            html: 'CLICK HERE TO TEST'
        }
    ]
})

Update

Based on priyadarshi answer, the following on the element calls the function in the controller. I would prefer however to pick the event up normally in the controller by just listening to the click event. Is there anyway to attach event listeners to the dom from the controller or at least fire an event from the element so that you can pick it up in the controller (without it explicitly calling functions on the controller).

 Ext.define('TestController', {
     extend: 'Ext.app.ViewController',
     alias: 'controller.test-controller',

     control: {
         '[reference=someComponent]': {
             click: 'someComponentClick'
         }
     },

     someComponentClick: function() { 
        console.log('it worked!')
     },
     someFuncOnController: function() {
         console.log('someFuncOnController') // << This runs
     }
 })


 Ext.define('TestContainer', {
     extend: 'Ext.Container',
     xtype: 'test-container',
     controller: 'test-controller',
     items: [
         {
             xtype: 'component',
             reference: 'someComponent'
             html: 'CLICK HERE TO TEST',
             listeners: [
                 element: 'element',
                 click: 'someFuncOnController'
             ]
         }
     ]
 })
Tony J Watson
  • 629
  • 2
  • 9
  • 20

3 Answers3

4

In ExtJS 6.x we don't need to provide reference or control like below code

control: {
        '[reference=someComponent]': {
            click: 'someComponentClick'
        }
    }

When a view controller is specified on a view, events and other handlers that use strings as values will be automatically connected with the appropriate methods in the controller's class.

In this FIDDLE, I have created a demo using view and view controller. This show better explanation for events. I hope this will help you or guide you.

CODE SNIPPET

Ext.define('MyViewController', {
    extend: 'Ext.app.ViewController',
    alias: 'controller.myview',

    // This method is called as a "handler" for the Add button in our view
    onAddClick: function () {
        Ext.Msg.alert('Success', 'Button Click');
    },
    // This method is called as a "click" for the component in our view
    onComponentClick: function () {
        Ext.Msg.alert('Success', 'Component Click');
    },
    // This method is called as a "click" for the label in our view
    onLabelClick: function () {
        Ext.Msg.alert('Success', 'Label Clcik');
    }
});

Ext.create('Ext.Panel', {
    controller: 'myview',
    renderTo: Ext.getBody(),
    items: [{
        xtype: 'button',
        text: 'Add',
        handler: 'onAddClick', // calls MyViewController's onAddClick method
    }, {
        xtype: 'component',
        margin: 10,
        style:"padding: 10px;border: 1px solid #ccc;cursor: pointer;",
        html: 'Component->click here to test {component} click',
        listeners: {
            element: 'element',
            click: 'onComponentClick' // calls MyViewController's someFuncOnController method
        }
    }, {
        xtype: 'label',
        margin: 10,
        style:"padding: 10px;border: 1px solid #38839d;cursor: pointer;",
        html: 'Label Component->click here to test {label} click',
        listeners: {
            element: 'element',
            click: 'onLabelClick' // calls MyViewController's onLabelClick method
        }
    }]
});
Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
  • 1
    Maybe needless to say, but: mind the quotes for the callback method (`'onComponentClick'`)! Without them an error occurs. – 321X Oct 09 '19 at 12:35
0

Containers do not have a click event. You need to target the DOM element to attach the event. Do something like this.

      var container = Ext.create('Ext.Container', {
      renderTo: Ext.getBody(),
      html: 'Click Me!',
      listeners: {
        click: function(){
            Ext.Msg.alert('Success!', 'I have been clicked!')  
          }
        }
     });

    container.getEl().on('click', function(){ 
      this.fireEvent('click', container); 
    }, container);
  • Based on priyadarshi answer, the following on the element calls the function in the controller. I would prefer however to pick the event up normally in the controller by just listening to the click event. Is there anyway to attach event listeners to the dom from the controller or at least fire an event from the element so that you can pick it up in the controller (without it explicitly calling functions on the controller). – Tony J Watson Dec 05 '17 at 01:26
  • Yes, it can be done. I will post the code in sometime. I am currently on mobile device. – priyadarshi swain Dec 05 '17 at 02:55
0

Altering your code.

Do you need something like this?

Ext.define('TestController', {
 extend: 'Ext.app.Controller',

 init: function() {
     this.control({
         'test-container': {
             buttonClicked: this.onButtonClick
         }
     });
 },

 onButtonClick: function(button) { 
    console.log('it worked!')
 }
})


Ext.define('TestContainer', {
 extend: 'Ext.Container',
 xtype: 'test-container',
 //controller: 'test-controller', //declare your controller in your app.js
 items: [
     {
         xtype: 'button',
         text: 'Click Me!'
         listeners: {
             tap: function (button) {
                 var container = button.up('test-container');
                 container.fireEvent('buttonClicked', button);
             }
         }
     }
 ]
})
Zoti
  • 822
  • 11
  • 31
  • This is not as nice as being able to just use control directly without having to modify the view, but this definitely works. – Tony J Watson Dec 13 '17 at 11:45
  • you can capture the event using something like `'button[itemId=btnClick]'` but i would stick with this approach. It's more elegant imho. (add `itemId: 'btnClick'` to the button inside your view) – Zoti Dec 13 '17 at 12:49