After changing my OS's decimal separator as explained here:
( http://blogmines.com/blog/2010/03/11/how-to-change-the-decimal-separator-in-excel-2010/ ), I want to display a number in Flex that uses a comma for both the thousands separator and the decimal separator. Sounds simple enough, right?
I tried using three different NumberFormatters offered by Flex. Along the way, I learned that two of them didn't play well with others in the same class, even if using fully qualified class paths when declaring the variables, so I had to split them up into three classes, like so:
NF1 - spark.formatters.NumberFormatter
package dstrube
{
import flash.globalization.NumberParseResult;
import spark.formatters.NumberFormatter;
public class NF1
{
public static function get(value:String):String{
var nf1:NumberFormatter = new NumberFormatter();
var result:NumberParseResult = nf1.parse(value);
return nf1.format(result.value);
}
}
}
NF2 - flash.globalization.NumberFormatter
package dstrube
{
import flash.globalization.NumberParseResult;
import flash.globalization.NumberFormatter;
public class NF2
{
public static function get(value:String):String{
var nf2:NumberFormatter = new NumberFormatter("");// LocaleID.DEFAULT = same outcome as without
nf2.fractionalDigits = 2; //= same outcome as without
nf2.trailingZeros = true;
var result:NumberParseResult = nf2.parse(value);
//nf2.parseNumber(value); = NaN
return nf2.formatNumber(result.value)
}
}
}
NF3 - mx.formatters.NumberFormatter (deprecated)
package dstrube
{
//import mx.formatters.NumberBaseRoundType;
import mx.formatters.NumberFormatter;
public class NF3
{
public static function get(value:String):String{
var nf3:NumberFormatter = new NumberFormatter();
//nf3.rounding = NumberBaseRoundType.NEAREST; //no effect in this case
return nf3.format(value);
}
}
}
and finally, the main
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
creationComplete="init()"
>
<fx:Script>
<![CDATA[
import dstrube.NF1;
import dstrube.NF2;
import dstrube.NF3;
[Bindable]
public var s:String = "";
protected function init():void{
var value:String = "5558049.90360013";
s = "spark.formatters.NumberFormatter = " + NF1.get(value); //5,558,049.90
s += "\n flash.globalization.NumberFormatter = " + NF2.get(value);//5,558,049,00
s += "\n mx.formatters.NumberFormatter = " + NF3.get(value); //5,558,049.90360013
}
]]>
</fx:Script>
<s:TextArea id="textArea" text="{s}" width="100%" height="100%" />
</s:Application>
The smartest of the three NumberFormatters is flash.globalization.NumberFormatter for recognizing decimal separator, but it rounds incorrectly, showing 5,558,049,00 instead of 5,558,049,90
Any ideas?
You can either:
Explicitly setting the formatter's properties will give you the
output you require.
Set the formatter to use the default locale.
[Bindable] protected var formatted:String;
protected function init(event:FlexEvent):void
{
var formatter:NumberFormatter = new NumberFormatter();
// Option 1 set explicitly
formatter.decimalSeparator = ",";
formatter.fractionalDigits = 2;
formatter.trailingZeros = true;
// Option 2 set default locale to be the locale
formatter.setStyle("locale", LocaleID.DEFAULT);
formatted = formatter.format("5558049.90360013");
}
]]>
</fx:Script>
<s:Label text="{formatted}" />
The output is "5,558,049,90".
This way will display whatever the decimal separator is set to be in the OS's settings.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
initialize="init(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.formatters.NumberFormatter;
import flash.globalization.NumberFormatter;
[Bindable] protected var formatted:String;
protected function init(event:FlexEvent):void
{
var formatter:spark.formatters.NumberFormatter = new spark.formatters.NumberFormatter();
var nf2:flash.globalization.NumberFormatter = new flash.globalization.NumberFormatter("");
formatter.decimalSeparator = nf2.decimalSeparator;
formatter.fractionalDigits = 2;
formatter.trailingZeros = true;
formatted = formatter.format("5558049.90360013");
}
]]>
</fx:Script>
<s:Label text="{formatted}" />
</s:Application>
Related
I had a code like this
var str:string = "GeoCode: 3";
in this code I want ":" to be in bold.
How can I do that and this should be done in spark
Please help me
Thanks!
The simplest approach is to use TextFlowUtil.importFromString() and assign the resulting TextFlow object to a RichText component, like this:
<s:RichText id="textDisplay"/>
textDisplay.textFlow =
TextFlowUtil.importFromString('GeoCode<span fontWeight="bold">:</span> 3');
If you'd like to keep your original Strings intact, you can do a replace on them to add the span:
var str:String = "GeoCode: 3";
str = str.replace(/:/, '<span fontWeight="bold">:</span>');
textDisplay.textFlow = TextFlowUtil.importFromString(str);
I would do something like this:
The text property of the component is splitted into parts by means of ":" symbol. Then each part is added into a HGroup like a Label. Colons are added bold.
//Application
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600" xmlns:com="com.*">
<s:VGroup left="20" top="20">
<com:GeoLabel text="GeoCode: 3"/>
<com:GeoLabel text="GeoCode: 5: Some Info: 123"/>
</s:VGroup>
</s:Application>
//GeoLabel component
<?xml version="1.0" encoding="utf-8"?>
<s:HGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="120" height="25" gap="0">
<fx:Script>
<![CDATA[
import spark.components.Label;
private var _text:String;
public function get text():String
{
return _text;
}
public function set text(value:String):void
{
_text = value;
createMembers();
}
private function insertLabel(str:String, bold:Boolean):void
{
var la:Label = new Label();
la.text = str;
if (bold)
la.setStyle("fontWeight", "bold");
this.addElement(la);
}
private function createMembers():void
{
this.removeAllElements();
var arr:Array = text.split(":");
for (var i:int = 0; i < arr.length; i++)
{
if (i != 0)
insertLabel(":", true);
insertLabel(arr[i], false);
}
}
]]>
</fx:Script>
</s:HGroup>
I want to make an App using SplitViewNavigator container which contains List of cities in left view and Detail about the city in right view, In right view there is a text input through I get Name of city and store in a SQLite Database, and that name should be added to list in left view from SQLite Database I got started with flowing code in Main.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
applicationDPI="160"
initialize="application1_initializeHandler(event)">
<fx:Script>
<![CDATA[
import model.DataModel;
import mx.events.FlexEvent;
import valueobject.CityValueObject;
import utillities.CityUtils;
public var sqlConnection:SQLConnection;
protected var statement:SQLStatement;
protected function application1_initializeHandler(event:FlexEvent):void
{
sqlConnection = new SQLConnection();
sqlConnection.open(File.applicationStorageDirectory.resolvePath("cityDB.db"), SQLMode.CREATE);
statement.sqlConnection = sqlConnection; // Here error occurs saying that Error #1009: Cannot access a property or method of a null object reference.
statement.text = "CREATE TABLE IF NOT EXISTS CITYNAME (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"nameofcity TEXT)";
statement.execute();
DataModel.getInstance().connection = sqlConnection;
CityUtils.getAllCities();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:SplitViewNavigator id="svn" width="100%" height="100%">
<s:ViewNavigator width="30%" height="100%" id="list_of_cities" firstView="views.ListOfCities"/>
<s:ViewNavigator width="70%" height="100%" id="display_contents" firstView="views.DisplayContents"/>
</s:SplitViewNavigator>
My model.DataModel is an action script class:
package model
{
import flash.data.SQLConnection;
import mx.collections.ArrayCollection;
[Bindable]
public class DataModel
{
public var connection:SQLConnection;
public var cityList:ArrayCollection = new ArrayCollection();
public var logs:String="Application Logs........\n";
public static var _instance:DataModel;
public function DataModel()
{
}
public static function getInstance():DataModel
{
if(_instance == null)
{
_instance = new DataModel();
}
return _instance;
}
}
}
My valueobject.CityValueObject class is:
package valueobject
{
[Bindable]
public class CityValueObject
{
public var id:uint;
public var nameofcity:String;
}}
And My uttillities.CityUtils class is ::
package utillities
{
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import model.DataModel;
import mx.collections.Sort;
import mx.collections.SortField;
import valueobject.CityValueObject;
public class CityUtils
{
public static function getAllCities():void
{
var contactListStatement:SQLStatement = new SQLStatement();
contactListStatement.sqlConnection = DataModel.getInstance().connection;
contactListStatement.text = "SELECT * FROM CITYNAME";
contactListStatement.execute();
var result:SQLResult = contactListStatement.getResult();
if( result.data!=null)
{
DataModel.getInstance().cityList.removeAll();
for(var count:uint=0;count<result.data.length;count++)
{
var cityVO:CityValueObject = new CityValueObject();
cityVO.id = result.data[count].id;
cityVO.nameofcity = result.data[count].city;
DataModel.getInstance().cityList.addItem(cityVO);
}
}
sortData();
}
public static function sortData():void
{
var dataSortField:SortField = new SortField();
dataSortField.name = "cityName";
dataSortField.numeric = false;
/* Create the Sort object and add the SortField object created earlier to the array of fields to sort on. */
var numericDataSort:Sort = new Sort();
numericDataSort.fields = [dataSortField];
/* Set the ArrayCollection object's sort property to our custom sort, and refresh the ArrayCollection. */
DataModel.getInstance().cityList.sort = numericDataSort;
DataModel.getInstance().cityList.refresh();
}
public static function updateLog(newLog:String):void
{
DataModel.getInstance().logs += new Date().time+" :-> "+newLog+"\n";
}
}
}
My left containing list of cities is :
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Cities"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import model.DataModel;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.events.IndexChangedEvent;
import spark.components.SplitViewNavigator;
import spark.components.ViewNavigator;
import spark.transitions.ViewTransitionBase;
protected function myList_changeHandler():void {
// Create a reference to the SplitViewNavigator.
var splitNavigator:SplitViewNavigator = navigator.parentNavigator as SplitViewNavigator;
// Create a reference to the ViewNavigator for the Detail frame.
var detailNavigator:ViewNavigator = splitNavigator.getViewNavigatorAt(1) as ViewNavigator;
detailNavigator.transitionsEnabled = false;
// Change the view of the Detail frame based on the selected List item.
detailNavigator.pushView(DisplayContents, list_of_cities.selectedItem);
}
]]>
</fx:Script>
<s:VGroup width="100%" height="100%">
<s:List id="list_of_cities" height="100%" width="100%" change="myList_changeHandler();"
dataProvider="{DataModel.getInstance().cityList}" labelField="nameofcity">
</s:List>
</s:VGroup>
and in last my Display Detail about city is simply like this :
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Detail About City"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:actionContent>
<s:CalloutButton id="add_call_out_button" label="Add City" verticalPosition="after"
icon="#Embed('assets/add.png')" calloutDestructionPolicy="never">
<!-- layout the callout content here -->
<s:calloutLayout>
<s:VerticalLayout paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10" horizontalAlign="center" gap="5"/>
</s:calloutLayout>
<s:calloutContent>
<s:TextInput id="city_name_input" prompt="Enter City Name" text="Sydney"/>
<s:HGroup gap="40">
<s:Button id="add_city_name" label="Add City" width="150" height="40" click="add_city_name_clickHandler()"/>
<s:CheckBox id="preferred_cbox" label="Preferred" height="40" />
</s:HGroup>
</s:calloutContent>
</s:CalloutButton>
<s:Button id="remove_city_name" label="Remove" width="120" height="40"
click="remove_city_name_clickHandler()" icon="#Embed('assets/delete.png')"/>
</s:actionContent>
<s:Label id="nameSomeThing" text="{data.Description}"/>
<fx:Script>
<![CDATA[
import model.DataModel;
import spark.components.SplitViewNavigator;
import spark.components.ViewNavigator;
protected function add_city_name_clickHandler():void
{
var sqlStatement:SQLStatement = new SQLStatement();
sqlStatement.sqlConnection = DataModel.getInstance().connection;
sqlStatement.text = "INSERT INTO CITYNAME (nameofcity)" +
"VALUES(:nameofcity)";
sqlStatement.parameters[":nameofcity"] = city_name_input.text;
sqlStatement.execute();
var splitNavigator:SplitViewNavigator = navigator.parentNavigator as SplitViewNavigator;
// Create a reference to the ViewNavigator for the Detail frame.
var detailNavigator:ViewNavigator = splitNavigator.getViewNavigatorAt(1) as ViewNavigator;
detailNavigator.transitionsEnabled = false;
// Change the view of the Detail frame based on the selected List item.
detailNavigator.popToFirstView();
}
protected function remove_city_name_clickHandler():void
{
// TODO Auto-generated method stub
}
]]>
</fx:Script>
the above view(Display Detail) is still in development but at this stage I was Trying to add City Name to list of cities by getting name from city name input text input but at:
statement.sqlConnection = sqlConnection; // Here error occurs saying that Error #1009: Cannot access a property or method of a null object reference.
Iget that error and not be able to go ahead.
Can any one please give me the way to solve my this problem by my code givien above or suggest me an other way to meet my needs by this App Thanks in Advance...
As the error message says, statement is null.
I don't see any code that would initialize it.
You need:
statement = new SQLStament();
(And I don't see any reason why this variable would need to be outside the application1_initializeHandler function.)
In my Flex 4.6 web application I use mainly spark components, but there is also an mx-component - a PopUpButton extended by me (the source code is below).
Users report problems with that button, but I can't reproduce any - since weeks.
I've tried replacing mx:Menu attached to it by a s:List but it hasn't changed anything. I suspect there is a "null pointer exception" or some other failure, that I don't hit when testing myself...
My question is: why does Flash Builder reports warning about my custom button as if its methods would be private or not present?
Can anybody please spot the reason?
My main App.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:comps="*">
<fx:Script>
<![CDATA[
_auxBtn.update(obj.aux);
......
_auxBtn.disable();
]]>
</fx:Script>
<comps:AuxButton id="_auxBtn" enabled.normal="false" enabled.ingame="false" aux="handleAux(event)" />
My custom button AuxButton.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:PopUpButton
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
popUp="{_list}"
initialize="init(event)">
<fx:Metadata>
[Event(name="aux", type="PrefEvent")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.utils.ObjectUtil;
import spark.components.List;
private const EXACT:String = 'Своя игра';
private const REVEAL:String = 'Показать';
private var _str:String;
[Bindable]
private var _data:ArrayCollection = new ArrayCollection();
[Bindable]
private var _list:List = new List();
private function init(event:FlexEvent):void {
_list.dataProvider = _data;
_list.addEventListener('click', handleList);
addEventListener('click', handleClick);
}
public function update(aux:Array):void {
var found:Boolean;
// nothing has changed
if (ObjectUtil.compare(_data.source, aux, 0) == 0)
return;
if (aux == null || aux.length == 0) {
disable();
return;
}
_data.removeAll();
for each (var obj:Object in aux) {
_data.addItem(obj);
if (!_str) {
if (EXACT == obj['label']) {
_str = obj['event'];
label = obj['label'];
found = true;
} else if (REVEAL == obj['label']) {
_str = obj['event'];
label = obj['label'];
found = true;
}
} else if (_str == obj['event']) {
found = true;
}
}
if (!found) {
_str = _data[0].event;
label = _data[0].label;
}
enabled = true;
}
private function handleList(event:MouseEvent):void {
var index:int = _list.selectedIndex;
if (index >= 0 && index < _data.length) {
_str = _data[index].event;
label = _data[index].label;
}
close();
}
private function handleClick(event:MouseEvent):void {
dispatchEvent(new PrefEvent(PrefEvent.AUX, _str));
disable();
}
public function disable():void {
_data.removeAll();
enabled = false;
_str = null;
label = '';
}
]]>
</fx:Script>
</mx:PopUpButton>
Don't worry about Flash Builder warnings, sometimes it has difficulties analyzing custom mx extended code (even spark sometimes!).
If it runs it's okay, warnings will eventually go away after a clean or a FB restart.
You can also try to reproduce same feature using a mix of spark component, depending on a feature, it is maybe the best thing to do.
Stay assured, I pasted your code in my Flash Builder (and removed the PrefEvent), there are no warnings at all on my computer :)
For the error you users are reporting, you should give us more detail so we can try to help.
Cheers
I'd be extremely grateful if somebody could help me, or point me in the right direction.
I've been trying to get an adobe air application start in system tray, so far I've used this snippet: http://www.swamicharan.com/blog/air/minimizing-an-air-app-to-systemtray/ which works as described, however no matter what I do I can't seem to make it start, minimized, in the system tray. This is the code I have so far:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="300" height="100" creationComplete="initApp()" layout="horizontal">
<fx:Script>
<![CDATA[
import mx.events.CloseEvent;
private var trayIcon:BitmapData;
public function initApp():void{
loadTrayIcon();
this.addEventListener(Event.CLOSING, minToTray);
}
public function loadTrayIcon():void{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, readyToTray);
loader.load(new URLRequest("assets/icon.PNG"));
}
private function minToTray(event:Event):void{
event.preventDefault();
dock();
}
public function readyToTray(event:Event):void{
trayIcon = event.target.content.bitmapData;
var myMenu:NativeMenu = new NativeMenu();
var openItem:NativeMenuItem = new NativeMenuItem("Options");
var closeItem:NativeMenuItem = new NativeMenuItem("Close");
openItem.addEventListener(Event.SELECT, unDock);
closeItem.addEventListener(Event.SELECT, closeApp);
myMenu.addItem(openItem);
myMenu.addItem(new NativeMenuItem("", true));
myMenu.addItem(closeItem);
if(NativeApplication.supportsSystemTrayIcon){
SystemTrayIcon(NativeApplication.nativeApplication.icon).tooltip = "Notifier";
SystemTrayIcon(NativeApplication.nativeApplication.icon).
addEventListener(MouseEvent.CLICK, unDock);
stage.nativeWindow.addEventListener(
NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, winMinimized);
SystemTrayIcon(NativeApplication.nativeApplication.icon).menu = myMenu;
}
}
private function winMinimized(displayStateEvent:NativeWindowDisplayStateEvent):void{
if(displayStateEvent.afterDisplayState == NativeWindowDisplayState.MINIMIZED){
displayStateEvent.preventDefault();
dock();
}
}
public function dock():void{
stage.nativeWindow.visible = false;
NativeApplication.nativeApplication.icon.bitmaps = [trayIcon];
}
public function unDock(event:Event):void{
stage.nativeWindow.visible = true;
stage.nativeWindow.orderToFront();
NativeApplication.nativeApplication.icon.bitmaps = [];
}
private function closeApp(event:Event):void{
stage.nativeWindow.close();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
s|WindowedApplication
{
skinClass:ClassReference("spark.skins.spark.SparkChromeWindowedApplicationSkin");
background-color:#999999;
background-alpha:"0.7";
}
</fx:Style>
<s:Label text="Hello AIR"/>
</mx:WindowedApplication>
Many Thanks.
I think you'll manage by calling dock() at the end of readyToTray(event:Event).
To make sure your initialWindow is invisible when it launches you can set it's visible property to false in the application descriptor file.
I'm facing a strange issue with flex and validator.
Here is the code:
TestMain.xml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.validators.StringValidator;
import utils.ValidableProperty;
[Bindable] public var nameID:ValidableProperty;
public function start():void {
var nameIDValidator:StringValidator = new StringValidator();
nameIDValidator.required = true;
nameIDValidator.maxLength = 35;
nameID = new ValidableProperty(nameIDValidator);
nameID.validate();
}
]]>
</fx:Script>
<s:applicationComplete>
start();
</s:applicationComplete>
<s:minHeight>600</s:minHeight>
<s:minWidth>955</s:minWidth>
<mx:Form color="0x323232" paddingTop="0">
<s:Label text="See strange behavior of errorString during validator operation with validate."/>
<mx:FormItem label="Name">
<mx:TextInput id="nameInput" width="300" errorString="#{nameID.errorMessage}" text="#{nameID.value}"/>
</mx:FormItem>
</mx:Form>
ValidableProperty.as
package utils
{
import flash.events.EventDispatcher;
import mx.events.PropertyChangeEvent;
import mx.events.ValidationResultEvent;
import mx.validators.Validator;
public class ValidableProperty extends EventDispatcher
{
[Bindable]
public var value:Object;
private var validator:Validator;
[Bindable]
public var isValid:Boolean;
[Bindable]
public var errorMessage:String;
private var statusChangeHandler:Function;
public function ValidableProperty(validator:Validator, statusChangeHandler:Function=null,
target:IEventDispatcher=null) {
super(target);
this.validator = validator;
this.statusChangeHandler = statusChangeHandler;
this.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler);
}
private function propertyChangeHandler(evt:PropertyChangeEvent):void {
if (evt.property == "value") {
this.validate();
}
}
public function validate():void {
var result:ValidationResultEvent = this.validator.validate(this.value);
this.isValid = (result.type == ValidationResultEvent.VALID);
if (isValid) {
this.errorMessage = null;
}
else {
this.errorMessage = result.message;
}
if (statusChangeHandler != null)
statusChangeHandler();
}
public function set required(required:Boolean):void {
if (validator == null)
return;
validator.required = required;
}
}
}
When you execute this simple code, when writing a value, for example "A", the errorMessage value "this field is required" will disappear but the red color on the inputtext border will still be there with the blue color.
When deleting the A value, this time the blue color will be there with the red one (cannot reproduce all the time) and the error message "this field is required".
What am I missing here? Is it a bug in flex? We cannot have both of red and blue colors on the textinput border.
I am using Eclipse with Flex SDK 4.5.0 (build 20967)
This is not a bug in Flex. This is a bug with how you're coding it all. If you were to follow the example in the documentation, it would work.
<?xml version="1.0" encoding="utf-8"?>
<!-- Simple example to demonstrate StringValidator. -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<mx:StringValidator source="{nameInput}" property="text"
tooShortError="This string is shorter than the minimum length of 4. "
tooLongError="This string is longer than the maximum allowed length of 35."
minLength="4" maxLength="35"/>
</fx:Declarations>
<s:Form>
<s:FormItem label="Name">
<s:TextInput id="nameInput" width="300" text="{nameID.value}"/>
</s:FormItem>
</s:Form>
</s:Application>
I finally resolve this. I was using mx:TextInput instead of s:TextInput. Thanks J_A_X for your suggestion !