3

My ExtJS button's handler is not invoked after clicking. Now the code looks like this.

Ext.define('EDS.view.selector.Container', {
    extend: 'Ext.form.Panel',
    alias : 'widget.selectorcontainer',

    title: 'Selector_V2',
    renderTo: 'input-div',
    layout: 'fit',
    height: '100%',

    items: [
            {
                xtype: 'tabpanel',
                defaults: {
                    bodyPadding: 10
                },
            }
    ],
    buttons: [
        {
            text: 'Reset',
            handler: function(){
                console.log("Reset");
                this.up('form').getForm().reset();
            }
        },
        {
            text: 'Add to constrain',
            handler: this.addConstrain,
        }
    ],

    /*
     * Logic for button "Add to constrain"
     * 
     * Adds an entry into the constrain list describing a person, cost center or an application
     */
    addConstrain: function(button, event){
        console.log('Add_to_constrain clicked');
    }
});

Originally this 'selectorcontainer' was put diretly in my app.js. But I extracted it into a stand-alone view. Before the extraction, it works perfect but now it is not working.

BTW, I've two buttons and the first "reset" works fine. So I'm wondering if there's anything wrong with "this.addConstrain" related to scoping.

3
  • You should clean up your trailing commas, otherwise this will break in some browsers. Commented Aug 20, 2013 at 2:21
  • Good point. I'll do that after the development completes. Is there any 3rd party tools on that? @Towler Commented Aug 20, 2013 at 2:56
  • I haven't come across any, but I haven't looked too hard either. If you find one, let me know! Commented Aug 20, 2013 at 11:02

2 Answers 2

5

You're right, it is a scoping issue - this is not the class you're defining; it's the scope at the time the Ext.define function is called (likely window). There are a few ways to handle this. The easiest (in my opinion) is to change your handler to work similarly to your reset handler:

{
    text: 'Add to constrain',
    handler: function(btn, e) {
       //'this' is now the button
       this.up('selectorcontainer').addConstrain(btn, e);
    }
}

You could also add the buttons as part of the initComponent function instead of defining them as part of the Ext.define config.

initComponent: function() {
    //'this' is now the selector container
    this.buttons = [{
        text: 'Reset',
        handler: function(){
            console.log("Reset");
            this.up('form').getForm().reset();
        }
    }, {
        text: 'Add to constrain',
        handler: this.addConstrain
    }];

    this.callParent();
}
Sign up to request clarification or add additional context in comments.

3 Comments

Works perfect. I chose your second solution. It's a shame that I can not vote up more than one time
I prefer the first one because it makes the code a bit cleaner. However, when I use it, I do "btn.up()…" instead of "this.up()…" for clarity. That way I don't have to mess with scoping.
It is better to add: "scope: this," between "text: 'Add..." and "handler:..". Then the scope of the handler is pointing to the object where the button is child of.
4

The proper way to design your class is like this. You apply your config settings to the object before you do the callParent.

Ext.define('EDS.view.selector.Container', {
    extend: 'Ext.form.Panel',
    alias : 'widget.selectorcontainer',

    title: 'Selector_V2',
    renderTo: 'input-div',
    layout: 'fit',
    height: '100%',

    initComponent: function() {

        Ext.applyIf(this, {

           items: [
               {
                   xtype: 'tabpanel',
                   defaults: {
                      bodyPadding: 10
                   }
               }
           ],
           buttons: [
               {
                  text: 'Reset',
                  scope: this,                 // <--- scope to form panel
                  handler: function(){
                     console.log("Reset");
                     this.getForm().reset();
                  }
               },
               {
                   text: 'Add to constrain',
                   scope : this,               // <--- scope to form panel
                   handler: this.addConstrain
               }
           ]
       });

       this.callParent(arguments);

  }
  /*
   * Logic for button "Add to constrain"
   * 
   * Adds an entry into the constrain list describing a person, cost center or an      application
   */
   addConstrain: function(button, event){
      console.log('Add_to_constrain clicked');
   }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.