Results 1 to 9 of 9

Thread: Button with dynamic iconcls not showing the correct icon

  1. #1
    Sencha User
    Join Date
    Dec 2011
    Posts
    24
    Vote Rating
    1
      0  

    Default Answered: Button with dynamic iconcls not showing the correct icon

    Hi,

    I have a button with an iconcls that depends on a fieldvalue.
    The icon is set correctly (when I alert the iconcls of the button, it's correct), but it's not shown.
    Does anybody know what I am doing wrong?

    Code:
        modelAddForm.getForm().reset();
        
        var record = grid.getStore().getAt(index);
        grid.getSelectionModel().select(index);
        g_modelGrid.disable();
        
        modelAddForm.getForm().loadRecord(record);
        Ext.getCmp('buttonActivate').setIconCls(getActIcon('fldModelAct'));  // -> The correct icon is set!
        
        if(gs_action == 'UPDATE') {
            g_modelEditWindow.setTitle('Edit model');
            
        } else if(gs_action == 'COPY') {
            g_modelEditWindow.setTitle('Copy model');
            gs_action = 'INSERT';
        }
        g_modelEditWindow.show();
    
    //checks the field with id actFieldId to return the correct iconcls
    function getActIcon(activeFieldId) {
        var active = Ext.getCmp(activeFieldId).getValue();
        var result = '';
        if (active == true ) {
            result =  'icon-column-active';
        } else {
            result = 'icon-column-not-active';
        }
        return result;
    }
    in my css: (I put 'button.' before the class because I saw that on a forum as a possible solution, but it works the same as without)

    button.icon-column-active {background-image:url(../icons/active.png) ! important; }
    button.icon-column-not-active {background-image:url(../icons/notActive.png) ! important; }

  2. I never use Ext.getCmp with static ids. Not because it's buggy, just because it's a use of global variables and they're short-term gain for long-term pain. It's an OO anti-pattern.

    That said, Ext.getCmp does work. It will return you the component with that id. There's no such concept as casting in JavaScript. Given you aren't seeing an error message and it's updating the iconCls property it suggests that you are successfully calling setIconCls on a button, or possibly one of the other classes that support that method.

    That leads me to wonder which button you're calling it on, because it appears it isn't the button you think it is. You claim the ids are unique but I'm a bit cynical about that, one reason why the use of static ids is a bad idea is that you quickly slip into scenarios where you think ids are unique when they aren't.

    Try this. In the button's handler write something like this:

    Code:
    handler: function(btn) {
        console.log(btn === Ext.getCmp('buttonActivate'));
        console.log(btn.getId());
        console.log(Ext.getCmp('buttonActivate').getId());
    }
    I suspect you'll find it isn't the button you think it is.

    If things are still unexplained, try posting the code you use to create the button.

  3. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791
    Answers
    585
    Vote Rating
    393
      0  

    Default

    Is there a gap where the icon should be?

    Try to get it working by hard-coding the iconCls, that leaves less room for things to go wrong. Then try to do it dynamically.

    Inspect the elements using a debugger like Firebug or the Chrome Developer Tools. See whether the iconCls turns up as a class on your component's elements. If it does then the problem is just writing a suitable CSS rule. The tools I mentioned will let you inspect the current CSS rules to give you an idea of what you need to do.

  4. #3
    Sencha User
    Join Date
    Dec 2011
    Posts
    24
    Vote Rating
    1
      0  

    Default

    Thanks for the quick response.

    There's no gap, you just see the wrong icon. Even when I change the iconCls hardcoded, the new icon isn't shown.
    When I inspect the element with firebug, it's the original iconCls, not the new one.

    Any idea why?

  5. #4
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791
    Answers
    585
    Vote Rating
    393
      0  

    Default

    Before I dig any further, which ExtJS version are you using?

  6. #5
    Sencha User
    Join Date
    Dec 2011
    Posts
    24
    Vote Rating
    1
      0  

    Default

    I use ext-4.0.7-gpl

  7. #6
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791
    Answers
    585
    Vote Rating
    393
      0  

    Default

    OK, I gave it a shot and it worked fine for me. I've included my test case below, give it a try and see whether it works for you. If it does, it gives you a starting point for working out what the difference is.

    Code:
    Ext.onReady(function() {
        Ext.create('Ext.button.Button', {
            iconCls: 'icon-column-active',
            renderTo: Ext.getBody(),
            text: 'Click',
            handler: function(btn) {
                btn.setIconCls('icon-column-not-active');
            }
        });
    });
    Code:
    .icon-column-active {
        background-image: url(lib/silk/accept.png);
    }
    
    .icon-column-not-active {
        background-image: url(lib/silk/stop.png);
    }
    Inspecting with Firebug you should see HTML markup that looks a bit like this:

    Code:
    <div id="..." class="x-btn x-btn-default-small ...">
        <em id="..." class="">
            <button id="..." type="button" ... class="x-btn-center">
                <span id="..." class="x-btn-inner" style="">Click</span>
                <span id="..." class="x-btn-icon icon-column-not-active">&nbsp;</span>
            </button>
        </em>
    </div>
    Clearly putting 'button.' in your selector won't work as the iconCls is applied to the inner span, not the button element.

  8. #7
    Sencha User
    Join Date
    Dec 2011
    Posts
    24
    Vote Rating
    1
      0  

    Default

    You are right, like this it works.
    The difference with what I am trying to do is that the icon is changed in the handler of the button and 'setIconCls' is called on the btn reference of the handler
    When I do:
    Code:
    Ext.getCmp('buttonActivate').setIconCls
    in stead of :
    Code:
    btn.setIconCls
    it doesn't work anymore

    Do you know why?
    The id of the button is unique, so that is not the problem.
    The object returned from Ext.getCmp, do I have to cast it to a button object? If yes, how?

  9. #8
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,791
    Answers
    585
    Vote Rating
    393
      0  

    Default

    I never use Ext.getCmp with static ids. Not because it's buggy, just because it's a use of global variables and they're short-term gain for long-term pain. It's an OO anti-pattern.

    That said, Ext.getCmp does work. It will return you the component with that id. There's no such concept as casting in JavaScript. Given you aren't seeing an error message and it's updating the iconCls property it suggests that you are successfully calling setIconCls on a button, or possibly one of the other classes that support that method.

    That leads me to wonder which button you're calling it on, because it appears it isn't the button you think it is. You claim the ids are unique but I'm a bit cynical about that, one reason why the use of static ids is a bad idea is that you quickly slip into scenarios where you think ids are unique when they aren't.

    Try this. In the button's handler write something like this:

    Code:
    handler: function(btn) {
        console.log(btn === Ext.getCmp('buttonActivate'));
        console.log(btn.getId());
        console.log(Ext.getCmp('buttonActivate').getId());
    }
    I suspect you'll find it isn't the button you think it is.

    If things are still unexplained, try posting the code you use to create the button.

  10. #9
    Sencha User
    Join Date
    Dec 2011
    Posts
    24
    Vote Rating
    1
      0  

    Default

    You were absolutely right!
    In a widget I created I had a button with the same id.
    I already had a bad feeling about the large amount of global variables.
    Being a java programmer, OO principles are not new to me, but I am new to extjs and javascript and I still have to learn a lot about it's syntax and possibilities. I guess I should do some research on setting up a good application structure and rearrange my whole app.

    Thanks for your help!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •