Flex line chart zooming - apache-flex

I have a problem zooming in on a line chart with a dateTimeAxis as horizontal axis. I want to zoom in and out, by setting the minimum and the maximum attribute of the dateTimeAxis with a slider. The date labels change as should, but the lines disappear as I set the minimum or the maximum.
Here's a part of the code I have:
private function updateBoundariesFromSlider():void
{
leftBoundary = slider.values[0];
rightBoundary = slider.values[1];
updateMainData();
}
private function updateMainData():void
{
dateAxis.minimum = new Date(leftBoundary);
dateAxis.maximum = new Date(rightBoundary);
}
public function setChartData( data:XML, shown:Array, minDate:Date, maxDate:Date ):void
{
globalLeftBoundary = minDate.getTime();
globalRightBoundary = maxDate.getTime();
leftBoundary = minDate.getTime();
rightBoundary = maxDate.getTime();
for each( var s:String in shown )
{
var localXML:XMLList = data.track.(type == s);
// Create the new series and set its properties.
var localSeries:LineSeries = new LineSeries();
localSeries.dataProvider = localXML;
localSeries.yField = "value";
localSeries.xField = "time";
localSeries.displayName = s;
mySeries.push(localSeries);
}
hAxis = new DateTimeAxis();
hAxis.dataUnits = "minutes";
hAxis.dataInterval = 1;
hAxis.labelFunction = showLabel;
hAxis.alignLabelsToUnits = true;
hAxis.parseFunction = createDate;
//hAxis.minimum = new Date( leftBoundary );
//hAxis.maximum = new Date( rightBoundary );
Alert.show( (new Date( leftBoundary )).toString());
dateAxis = hAxis;
}
private function createDate(s:String):Date {
var dateTime:Array = s.split(" ");
var date:Array = dateTime[0].split("-");
var time:Array = dateTime[1].split(":");
var newDate:Date = new Date(date[0],date[1],date[2],time[0],time[1],time[2]);
return newDate;
}
<mx:LineChart id="lineChart" left="10" top="10" bottom="47" right="10" series="{mySeries}" horizontalAxis="{dateAxis}" />
<mx:Legend dataProvider="{lineChart}" height="23" bottom="16" left="10" id="legend" width="100"/>
<flexlib:HSlider id="slider" height="25"
allowTrackClick="true" allowThumbOverlap="false"
liveDragging="true" change="updateBoundariesFromSlider()"
showDataTip="false"
showTrackHighlight="true"
thumbCount="2" snapInterval="0"
values="{[leftBoundary, rightBoundary]}"
minimum="{globalLeftBoundary}" maximum="{globalRightBoundary}"
right="50" left="198" y="155"
/>

I had an application with a similar chart zooming requirement, and I found that filtering the charts data provider based of the upper and lower bounds looks much better than modifying the minimum and maximum on the charts horizontal axis. Here is a simple, working example (Flex 3, UPDATE 6-29-10: Modified example to use XMLListCollection):
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" initialize="{init()}"
>
<mx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.collections.ArrayCollection;
public static const MIN_DATE:Number = 1900;
public static const MAX_DATE:Number = 2010;
public var mainData:XML = function():XML{
var ret:XML = <data></data>;
for(var i:Number = MIN_DATE;
i <= MAX_DATE; i++)
{
ret.appendChild(
XMLList(
'<datum><date>'
+ i +
'</date><value>'
+ Math.random() +
'</value></datum>'
)
);
}
return ret;
}();
[Bindable]
public var selectedData:XMLListCollection =
new XMLListCollection(mainData.child('datum'));
public function init():void
{
selectedData.filterFunction = filterData;
selectedData.refresh();
}
private function filterData(o:Object):Boolean
{
return o.date >= minStepper.value && o.date <= maxStepper.value;
}
]]>
</mx:Script>
<mx:LineChart
id="lineChart"
dataProvider="{selectedData}"
>
<mx:horizontalAxis>
<mx:DateTimeAxis
id="hAxis"
parseFunction="{
function(obj:Object):Date
{
return new Date(obj.toString(), 1);
}
}"
/>
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:LinearAxis
id="vAxis"
/>
</mx:verticalAxis>
<mx:series>
<mx:LineSeries
xField="date"
yField="value"
/>
</mx:series>
</mx:LineChart>
<mx:HBox>
<mx:NumericStepper
id="minStepper"
minimum="{MIN_DATE}"
maximum="{Math.min(maxStepper.value - 1, MAX_DATE)}"
change="{selectedData.refresh();}"
value="{MIN_DATE}"
/>
<mx:NumericStepper id="maxStepper"
maximum="{MAX_DATE}"
minimum="{Math.max(minStepper.value + 1, MIN_DATE)}"
change="{selectedData.refresh();}"
value="{MAX_DATE}"
/>
</mx:HBox>

localSeries.filterData = false;
or
<mx:LineSeries filterData="false" />

Related

How to get a view to read data

I need to convert a lot of stuff in my profession - so I'm building a conversion tool for my phone with some of the conversions I use a lot.
Now, I want to be able to build this properly. So far, here's my code:
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Length">
<fx:Script>
<![CDATA[
protected function button1_clickHandler(event:MouseEvent):void
{
var Result:String;
var Finish:Number;
var Start:Number = parseFloat(Input.text);
Finish = Start * convert.selectedItem.data;
Result = String(Finish);
answer.text = Result;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:TextInput id="Input" x="20" y="46"/>
<s:SpinnerListContainer x="140" y="122" width="200" height="200">
<s:SpinnerList id="convert" height="100%" width="100%" labelField="label" selectedIndex="1">
<s:ArrayList>
<fx:Object label="km to mi" data="0.62137119224"></fx:Object>
<fx:Object label="km to yd" data="1093.6132983 "></fx:Object>
<fx:Object label="km to ft" data="3280.839895"></fx:Object>
<fx:Object label="km to in" data="39370.07874"></fx:Object>
<fx:Object label="km to m" data="1000"></fx:Object>
<fx:Object label="km to cm" data="100000"></fx:Object>
<fx:Object label="km to mm" data="1000000"></fx:Object>
</s:ArrayList>
</s:SpinnerList>
</s:SpinnerListContainer>
<s:Label id="answer" x="66" y="533" width="348" text="Answer"/>
<s:Button x="66" y="377" width="338" click="button1_clickHandler(event)" label="Button"/>
</View>
As you can see, I'm going to run into some problems with this:
1) Everything is hard-coded, and if I want to add, remove or change the elements in the array, it's going to be a bit of a pain.
2) I have a view that is essentially the same for my volume and weight conversions. With the same problem.
What I'd like to do, but I'm having some trouble understanding, is getting all that hard-coded stuff in one place and having the same view show it based on my previous view which is just a plain, hard-coded list.
I'm thinking of something like an xml sheet, and adding a category = "length" or category = "weight" element to the objects, so that I can show the category from the xml in the List, then when I click "length" it reads the label + data from this list. Is that a good solution? And how exactly do I get the selectedItem to remember which part of the xml list the view should be populated from?
Would it be better to have several xml files? But that still would mean I have to update a whole bunch of places when I need it.
Basically, I need assistance with:
So - Now the question is two-fold:
1) How to keep a connection to xml/db open across multiple views?
2) How to populate the end-view from information from the db?
Thanks for the advice and help.
I just finished an app about a month ago that's uses what I think would be the most "Flex"ible solution. (hehehehe)
(First Answer:)
If you're into/familiar with (good) database design, you could design a SQLite db that allows you to add to & modify all the data you're working with.
(If not, I'd recommend either:
http://www.amazon.com/The-Art-SQL-Stephane-Faroult/dp/0596008945/ref=sr_1_14?s=books&ie=UTF8&qid=1336262973&sr=1-14
or
http://www.amazon.com/SQL-Demystified-Andrew-Oppel/dp/0072262249/ref=sr_1_1?s=books&ie=UTF8&qid=1336263052&sr=1-1
...this post is going to take longer than I anticipated! hehehhehee ;P =D )
Basically what it'd be is:
Tables for categories (e.g. Volume, Length, etc.) and another for specific name/value pairs ("km to mi" = 0.62137119224 [each in separate columns]) with a category id column to.
Then on your home page you have your init() create an DAO (Data Access Object [research if you don't know already]) for the categories table, then fetch the categories into an ArrayCollection and set it as the dataProvider on your category list (on the home view -- or wherever).
(Second Answer:)
Have your change handler for the category list grab the selectedItem and pass it as the second param in navigator.pushView(). That will send the VO (Value Object -- another to research if you don't know it) to the new View as the "data" property.
In the "pushed view," use your creationComplete handler to "catch" (use) the data variable, which will contain the category's name and id. Create a new DAO for the values table and then use the data.id value to load all your values with that category id. Then set your new ArrayCollection as the dataProvider of your value list.
Then create another View for choosing values to edit in the same way. Except the final view in that "flow" would be a form with inputs for category, name, & value (with save & cancel buttons) that would get populated with the appropriate data too. (Note: use a category DAO to get the names of the categories so that the category names & ids are available if you change a category.
...Then it's just a matter of implementing insert & update methods on that View and the SQL & methods needed in each DAO.
You can use Lita (http://www.dehats.com/drupal/?q=node/58) build, design, pre-populate your database.
...I may come back with some nice example code/files (if I remember)
I made some examples for those who were reading and hoped I would...
//////////////////////////////////////
//VO (Value Object)
//Category.as
//////////////////////////////////////
package dao
{
[Bindable]//Makes all public properties bindable
public class Category
{
import mx.collections.ArrayCollection;
public var id:int = -1;
public var categoryName:String;
private var categoryDao:CategoryDAO;
public function Category() {}
public function get exists():Boolean {
return this.id > -1;
}
//"Super" convenient methods
//Not really part of Value Objects / Value Object Pattern
//May actually be a bad practice if you have many VO instances,
//you have the potential for a DAO instance in each
//when only one instance could be used.
public function insert():void {
if( !categoryDao ){ categoryDao = new CategoryDAO;}
categoryDao.insert( this );
}
public function update():void {
if( !categoryDao ){ categoryDao = new CategoryDAO;}
categoryDao.update( this );
}
public function deleteRow():void {
if( !categoryDao ){ categoryDao = new CategoryDAO;}
categoryDao.deleteRow( this );
}
}
}
//////////////////////////////////////
//DAO (Data Access Object)
//CatagoryDAO.as
//////////////////////////////////////
package dao
{
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.filesystem.File;
import mx.collections.ArrayCollection;
public class CategoryDAO
{
public static var _sqlConnection:SQLConnection;
public var failed:Boolean;
public var errorMessage:*;
public function CategoryDAO() {
}
public function getAll():ArrayCollection
{
var sql:String = "SELECT * FROM categories"
+ " ORDER BY categoryName ASC";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.execute();
var result:Array = stmt.getResult().data;
if( result ){
var list:ArrayCollection = new ArrayCollection();
for (var i:int=0; i < result.length; i++){
list.addItem( buildVO( result[i] ) );
}
return list;
} else {
return null;
}
}
public function getByCategoryId(id:int):Category
{
var sql:String = "SELECT * FROM categories WHERE id=?";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.parameters[0] = id;
stmt.execute();
var result:Array = stmt.getResult().data;
if( result && result.length == 1 ){
return buildVO( result[0] );
} else {
return null;
}
}
public function insert(category:Category):void
{
var sql:String =
"INSERT INTO categories ( categoryName )" +
" VALUES ( :name )";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.parameters[":name"] = category.categoryName;
this.execute( stmt );
}
public function update(category:Category):void
{
var sql:String =
"UPDATE categories" +
" SET categoryName = :name" +
" WHERE id = :id";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.parameters[":name"] = category.categoryName;
stmt.parameters[":id"] = category.id;
this.execute( stmt );
}
public function deleteRow(category:Category):void {
var sql:String =
"DELETE FROM categories" +
" WHERE id = :id";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.parameters[":id"] = category.id;
this.execute( stmt );
}
protected function execute(stmt:SQLStatement):void {
try {
stmt.execute();
} catch(error:Error) {
this.failed = true;
this.errorMessage = error.message;
}
}
protected function buildVO(o:Object):Category
{
var category:Category = new Category();
category.id = o.id;
category.categoryName = o.categoryName;
return category;
}
public function get sqlConnection():SQLConnection
{
if (_sqlConnection) return _sqlConnection;
var file:File =
File.documentsDirectory.resolvePath(DbUtility.DB_FILE_NAME);
var fileExists:Boolean = file.exists;
_sqlConnection = new SQLConnection();
_sqlConnection.open(file);
return _sqlConnection;
}
}
}
//////////////////////////////////////
//CategoryView.mxml
//////////////////////////////////////
<?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"
xmlns:dao="dao.*"
opaqueBackground="#111111"
title="All Categorys"
creationComplete="init()">
<fx:Script>
<![CDATA[
import dao.DbUtility;
import dao.DropPoint;
import dao.Category;
import dao.CategoryDAO;
protected var dbVerifyUtil:DbUtility
protected function init():void
{
dbVerifyUtil = new DbUtility;
dbVerifyUtil.confirmDb();
if( dbVerifyUtil.dbExists() ){
var categorysDAO:CategoryDAO = new CategoryDAO;
categoryList.dataProvider = categorysDAO.getAll();
}
}
protected function categorySelected():void
{
navigator.pushView( CategoryListView,
categoryList.selectedItem );
}
protected function newCategory():void
{
navigator.pushView( EditCategoryView );
}
protected function viewCategory():void
{
navigator.pushView( CategoryListView,
categoryList.selectedItem );
}
]]>
</fx:Script>
<s:List id="categoryList"
left="10" right="10" top="10" bottom="85"
change="viewCategory()"
dataProvider="{data}"
itemRenderer="irs.CategoryIR">
</s:List>
<s:Button label="Add Category"
left="104" bottom="10" height="43"
click="newCategory()"/>
<s:Label text="Touch a category to view or edit it."
y="326" horizontalCenter="0"/>
</s:View>
//////////////////////////////////////
//CategoryListView.mxml
//////////////////////////////////////
<?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"
xmlns:dao="dao.*"
creationComplete="init()">
<fx:Script>
<![CDATA[
import dao.Value;//Value VO
import dao.Category;//Category VO
import mx.collections.ArrayCollection;
import spark.events.IndexChangeEvent;
private var category:Category;
protected function init():void
{
var category:Category = data as Category;
listValues.dataProvider =
valueDAO.getByCategoryId(
category.id );
}
protected function editValue():void
{
navigator.pushView( EditValueView,
listValues.selectedItem );
}
protected function editCategory():void
{
navigator.pushView( EditCategoryView, category );
}
]]>
</fx:Script>
<s:viewMenuItems>
<s:ViewMenuItem label="Edit Category"
click="editCategory()"
icon="#Embed('assets/edit.png')"/>
<s:ViewMenuItem label="Add Location"
click="addLocation()"
icon="#Embed('assets/plus.png')"/>
</s:viewMenuItems>
<s:List id="listValues"
left="10" right="10" top="10" bottom="60"
labelFunction="labelValue"
change="editValue()"
itemRenderer="irs.ValueIR">
</s:List>
</s:View>
Have you looked at using resource bundles? Or LSOs?
When persisting Flex data, you have 4 main options.
Relational Databases (seems like overkill here)
XML (which you already seem comfortable with)
Resource Bundles
Local Shared Objects
The LSO example, linked above (#4), gives a potential solution to your question:
... how exactly do I get the selectedItem to remember which part of the xml list the view should be populated from?
snippet:
public function initApp():void {
mySO = SharedObject.getLocal("mydata");
if (mySO.data.visitDate==null) {
welcomeMessage = "Hello first-timer!"
} else {
welcomeMessage = "Welcome back. You last visited on " +
getVisitDate();
}
}
private function getVisitDate():Date {
return mySO.data.visitDate;
}
private function storeDate():void {
mySO.data.visitDate = new Date();
mySO.flush();
}
private function deleteLSO():void {
// Deletes the SharedObject from the client machine.
// Next time they log in, they will be a 'first-timer'.
mySO.clear();
}
I'd recommend using either a combination of XML and LSOs or resource bundles and LSOs--where your XML/RB stores non-changing, static data and your LSO keeps track of dynamic data (view settings, etc).
Data retrieve
As I understand your problem, you don't have to keep a connection open.
Retrieve the data from your database
Parse and store the retrieved
data in a collection ideally an ArrayCollection (you don't want to
handle XML based objects, they're fine when manipulating String
values, but they instantly become a pain in the .as when you want to
perform type-conversion and advanced add and remove operations)
Generic conversion
Then, with binding as in the following sample, all you have to do is always have two conversions when you convert a value from an unit to another :
conversion into a defined unit (ideally the SI unit, as in my
example)
conversion from the SI unit to the desired unit.
Sample
<?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="400" minHeight="300">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
private var unitz:ArrayCollection = new ArrayCollection([
{
label:"Length",
units: new ArrayCollection([
{label: "meter", toSI: 1},
{label: "kilometer", toSI: 1000},
{label: "inch", toSI: 0.0254}
])
},
{
label:"Temperature",
units: new ArrayCollection([
{label: "kelvin", toSI: 1},
{label: "celsius", toSI: 274.15},
{label: "farenheit", toSI: 255.927778}
])
}
]);
private function resetFields():void
{
fromValue.text = "";
toValue.text = "";
}
private function onInputChange():void
{
var fu:Object = fromUnitCB.selectedItem;
var tu:Object = toUnitCB.selectedItem;
toValue.text = (Number(fromValue.text)*fu.toSI/tu.toSI).toString();
}
]]>
</fx:Script>
<s:HGroup width="100%" height="40">
<s:ComboBox
id="categoryCB"
dataProvider="{unitz}"
change="resetFields()"
/>
<s:ComboBox id="fromUnitCB" dataProvider="{categoryCB.selectedItem.units}"/>
<s:ComboBox id="toUnitCB" dataProvider="{categoryCB.selectedItem.units}"/>
</s:HGroup>
<s:HGroup width="100%">
<s:TextInput id="fromValue" change="onInputChange()"/>
<s:Label id="toValue"/>
</s:HGroup>
</s:Application>

Flex 3: Strange behavior when function does a simple math operation

So, in one of my modules, a variable named numDays is created by looping through some XML data and finding the maximum value of an xml field calls days. After the numDays variable is found, I use it to find the width of a canvas by doing:
wrapper.width = numDays * parentApplication.oneDay;
(oneDay is a value determined by dividing the width of the window by 14)
So, now that I know how wide the wrapper canvas is, I can start to fill it. I have four items that are going into the wrapper: 1) Role description, 2) left controller, 3) name textbox (auto suggest component), 4) right controller. The width of the role description is 30px. The left and right controllers are 20 px each. So in order to get the width of the name textbox, I have a function that does the following:
nameTextbox.width = wrapper.width - 70;
for some reason when I do this, the application doesn't load fully. It pretty much stalls out. I have 30 "projects" with 15 "positions" within each of them. the wrapper.width is describing the width of a position, so there are 450 name textboxes trying to be figured out. Is this why it's messing up?
EDIT
So, from the main application, the project module is called. From within the project module, a list is created with a datasource of "positionsAC":
<mx:List id="wholePosition" dataProvider="{positionsAC}" width="100%" height="100%" paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0" backgroundAlpha="0" verticalScrollPolicy="off" itemRenderer="modules.position" useRollOver="false" selectable="false">
Below is a c/p of the position module in it's entirety
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:components="com.hillelcoren.components.*" dataChange="allData = data as Array" layout="absolute" creationComplete="init();" horizontalScrollPolicy="off">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
[Bindable] public var positionInfo:Array;
[Bindable] public var wholePositionID:Number;
[Bindable] public var allData:Array;
[Bindable] public var positions:XML;
[Bindable] public var startOffset:Number;
[Bindable] public var numDays:Number;
[Bindable] public var role:String;
[Bindable] public var studentID:Number;
[Bindable] public var conflict:Number;
[Bindable] public var studentType:String;
[Bindable] public var showInPrinciple:Number;
[Bindable] public var positionX:Number = 0;
[Bindable] public var positionWidth:Number = 0;
[Bindable] public var sName:String = new String;
[Bindable] public var asAC:ArrayCollection = new ArrayCollection;
[Bindable] public var conflictBG:uint = 0xffffff;
[Bindable] public var roleColor:uint = 0x000000;
private function init():void
{
if (allData)
{
getInfo(allData);
setBGColor();
getPositionX();
getPositionWidth();
getRightStudents();
}
}
private function getInfo(a:Array):void
{
var tempArray:Array = new Array;
startOffset = Number(a[0]);
numDays = Number(a[1]);
positionWidth = parentApplication.oneDay * numDays;
setStudentNameW();
role = a[2];
studentID = Number(a[3]);
tempArray = parentApplication.studentsDBIDDict[String(studentID)] as Array;
conflict = Number(a[4]);
studentType = a[5];
sName = "test";
showInPrinciple = a[6];
}
private function setStudentNameW():void
{
if (numDays == 1)
{
studentName.width = 55;
studentName.x = 37;
contractLeft.visible = false;
contractRight.visible = false;
}
else if (numDays == 2)
{
Alert.show("HI");
studentName.width = 133;
}
else if (numDays == 3)
studentName.width = 230;
else if (numDays == 4)
studentName.width = 330;
if (numDays > 1)
{
studentName.x = 47;
contractLeft.visible = true;
contractRight.visible = true;
}
}
public function setBGColor():void
{
if (conflict == 1)
conflictBG = parentApplication.errorColor;
else if (conflict == 2)
conflictBG = parentApplication.okErrorColor;
else
conflictBG = 0xFFFFFF;
}
private function getPositionX():void
{
positionX = parentApplication.oneDay * startOffset - 1;
}
private function getPositionWidth():void
{
positionWidth = parentApplication.oneDay * numDays;
}
private function getRightStudents():void
{
if (studentType == "freshman")
makeASAC(parentApplication.freshmanAC);
else if (studentType == "bfa1")
makeASAC(parentApplication.bfa1AC);
else if (studentType == "bfa2")
makeASAC(parentApplication.bfa2AC);
else if (studentType == "bfa3")
makeASAC(parentApplication.bfa3AC);
else if (studentType == "mfa1")
makeASAC(parentApplication.mfa1AC);
else if (studentType == "mfa2")
makeASAC(parentApplication.mfa2AC);
else if (studentType == "mfa3")
makeASAC(parentApplication.mfa3AC);
else if (studentType == "mfaw1")
makeASAC(parentApplication.mfaw1AC);
else if (studentType == "mfaw2")
makeASAC(parentApplication.mfaw2AC);
else if (studentType == "mfaw3")
makeASAC(parentApplication.mfaw3AC);
}
private function makeASAC(students:ArrayCollection):void
{
for (var i:int = 0; i < students.length; i++)
asAC.addItem(parentApplication.getStudentName(students.getItemAt(i)));
}
private function posLength(whichSide:String, expandContract:String):void
{
if (whichSide == 'l')
{
if (expandContract == 'e')
{
if (startOffset > 0)
{
numDays++;
startOffset--;
getPositionX();
getPositionWidth();
}
}
else if (expandContract == 'c')
{
if (numDays > 1)
{
numDays--;
startOffset++;
getPositionX();
getPositionWidth();
}
}
}
else if (whichSide == 'r')
{
if (expandContract == 'e')
{
if (numDays + startOffset < parentDocument.projectLength)
{
numDays++;
getPositionX();
getPositionWidth();
}
}
else if (expandContract == 'c')
{
if (numDays > 1)
{
numDays--;
getPositionX();
getPositionWidth();
}
}
}
//parentApplication.conflicts();
}
]]>
</mx:Script>
<mx:Canvas id="positionWrapper" width="{positionWidth}" height="25" backgroundColor="#ffffff" horizontalScrollPolicy="off" borderColor="#000000" borderStyle="solid" borderThickness="1">
<mx:Text id="roleText" text="{role}" width="25" y="3" color="{roleColor}" fontSize="11" fontWeight="bold" click="parentApplication.getDictLen(parentApplication.studentsDBIDDict)" />
<mx:Canvas id="leftSide" x="25" width="22" height="100%" mouseOver="expandLeft.visible = true; contractLeft.visible = true;" mouseOut="expandLeft.visible = false; contractLeft.visible = false;" backgroundColor="{conflictBG}" horizontalScrollPolicy="off">
<mx:Image id="expandLeft" source="images/addRed.png" y="5" click="posLength('l', 'e')" mouseOver="parentApplication.switchCursor(true);" mouseOut="parentApplication.switchCursor(false);" visible="false" />
<mx:Image id="contractLeft" source="images/minusRed.png" x="10" y="5" click="posLength('l', 'c')" mouseOver="parentApplication.switchCursor(true);" mouseOut="parentApplication.switchCursor(false);" visible="false" />
</mx:Canvas>
<components:AutoComplete id="studentName" textAlign="center"
dataProvider="{asAC}"
x="47" y="3"
/>
<mx:Image id="showSNW" source="images/searchicon.png" x="{(studentName.width + studentName.x) - 12}" y="5" visible="false" mouseOver="parentApplication.switchCursor(true); studentName.enabled = false;" mouseOut="parentApplication.switchCursor(false); studentName.enabled = true; showSNW.visible = false;" />
<mx:Canvas id="rightSide" x="{positionWrapper.width - 22}" width="20" height="100%" mouseOver="expandRight.visible = true; contractRight.visible = true;" mouseOut="expandRight.visible = false; contractRight.visible = false;" backgroundColor="{conflictBG}" horizontalScrollPolicy="off">
<mx:Image id="contractRight" source="images/minusRed.png" y="5" click="posLength('r', 'c')" visible="false" mouseOver="parentApplication.switchCursor(true);" mouseOut="parentApplication.switchCursor(false);" />
<mx:Image id="expandRight" source="images/addRed.png" x="10" y="5" click="posLength('r', 'e')" visible="false" mouseOver="parentApplication.switchCursor(true);" mouseOut="parentApplication.switchCursor(false);" />
</mx:Canvas>
</mx:Canvas>
Best to get a debugger. Flash Builder 4 is a pretty decent one, and they even give out free standard licenses to
Students, faculty and staff of eligible educational institutions
Software developers who are affected by the current economic condition and are currently unemployed
Event attendees who receive a special promotional code at their event
Check this out
Also, get debugger versions of the latest Flash Player here
The free standard might take some time to come, but you can always use the free trial in the meanwhile.
When you debug, check that nameTextBox is not null.

Finding previous word boundary with enter key?

This code works great and it get the last word, but when I use enter key
it behaves erroneously and stops getting last word(s). When I comment the findPreviousWordBoundary line, it gets all text:
<fx:Script>
<![CDATA[
import flashx.textLayout.elements.ParagraphElement;
protected function togglebutton1_clickHandler(event:MouseEvent):void {
var urlLoader:URLLoader = new URLLoader();
var suggestions:Array = new Array();
var suggested:Array = new Array();
var textfields:Array = new Array();
var format:TextFormat = new TextFormat();
var currentSelection:int = -1;
mytextflow.addEventListener(KeyboardEvent.KEY_UP, suggest);
function suggest(event:KeyboardEvent):void {
suggested = [];
var activePos:int = mytextflow.selectionActivePosition
var curParagraph:ParagraphElement =
mytextflow.textFlow.findLeaf(activePos).getParagraph();
var wordBoundary:int = curParagraph.
findPreviousWordBoundary(activePos);
//var lastword:String = curParagraph.getText(wordBoundary,activePos);
}
}
]]>
</fx:Script>
<s:ToggleButton x="21" y="10"
click="togglebutton1_clickHandler(event)"/>
<s:RichEditableText
id="mytextflow"
x="111"
y="43"
width="363"
height="285"
backgroundColor="#C39191"/>
</s:Application>

Multiple downloads in flex

can someone help me?
I want to download files from the server side to client side without prompting a window to the user to download when any updates happen at server side.
Right now I am using urlstream class but first file is downloading completely rest of the files contents downloading partially.
edit
Code sample taken from other post. Warning: it's a huuuge chunk o'code.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:MyComp="client.components.*" layout="absolute" height="554" width="817"
backgroundGradientAlphas="[1.0, 0.0]"
backgroundGradientColors="[#ABA9A7, #03143B]" creationComplete="init();">
<mx:Script>
<![CDATA[
import flash.system.Capabilities;
import mx.collections.XMLListCollection;
import mx.rpc.Fault;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.events.ListEvent;
import mx.collections.ArrayCollection;
import flash.data.SQLConnection;
import flash.errors.SQLError;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.filesystem.File;
import flash.errors.SQLError;
import mx.controls.Alert;
import mx.events.CloseEvent;
import flash.net.*;
import flash.filesystem.*;
import flash.events.OutputProgressEvent;
private var urlstring:String="server path";
private var urlReq:URLRequest;
private var urlStream:URLStream;
private var fileData:ByteArray = new ByteArray();
private var sqlConnection:SQLConnection =null;
private var sql:String;
private var result:SQLResult;
private var stmt:SQLStatement=null;
private var catid:int=0;
private var testcollection:Array=new Array();
[Bindable]
private var DGArray:ArrayCollection = new ArrayCollection(testcollection);
private var number:int;
private var selection:Boolean=false;
private var timestamp:String;
private var xmlcol:XMLListCollection;
private var categoryid:int=0;
private var numbers:int;
private var index:int=0;
private var findex:int=0;
private var nupdates:int=0;
private var newfile:String="";
private var selectstream:int=1;
private var startdownload:Boolean=false;
public function init():void{
userRequest.send(null);
sqlConnection= new SQLConnection();
//create a new db-file in the application storage location
var file:File = new File("app:/E-catalog.db");
sqlConnection.addEventListener(SQLEvent.OPEN,dbOpenedHandler);
sqlConnection.addEventListener(SQLErrorEvent.ERROR,dbErrorHandler);
sqlConnection.open(file);
getData();
}
public function loaded(event:Event):void {
urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
for(var x:int=0;x<nupdates;x++){
var filename:Object=xmlcollection.getItemAt(x);
newfile=filename['pdfimage'];
writeAirFile();
}
}
public function writeAirFile():void {
/*
var obj:Object=new Object;
startdownload=true;
var file:File = File.applicationStorageDirectory.resolvePath(newfile);
fileStream = new FileStream();
fileStream.openAsync(file, FileMode.WRITE);
fileStream.writeBytes(fileData, 0, fileData.length);
fileStream.addEventListener(Event.COMPLETE,progressHandler,true,10,true);
for(var x:int=0;x<fileData.length;x++){}
startdownload=false;
fileStream.close();
*/
}
public function progressHandler(event:Event){
Alert.show("File downloading");
}
public function dbOpenedHandler(event:SQLEvent):void{}
public function dbErrorHandler(error:SQLError):void{}
public function getData():void{
sql = "SELECT STRFTIME('%Y-%m-%d %H:%M:%S',lupdated_dt)as lupdated_dt FROM update_mas where delflag=0 ";
stmt = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.addEventListener(SQLEvent.RESULT, selectResult);
stmt.addEventListener(SQLErrorEvent.ERROR, selectError);
stmt.execute();
}
public function selectResult(event:SQLEvent){
DGArray.removeAll();
number=1;
var result = stmt.getResult();
var numRows = result.data.length;
for (var i = 0; i < numRows; i++){
for(var col:String in result.data[i]){
timestamp=result.data[i][col];
}
}
updateRequest.url="serverpath ?time="+timestamp+"";
updateRequest.send(null);
}
public function selectError(event):void{
stmt.removeEventListener(SQLEvent.RESULT, selectResult);
stmt.removeEventListener(SQLErrorEvent.ERROR, selectError);
Alert.show("SELECT error:");
}
public function displayPOPUP(event:ResultEvent):void{
nupdates=((int)(event.result));
if(nupdates==0){
}else{
selection=Alert.show(""+nupdates+"Updates available", "UPDATES", Alert.YES|Alert.NO, this, alertClickHandler);
}
}
private function alertClickHandler(event:CloseEvent):void {
if (event.detail==Alert.YES){
downloadRequest.url="serverpath ?time="+timestamp;
downloadRequest.send(null);
}else
Alert.show("download cancelled");
}
public function displayResult(event:ResultEvent):void{
var record:String="";
sql="";
for(index=0;index<xmlcollection.length;index++){
var category:Object=xmlcollection.getItemAt(index);
sql="select Id FROM CATEGORY where delflag=0 and cat_name='"+category['catname']+"'";
stmt = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.addEventListener(SQLEvent.RESULT,checkRecord);
stmt.addEventListener(SQLErrorEvent.ERROR,checkError);
stmt.execute();
}
}
public function checkRecord(event:Event):void{
var category:Object=xmlcollection.getItemAt(index);
var path:String="";
var result:SQLResult = stmt.getResult();
if(result.data==null){
var sql:String= "INSERT INTO CATEGORY (cat_name, created_user,created_dt,updated_user,updated_dt,image_jpg,image_pdf) ";
sql += "VALUES ('"+category['catname']+"',";
sql +="'admin','"+category['cdate']+"','admin','"+category['udate']+"'"+category['pictimage']+"','"+category['pdfimage']+"' )";
stmt = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.addEventListener(SQLEvent.RESULT,insertRecord);
stmt.addEventListener(SQLErrorEvent.ERROR,insertError);
stmt.execute();
}else{
sql="";
sql="update CATEGORY set created_dt='"+category['cdate']+"', updated_dt='"+ category['udate']+"',image_jpg='"+category['pictimage']+"', image_pdf='"+category['pdfimage']+"' where delflag=0 and cat_name='"+category['catname']+"'";
stmt = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.addEventListener(SQLEvent.RESULT,updateResult);
stmt.addEventListener(SQLErrorEvent.ERROR,updateError);
stmt.execute();
}
userRequest.send(null);
var ludt_dt:Object=xmlcollection.getItemAt((xmlcollection.length-1));
timestamp="";
timestamp=ludt_dt['udate'];
sql="";
sql="update update_mas set lupdated_dt='"+timestamp+"' where delflag=0 ";
stmt = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.addEventListener(SQLEvent.RESULT,updateResult);
stmt.addEventListener(SQLErrorEvent.ERROR,updateError);
stmt.execute();
var temp:int=0;
for(var x:int=0;x<=xmlcollection.length-1;){
var urlstring:String="http://sidssoldc:81/lessons/ravi/";
var url:Object=xmlcollection.getItemAt(x);
urlstring+=url['pdfimage'];
path=url['pdfimage'];
while((path.indexOf('/',0)!=-1)){
path=path.slice(path.indexOf('/',0)+1,path.length);
}
urlReq=new URLRequest(urlstring);
var filename:Object=xmlcollection.getItemAt(x);
var loader:URLLoader=new URLLoader();
loader.dataFormat="binary";
selectstream=2;
loader.load(urlReq);
loader.addEventListener(Event.COMPLETE,function(event:Event){
var loader:URLLoader=(URLLoader)(event.target);
loader.dataFormat="binary";
var ofstream2:FileStream= new FileStream();
var ofstream1:FileStream= new FileStream();
var ofstream3:FileStream= new FileStream();
if(selectstream==1){
var ofile1:File = File.applicationStorageDirectory.resolvePath('images/pdf/'+path);
ofstream1.openAsync(ofile1, FileMode.WRITE);
ofstream1.writeBytes(loader.data, 0, loader.bytesTotal);
selectstream++;
}else if(selectstream==2){
ofstream1.close();
var ofile2:File = File.applicationStorageDirectory.resolvePath('images/pdf/'+path);
ofstream2.openAsync(ofile2, FileMode.WRITE);
ofstream2.writeBytes(loader.data, 0, loader.bytesTotal);
selectstream++;
}else if(selectstream==3){
ofstream2.close();
var ofile3:File = File.applicationStorageDirectory.resolvePath('images/pdf/'+path);
ofstream3.openAsync(ofile3, FileMode.WRITE);
ofstream3.writeBytes(loader.data, 0, loader.bytesTotal);
}
if(selectstream==3){
ofstream3.close();
}
});
x++;
temp=loader.bytesTotal;
checkStream.close();
}
/*urlStream=new URLStream();
urlStream.addEventListener(Event.COMPLETE, function(event:Event){
urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
for(var x:int=0;x<nupdates;x++){
var filename:Object=xmlcollection.getItemAt(x);
newfile=filename['pdfimage'];
var obj:Object=new Object;
startdownload=true;
var file:File = File.applicationStorageDirectory.resolvePath(newfile);
var fileStream:FileStream = new FileStream();
fileStream.openAsync(file, FileMode.WRITE);
fileStream.writeBytes(fileData, 0, fileData.length);
fileStream.addEventListener(Event.COMPLETE,progressHandler,true,10,true);
for(var x:int=0;x<fileData.length;x++){
startdownload=false;
fileStream.close();
}
});
urlStream.load(urlReq);
x++;*/
}
public function insertRecord(event:Event):void{}
public function insertError(event:Event):void{}
public function updateResult(event:Event):void{}
public function updateError(event:Event):void{
Alert.show("update failed");
}
public function checkError(event:Event):void{
Alert.show("error");
}
public function showError(event:FaultEvent):void{
Alert.show(""+event.fault);
}
public function itemClick(event:ListEvent):void{}
]]>
</mx:Script>
<mx:DataGrid id="dgUserRequest" sortableColumns="false" x="99" y="115" width="364" textAlign="left" itemClick="itemClick(event);" rowHeight="30" doubleClickEnabled="false" height="297" themeColor="#ACF4F8" visible="true" editable="false" dataProvider="{catxmlcollection}" color="#000C0E" fontSize="11" >
<mx:columns>
<mx:DataGridColumn id="ID" headerText="Id" visible="false" dataField="catid" />
<mx:DataGridColumn id="snumber" width="70" headerText="SerialNo" dataField="sno" visible="true" />
<mx:DataGridColumn id="CATEGORY3" width="250" headerText="CATEGORY" dataField="catname" visible="true" />
</mx:columns>
</mx:DataGrid>
<mx:XMLListCollection id="catxmlcollection" source="{userRequest.lastResult.categories.category}"/>
<mx:HTTPService id="userRequest" url="http://192.168.10:81/lessons/ravi/cat.php" fault="showError(event);" useProxy="false" method="GET" resultFormat="e4x" />
<mx:HTTPService id="updateRequest" result="displayPOPUP(event);" fault="showError(event);" method="GET" > </mx:HTTPService>
<mx:XMLListCollection id="xmlcollection" source="{downloadRequest.lastResult.Categories.Category}" />
<mx:HTTPService id="downloadRequest" result="displayResult(event);" fault="showError(event);" useProxy="false" method="GET" resultFormat="e4x" ></mx:HTTPService>
<mx:HTTPService id="categoryRequest"></mx:HTTPService>
<mx:Label x="216" y="53" text="Category Master" fontWeight="bold" fontSize="12" width="151"/>
</mx:WindowedApplication>
You need to provide more details. I can't even understand whether you want to refresh data from the server or want to download files without the user's permission. If it's the former, polling is the way to go. For the latter, you might as well shut shop because nobody's going to use an app that downloads stuff without asking first.
.p
I have had some issues when sending multiple requests simultaneously... when, for example, trying to load twenty images at the same time only some of them were received properly. I am not sure what was causing this, but I would suggest you try doing the transfers in a sequence since it solved all of my problems. In practice you might put them in an array and always take and remove the top one when the previous one completes.

How to generate a form(<mx:form>) dynamically in flex?

I need to generate a mx:form from an xml file that I am getting from httpservice.
Also I need to prefill the data that I am getting from the form itself.
Can someone give me a sample code?
You would have to expand on this obviously, but this is how I would go about building a dynamic form..
import mx.controls.TextInput;
import mx.containers.FormItem;
import mx.containers.Form;
private var fxml:XML =
<form>
<fields>
<field type="text" label="name" default="gary"/>
<field type="text" label="surname" default="benade"/>
</fields>
</form>
private function init():void
{
var form:Form = new Form();
form.setStyle("backgroundColor", 0xFFFFFF);
for each( var xml:XML in fxml..field)
{
switch( xml.#type.toString())
{
case "text":
var fi:FormItem = new FormItem();
fi.label = xml.#label;
var ti:TextInput = new TextInput();
ti.text = xml.#default.toString();
fi.addChild( ti);
form.addChild( fi);
break;
case "int":
break;
}
}
this.addChild( form);
}
Check this out: MXMLLoader for Flex 3. HTH.
<?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"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="handleCreationComplete()">
<fx:Declarations>
<fx:XML id="formdata">
<userinfoform>
<user>
<firstname inputtype="TextInput" formlabel="First Name" required="true">true</firstname>
<lastname inputtype="TextInput" formlabel="Last Name" required="true">true</lastname>
<Middlename inputtype="TextInput" formlabel="Middle Name" required="false">true</Middlename>
<nickname inputtype="TextInput" formlabel="Nick Name" required="false">false</nickname>
<combobox inputtype="ComboBox" formlabel="Gender" required="true">Male,Female</combobox>
<type inputtype="ComboBox" formlabel="Type" required="false">Book,Cds,Games</type>
<radioButtonGroup inputtype="RadioButtonGroup" formlabel="Gender" required="false">
<radiobutton inputtype="RadioButton" formlabel="Gender" required="true">Male</radiobutton>
<radiobutton inputtype="RadioButton" formlabel="Gender" required="true">Female</radiobutton>
</radioButtonGroup>
</user>
</userinfoform>
</fx:XML>
</fx:Declarations>
`enter code here`<fx:Script>
<![CDATA[
import flashx.textLayout.events.SelectionEvent;
import mx.collections.ArrayCollection;
import mx.core.UIComponent;
import mx.events.ItemClickEvent;
import mx.events.ValidationResultEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.validators.NumberValidator;
import mx.validators.StringValidator;
import spark.components.ComboBox;
import spark.components.DropDownList;
import spark.components.RadioButton;
import spark.components.RadioButtonGroup;
import spark.components.TextArea;
import spark.components.Form;
import spark.components.FormItem;
import spark.components.TextInput;
import spark.components.RadioButtonGroup;
import spark.components.RadioButton;
private function handleCreationComplete():void
{
//Below line can be used for XML from an external source
//XMLService.send();
buildForm(new XML(formdata));
}
private function errorHandler(evt:FaultEvent):void
{
//Alert.show("Error: " + evt.fault.message);
}
private function resultHandler(evt:ResultEvent):void
{
buildForm(new XML(evt.result));
}
private function buildForm(xml:XML):void
{
var lst:XMLList = xml.children();
for(var i:int = 0; i < lst.length(); i++)
{
var x:XMLList = lst[i].children();
for(var j:int = 0; j < x.length(); j++)
{
if(x[j].#inputtype == 'TextInput')
{
var frmItem:FormItem = new FormItem();
//frmItem.direction = "horizontal";
frmItem.label = x[j].#formlabel;
// make sure boolean is pasrsed to a string before assigned
// to required property of the formitem
var validString : String = x[j].#required;
var valid : Boolean = (validString == "true");
frmItem.required = valid;
var tb:TextInput = new TextInput();
tb.text = x[j];
frmItem.addElement(tb);
userInfoForm.addElement(frmItem);
}
else if(x[j].#inputtype == 'ComboBox')
{
var frmItemCB:FormItem = new FormItem();
//frmItemCB.direction = "horizontal";
frmItemCB.label = x[j].#formlabel;
// make sure boolean is pasrsed to a string before assigned
// to required property of the formitem
var validString : String = x[j].#required;
var valid : Boolean = (validString == "true");
frmItemCB.required = valid;
// make sure the string is split, assigned to an array, and parsed
// to an arraycollection to assgn it as dataprovider for dropdownlist
var str:String = x[j];
var arr:Array = str.split(",");
var arrcol:ArrayCollection = new ArrayCollection();
for(var k:int = 0; k < arr.length; k++)
{
var obj:Object = {name:arr[k]}
arrcol.addItem(obj);
}
var cb:DropDownList = new DropDownList();
cb.dataProvider = arrcol;
cb.labelField = "name";
frmItemCB.addElement(cb);
userInfoForm.addElement(frmItemCB);
}
else if(x[j].#inputtype == 'RadioButtonGroup')
{
var frmItemRB:FormItem = new FormItem();
//frmItemRB.direction = "horizontal";
frmItemRB.label = x[j].#formlabel;
// make sure boolean is pasrsed to a string before assigned
// to required property of the formitem
var validString : String = x[j].#required;
var valid : Boolean = (validString == "true");
frmItemRB.required = valid;
var frmItemRB1:FormItem = new FormItem();
frmItemRB1.addElement(label);
var y:XMLList = x[j].children();
var radioGroup = new RadioButtonGroup();
radioGroup.addEventListener(ItemClickEvent.ITEM_CLICK,
radioGroup_itemClick);
for(var l:int = 0; l < y.length(); l++)
{
var rb = new RadioButton();
rb.label = y[l];
rb.group = radioGroup;
frmItemRB.addElement(rb);
userInfoForm.addElement(frmItemRB);
}
}
}
}
}
public var label:TextInput = new TextInput();
private function radioGroup_itemClick(evt:ItemClickEvent):void {
label.text = evt.label ;
}
/**
* Helper function that returns all the fields for a
* given form. Pass in requiredOnly = true if you only want
* the required fields.
*/
private function getFields(form:Form, requiredOnly:Boolean=false):Array
{
var a:Array = [];
return a;
}
/**
* Validates all fields in a given form.
*/
private function validateForm(form:Form):Boolean
{
// reset the flag
var _isValid:Boolean = true;
var _notValid:Boolean = false;
// populate the fields - if your fields aren't dynamic put this in creationComplete
var fields:Array = getFields(form, true);
for each(var source:UIComponent in fields)
{
// create a simple string validator
var stringValidator:StringValidator = new StringValidator();
stringValidator.minLength = 2;
stringValidator.source = source;
stringValidator.property = "text";
stringValidator.requiredFieldError = "This field is required!!!";
var numberValidator:NumberValidator = new NumberValidator();
numberValidator.minValue = 0;
numberValidator.source = source;
numberValidator.property = "text";
numberValidator.lowerThanMinError = "This field is required!!!";
var rbValidator:StringValidator = new StringValidator();
rbValidator.minLength = 1;
rbValidator.maxLength = 80;
rbValidator.source = source;
rbValidator.property = "selectedValue";
rbValidator.requiredFieldError = "This field is required!!!";
var result:ValidationResultEvent;
//var radiogroup:spark.components.RadioButtonGroup = new spark.components.RadioButtonGroup;
// typical validation, but check to this checks for any different
// types of UIComponent here
if (source is TextInput)
result = stringValidator.validate(TextInput(source).text)
else if (source is TextArea)
result = stringValidator.validate(TextArea(source).text)
else if (source is DropDownList)
result = numberValidator.validate(DropDownList(source).selectedIndex)
//else if (source is Label)
//result = stringValidator.validate(Label(source).text)
//if(source is spark.components.RadioButton)
//result = numberValidator.validate(mx.controls.RadioButton(source))
// if the source is valid, then mark the form as valid
_isValid = (result.type == ValidationResultEvent.VALID) && _isValid;
}
return _isValid;
}
protected function submitButton_clickHandler(event:MouseEvent):void
{
if(validateForm(userInfoForm) == true)
{
//Alert.show("Proceed Genius!!!","Alert");
}
else
{
//Alert.show("Open ur eyes and fill the form properly u morron!!!","Morron");
}
}
]]>
</fx:Script>
<fx:Declarations>
<!--Below line can be used for XML from an external source-->
<!--<mx:HTTPService fault="errorHandler(event)" id="XMLService" resultFormat="e4x" url="formdata.xml" result="resultHandler(event)" />-->
</fx:Declarations>
<s:VGroup width="100%">
<s:Form id="userInfoForm" />
<s:Button label="Submit" id="submitButton" click="submitButton_clickHandler(event)"/>
</s:VGroup>
</s:View>

Resources