Flex Numeric Stepper with Currency
Flex's numeric stepper controls work well but will only work with numeric data so can't be used for editing currency.
There's a few ways around the issues but none of the solutions are perfect.
Here's but I'd like to work;
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:DataGrid dataProvider="{products}" editable="true">
<mx:columns>
<mx:DataGridColumn width="100" headerText="Product" dataField="description" editable="false" />
<mx:DataGridColumn width="60" headerText="Price" textAlign="right" dataField="price" editorDataField="text">
<mx:itemEditor>
<mx:Component>
<mx:NumericStepper xmlns:mx="http://www.adobe.com/2006/mxml" stepSize="0.01" minimum="0.01" maximum="100" />
</mx:Component>
</mx:itemEditor>
<mx:itemRenderer>
<mx:Component>
<mx:HBox>
<mx:CurrencyFormatter id="money" precision="2" />
<mx:Label id="price" text="{money.format(data.price)}" />
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var products:ArrayCollection = new ArrayCollection([{description:"Milk", price:1.99}, {description:"Bread", price:1.50}, {description:"Honey", price:3.99}]);
]]>
</mx:Script>
</mx:Application>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:DataGrid dataProvider="{products}" editable="true">
<mx:columns>
<mx:DataGridColumn width="100" headerText="Product" dataField="description" editable="false" />
<mx:DataGridColumn width="60" headerText="Price" textAlign="right" dataField="price" editorDataField="text">
<mx:itemEditor>
<mx:Component>
<mx:NumericStepper xmlns:mx="http://www.adobe.com/2006/mxml" stepSize="0.01" minimum="0.01" maximum="100" />
</mx:Component>
</mx:itemEditor>
<mx:itemRenderer>
<mx:Component>
<mx:HBox>
<mx:CurrencyFormatter id="money" precision="2" />
<mx:Label id="price" text="{money.format(data.price)}" />
</mx:HBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var products:ArrayCollection = new ArrayCollection([{description:"Milk", price:1.99}, {description:"Bread", price:1.50}, {description:"Honey", price:3.99}]);
]]>
</mx:Script>
</mx:Application>
But unfortunately it doesn't. The issue is that the numeric stepper is in a vbox and the datagrid can't get at it's value.
Here's an ugly solution. The + 0.05 are to deal with rounding errors that occur.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:DataGrid dataProvider="{products}" editable="true">
<mx:columns>
<mx:DataGridColumn width="100" headerText="Product" dataField="description" editable="false" />
<mx:DataGridColumn width="60" headerText="Price" textAlign="right" editorDataField="value" dataField="price">
<mx:itemEditor>
<mx:Component>
<mx:NumericStepper xmlns:mx="http://www.adobe.com/2006/mxml" stepSize="0.01" minimum="0.01" maximum="100" />
</mx:Component>
</mx:itemEditor>
<mx:itemRenderer>
<mx:Component>
<mx:Label text="${Math.floor(data.price)}.{Math.floor((data.price-Math.floor(data.price))*10+0.05)}{Math.floor((data.price*10-Math.floor(data.price*10))*10+0.05)}" />
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var products:ArrayCollection = new ArrayCollection([{description:"Milk", price:1.99}, {description:"Bread", price:1.50}, {description:"Honey", price:3.99}]);
]]>
</mx:Script>
</mx:Application>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:DataGrid dataProvider="{products}" editable="true">
<mx:columns>
<mx:DataGridColumn width="100" headerText="Product" dataField="description" editable="false" />
<mx:DataGridColumn width="60" headerText="Price" textAlign="right" editorDataField="value" dataField="price">
<mx:itemEditor>
<mx:Component>
<mx:NumericStepper xmlns:mx="http://www.adobe.com/2006/mxml" stepSize="0.01" minimum="0.01" maximum="100" />
</mx:Component>
</mx:itemEditor>
<mx:itemRenderer>
<mx:Component>
<mx:Label text="${Math.floor(data.price)}.{Math.floor((data.price-Math.floor(data.price))*10+0.05)}{Math.floor((data.price*10-Math.floor(data.price*10))*10+0.05)}" />
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var products:ArrayCollection = new ArrayCollection([{description:"Milk", price:1.99}, {description:"Bread", price:1.50}, {description:"Honey", price:3.99}]);
]]>
</mx:Script>
</mx:Application>
Here's a better solution but it needs to use an actionscript component.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:DataGrid dataProvider="{products}" editable="true">
<mx:columns>
<mx:DataGridColumn width="100" headerText="Product" dataField="description" editable="false" />
<mx:DataGridColumn width="60" headerText="Price" textAlign="right" dataField="price" editorDataField="value" itemRenderer="Money">
<mx:itemEditor>
<mx:Component>
<mx:NumericStepper xmlns:mx="http://www.adobe.com/2006/mxml" stepSize="0.01" minimum="0.01" maximum="100" />
</mx:Component>
</mx:itemEditor>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var products:ArrayCollection = new ArrayCollection([{description:"Milk", price:1.99}, {description:"Bread", price:1.50}, {description:"Honey", price:3.99}]);
]]>
</mx:Script>
</mx:Application>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:DataGrid dataProvider="{products}" editable="true">
<mx:columns>
<mx:DataGridColumn width="100" headerText="Product" dataField="description" editable="false" />
<mx:DataGridColumn width="60" headerText="Price" textAlign="right" dataField="price" editorDataField="value" itemRenderer="Money">
<mx:itemEditor>
<mx:Component>
<mx:NumericStepper xmlns:mx="http://www.adobe.com/2006/mxml" stepSize="0.01" minimum="0.01" maximum="100" />
</mx:Component>
</mx:itemEditor>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable] private var products:ArrayCollection = new ArrayCollection([{description:"Milk", price:1.99}, {description:"Bread", price:1.50}, {description:"Honey", price:3.99}]);
]]>
</mx:Script>
</mx:Application>
And the file Money.as:
package {
import mx.controls.Text;
import mx.formatters.CurrencyFormatter
public class Money extends Text
{
override public function set data(value:Object):void {
super.data = value;
var cf:CurrencyFormatter = new CurrencyFormatter;
cf.currencySymbol = "$";
cf.precision = 2;
if (value != null) {
this.text = cf.format(value.price);
}
super.invalidateDisplayList();
}
}
}
import mx.controls.Text;
import mx.formatters.CurrencyFormatter
public class Money extends Text
{
override public function set data(value:Object):void {
super.data = value;
var cf:CurrencyFormatter = new CurrencyFormatter;
cf.currencySymbol = "$";
cf.precision = 2;
if (value != null) {
this.text = cf.format(value.price);
}
super.invalidateDisplayList();
}
}
}
While this works well there should be a more elegant solution. Anyone know how this can be done in a single MXML file?
Check it out - http://sethonflex.blogspot.com/2007/07/im-back-on-...