Sometimes I have the need to associate two different actions to the same button. It is not always a good solution. Indeed, good user interfaces should have a clear layout and buttons should always do the same thing. Sometimes, but very rarely, you can disregard such a rule and associate different actions to the same button. It is the case of play/pause. If you check your Itunes you will notice that when you click play the button changes icon to pause and viceversa. Same for Windows Media Player and many other players. This is allowed because actions are distinct and mutually exclusive.
I was in front of a similar situation when I added the possiblity to visualize comments in Posty. The feature is very similar in Pownce, which allows replies to posts, and Friendfeed which has comments attached to entries. What I wanted to obtain is a button which is:
- visible when there are comments/replies
- dynamic, in the sense it switches functionality (and label) according to the state of comments/replied (shown or hidden)
To give you the flavor of my solution here I propose a demo with a button that shows/hides a logo.
Demo (right click to view source).
The solution exploits Flex capability to represent functions as objects. If you check out the code you’ll see a variable declared like this:
private var _functionToBeCalled:Function = showLogo;;
The application initializes the variable with the showLogo function assigned by default. When executed, this function shows the logo, sets hideLogo
as the function to be called next time and changes the label to “Hide logo”.
private function showLogo():void { logo.visible = true; this.linkButton.label = "Hide logo"; this._functionToBeCalled = hideLogo; }
The hideLogo function does the exact “opposite”: hides the logo, sets the function to be called back to showLogo and changes the label.
Enjoy the trick!
Cool, I like using inline conditionals for simple ‘this’ or ‘that’ logic on a button for example. Some like some dont. Heres a double whammy:
[Bindable] private var show:Boolean = false;
private function showLogo():void
{
( show ) ? show = false : show = true;
}
Ahhh man the tags prevented the button from showing :)
mx:Button id=”show_btn” click=”showLogo()”
label=”{ ( show )?’Show Logo’:'Hide Logo’ }”
That solution works, but in the Flex world we don’t code like that anymore.
What you want is simply:
private function showLogo():void {
show = !show;
logo.visible = show;
linkButton.label = (show) ? “Hide Logo” : “Show Logo”;
}