May 22 2008

Powerful MXML Bindings with Ternary (?:) Operators

Posted by Joe Rinehart at 9:00 AM
4 comments
- Categories: Flex

One thing I've found myself doing more and more often in Flex applications is using Ternary operators within data bindings. Frequently, if I find myself with an event handler that updates visual state based on nothing more than a condition, I can replace the AS3 function entirely with such a binding.

A example over on the Flexexamples blog that was posted earlier today shows a good "before" picture of the situation. A change handler is assigned to a checkbox, and based on the state of the checkbox, an error string is set / nulled:

<mx:Script>
<![CDATA[
private function checkBox_change(evt:Event):void {
   if (checkBox.selected) {
      checkBox.errorString = "";
   } else {
      checkBox.errorString = "You must click here to continue";
   }
}
]]>
</mx:Script>

<mx:CheckBox
   id="checkBox"
   label="I have read and agreed to your license"
   errorString="You must click here to continue"
   change="checkBox_change(event);"
   width="100%"
/>
Full code available at Flexexamples.

What's the Ternary operator?

It's a shortcut to a conditional operator that uses a ?: combination as a quick "if / then / else" to return one of two values. It can replace the following code:

if (foo == bar)
{
   result = "success";
}
else
{
   result = "failure";
}

With this:

result = (foo == bar ? "success" : "failure");

What's important about it in this context is that it's legal to use it within a data binding expression.

Putting it all together

By using a ternary operator in a binding expression to control the CheckBox's error string, we can replace the AS3 event handler in the Flexexample code entirely, leaving us with nothing but MXML:

<mx:CheckBox
   id="checkBox"
   label="I have read and agreed to your license"
   errorString="{checkBox.selected ? null : checkBoxErrorString}"
   width="100%"
/>

Other uses

I find myself often using this to control whether or not a control is enabled/disabled while a server-side operation takes place:

<mx:Panel
   title="Edit User: John Doe"
   enabled="{this.saveStatus != AsynchonousStatus.WAITNG}"
/>

I'll also use it to show / hide elements when a full-bore state may not be necessary:

<mx:HBox>
   <mx:Button label="Home" />
   <mx:Button
      label="User Management"
      includeInLayout="{currentUser.isAdministrator}"
      visible="{currentUser.isAdministrator}"
   />

</mx:HBox>

Conclusion

Data binding allows us to work declaratively, and by using it to evaluate expressions as well as update data, we can avoid a good deal of manual event handling.

Comments

radekg

radekg wrote on 05/22/08 10:27 AM

I remember myself struggling with declaring AND statement inside data binding. I could add || for OR but never knew AND... that was so easy - just { this.condition1 &amp;amp;&amp;amp; this.condition2 } gives AND :)
todd sharp

todd sharp wrote on 05/22/08 2:30 PM

I used to use this sweet shortcut with Flash Forms (gasp!) believe it or not. I love it - the only catch - which I'm sure most folks are savvy enough to figure out - is to remember that MXML must be XML compliant - so no special chars. So if you wanted to do:

&lt;mx:Panel
title=&quot;Edit User: John Doe&quot;
enabled=&quot;{this.saveStatus != AsynchonousStatus.WAITNG &amp;&amp; foo != bar}&quot;/&gt;

You'd have to use:

&lt;mx:Panel
title=&quot;Edit User: John Doe&quot;
enabled=&quot;{this.saveStatus != AsynchonousStatus.WAITNG &amp;amp;&amp;amp; foo != bar}&quot;/&gt;

Someone correct me if I mispoke (i'm no Flex guru)...
Rachel

Rachel wrote on 05/23/08 12:19 PM

Cool tip... I seem to remember at some point looking for an &quot;iif&quot; type function in Flex but didn't realize you could do that!
Dusty Jewett

Dusty Jewett wrote on 07/24/08 6:38 PM

Awesome tip, just remember one thing. Flex automatically generates a lot of code for each 'object' in a bind statement.

This is an awesome shortcut for quick projects, but once you get into the optimization portion of development, these bindings should be the first things to go.

Write your comment



(it will not be displayed)