I’m working on adding Header controls to my version of the Flex Rich Text Editor, and I noticed that the ToggleButtonBar doesn’t… exactly… work. I dug into the source and saw why. When using the “ToggleOnClick” property, the TBB does some funny stuff that it’s parent, the regular ButtonBar, doesn’t really care about. While it’s possible to set the TBB’s selectedIndex to -1, this doesn’t actually get transmitted to the parent ButtonBar. This means that, while the TBB deselects the item properly, the parent BB still think you have the same thing selected. Which means you can’t click on it again until you select something else and then come back to it.
I found a blog post of someone else complaining about this, and–even more valuabe–there was a comment from an Adobe employee saying they’d checked in a fix for this (into Flex 3). Hooray open source! I just went over to Adobe’s site, grabbed the latest build of the Flex 3 Beta, and copied the source for the new ToggleButtonBar into a new file in my source directly (which I’m calling FixedTBB).
The selection quirks are indeed fixed in the new version, but there were two more bugs in the ToggleButtonBar code. The logic for whether or not to select or deselect a particular button happens in the function “hiliteSelectedNavItem,” which is called after the clickHandler. So what? This means, from an itemClickEvent perspective, that the ToggleButtonBar will NEVER generate an event where the selectedIndex = -1. Why don’t I just check the TBB’s selectedIndex manually instead of trusting the events? Well, the handler for the event is actually getting called before the TBB’s hiliteSelectedNavItem fires, so as far as my event handler is concerned the selectedIndex can never be -1.
As I want the deselects to turn off paragraph styles, this is a bad thing. Luckily, it’s easy to fix. In the clickHandler function, you need to change it so that if you’re turning off a button it dispatches that event rather than letting the parent NavBar fire of its simpler “You clicked on Button #4″ event:
Previous version:
if (_toggleOnClick && index == selectedIndex) hiliteSelectedNavItem(-1); else hiliteSelectedNavItem(index); super.clickHandler(event);
New Version:
if (_toggleOnClick && index == selectedIndex)
{
selectedIndex = -1;
hiliteSelectedNavItem(-1);
var newEvent:ItemClickEvent = new ItemClickEvent(ItemClickEvent.ITEM_CLICK);
newEvent.label = "none";
newEvent.index = -1;
newEvent.item = null;
dispatchEvent(newEvent);
event.stopImmediatePropagation();
}else{
hiliteSelectedNavItem(index);
super.clickHandler(event);
}
And voila! My listener for itemClickEvents now magically also knows when a user has deselected something!
The other fix was pretty trivial as well. By default, the ToggleButtonBar always selects one of the items to begin with. As Headers are clearly optional states, I definitely don't want that. There's a private variable called "initializeSelectedButton" which defaults to true. Once the first button is added to a TBB, a function sets its selected property to true and then sets initializeSelectedButton to false. I just made that variable public and set it to false manually before adding any buttons, and my problems were solved. The better thing would be to actually create getters/setters for it, but I'll leave that to the Adobe whiz-kids.

#1 by Ranjit on 07/06/2010 - 2:52 am
there is very easier way
set toggleOnClick=”true” of Togglebuttonbar