PDA

View Full Version : Button with dynamic iconcls not showing the correct icon



kathy_s
6 Jan 2012, 2:13 AM
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?



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; }

skirtle
6 Jan 2012, 2:25 AM
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.

kathy_s
6 Jan 2012, 3:15 AM
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?

skirtle
6 Jan 2012, 3:30 AM
Before I dig any further, which ExtJS version are you using?

kathy_s
6 Jan 2012, 4:22 AM
I use ext-4.0.7-gpl

skirtle
6 Jan 2012, 5:33 AM
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.


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');
}
});
});


.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:


<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.

kathy_s
6 Jan 2012, 6:27 AM
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:

Ext.getCmp('buttonActivate').setIconCls
in stead of :

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?

skirtle
6 Jan 2012, 6:49 AM
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:


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.

kathy_s
6 Jan 2012, 12:07 PM
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!