How to get a view to read data - apache-flex

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>

Related

flex: list of files

I'm making a Flex mobile application with Flash Builder 4.6 And I have a question for a function I want to implement.
I have a declaration:
<s:HTTPService id="getXMLFile" fault="trace('No CCR found!')" result="getPatient(event)"
resultFormat="object" url="assets/CCR1.xml"/>
But this only points to one file and this has to be typed in.
Already now how to change the url and do the request again.
getXMLFile.url = "assets/CCR2.xml";
getXMLFile.send();
But I want to have some sort of function to check all the files in the "assets" package and to this code part for each file. So I want something like this:
for(var file:string in assets) {
getXMLFile.url = "assets/" + file;
getXMLFile.send();
}
Thx
<fx:Script>
<![CDATA[
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
//Create one xml having all URL, which you can parse on Flex side. Collect all URL in Array (ex:- fileArray),
//than you can loop it. You can call parseXML on creationComplete of your application.
private var fileArray:Array = new Array();
private var count:int = 0;
//Collect all URL in this fileArray.
private function parseXML():void
{
//parse XML and puch URL in fileArray
// xmlLength var is xml length.
var xmlLength:int;
for(var i:int;i<xmlLength ;i++)
{
var URL:String = "";
//URL = parse Value from XML;
fileArray.push(URL);
}
sendRequest();
}
private function sendRequest():void
{
getXMLFile.url = fileArray (count);
getXMLFile.send();
}
private function getPatient(event:ResultEvent):void
{
//If Success request for Next Patient
requestForNextPatient();
}
private function faultHandler(event:FaultEvent):void
{
//If fault request for Next Patient
requestForNextPatient();
}
private function requestForNextPatient():void
{
//Request for Next Patient
count++;
if(count > fileArray.length)
sendRequest():
}
]]>
</fx:Script>
<s:HTTPService id="getXMLFile" fault="faultHandler(event)" result="getPatient(event)" resultFormat="object" />
This may help you.....

IconItemRender In Flex 4.5.1 With Dynamically Called Icon

Alright, simple item render, or so I thought... I have an some data loaded into a list, one of the fields is project_Type. It's a string that either says "RESIDENTIAL" or "COMMERCIAL". And based on that string, I just want to display a little house, or a little office building as the icon. So, I cobbled together my itemrender as follows:
<?xml version="1.0" encoding="utf-8"?>
<s:IconItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
labelField="dateAdded"
messageField="builder_Name"
iconFunction="myiconfunction"
iconWidth="48" iconHeight="48"
decorator="#Embed('assets/Right-48x48.png')" >
<fx:Script>
<![CDATA[
// iconFunction="myiconfunction"
// iconWidth="32" iconHeight="32" -->
private function myiconfunction(data:Object):String{
var type:String;
var projectType:String = (data != null) ? data.project_Type : "QUESTION";
if (projectType == "RESIDENTIAL") {
type = "assets/House-48x48.png";
}
else if (projectType == "COMMERCIAL") {
type = "assets/Commercial-48x48.png";
}
else if (projectType == "QUESTION") {
type = "assets/Question-48x48.png";
}
return type;
}
]]>
</fx:Script>
</s:IconItemRenderer>
So, pretty straight forward there... But know custom icon.... No errors either though. What am I doing wrong guys?
Update
So, I changed the item renderer to the following, and still no icon... I've double checked the data and RESIDENTIAL and COMMERCIAL are both being passed...
<?xml version="1.0" encoding="utf-8"?>
<s:IconItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
labelField="dateAdded"
messageField="builder_Name"
iconFunction="myiconfunction"
iconWidth="48" iconHeight="48"
decorator="#Embed('assets/Right-48x48.png')" >
<fx:Script>
<![CDATA[
[Embed(source="assets/House-48x48.png")]
public var residentialClass:Class;
[Embed(source="assets/Commercial-48x48.png")]
public var commercialClass:Class;
[Embed(source="assets/Question-48x48.png")]
public var questionClass:Class;
private function myiconfunction(data:Object):Object
{
var projectType:String = (data != null) ? data.project_Type : "QUESTION";
if (projectType == "RESIDENTIAL") {
return residentialClass;
}
else if (projectType == "COMMERCIAL") {
return commercialClass;
}
return questionClass;
}
]]>
</fx:Script>
</s:IconItemRenderer>
But alas, nothing...
These Mods usually work for me.
<?xml version="1.0" encoding="utf-8"?>
<s:IconItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
labelField="dateAdded"
messageField="builder_Name"
iconFunction="myiconfunction"
iconWidth="48" iconHeight="48"
decorator="#Embed('assets/Right-48x48.png')" >
<fx:Script>
<![CDATA[
private function myiconfunction(data:Object):String
{
var s:String = data.project_Type; //capture data for case match
switch (s.toUpperCase()) {
case "RESIDENTIAL":
return 'assets/House-48x48.png';
break;
case "COMMERCIAL":
return 'assets/Commercial-48x48.png';
break;
default:
return 'assets/Question-48x48.png';
break;
}
}
]]>
</fx:Script>
</s:IconItemRenderer>
Are you sure your icon is ever getting called? Are you sure the path to the icon is correct? Are you sure the icon assets are being embedded in your compiled app?
Instead of returning the path to the object from your function, I'd probably return a class object, not a string value. In half psuedo-code, something like this, which would be inside the renderer:
<fx:Script>
[Embed(source="assets/House-48x48.png")]
public resientialClass : Class;
[Embed(source="assets/Commercial-48x48.png")]
public commercialClass : Class;
[Embed(source="assets/Question-48x48.png")]
public questionClass : Class;
private function myiconfunction(data:Object):Object
var type:String;
var projectType:String = (data != null) ? data.project_Type : "QUESTION";
if (projectType == "RESIDENTIAL") {
return residentialClass;
}
else if (projectType == "COMMERCIAL") {
return commercialClass;
}
return questionClass;
}
</fx:Script>
Specify the renderer function the same way you do in your original code.
Extend the IconItemRenderer class
package {
import spark.components.IconItemRenderer;
public class CustomIconListItemRenderer extends IconItemRenderer
{
[Embed(source="assets/House-48x48.png")]
public resientialClass : Class;
[Embed(source="assets/Commercial-48x48.png")]
public commercialClass : Class;
[Embed(source="assets/Question-48x48.png")]
public questionClass : Class;
public function CustomIconListItemRenderer()
{
super();
iconFunction = iconFunc;
}
private function iconFunc(data:Object):Object
var type:String;
var projectType:String = (data != null) ? data.project_Type : "QUESTION";
if (projectType == "RESIDENTIAL") {
return residentialClass;
}
else if (projectType == "COMMERCIAL") {
return commercialClass;
}
return questionClass;
}
}
}
So then in your list you can assign it as itemRenderer="renderers.CustomIconListItemRenderer"

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.

how to assign dataProvider to DataGrid Dyanmically in flex?

i done as follows
i have a method with brings data of particular table, as given my parameter to that method,
now i want to fetch data from corresponding table and it too list, and send back flex and form dynamically Grid & add dataprovider dynamically as for its corresponded table colomns in flex side ?
Remote objec(java class)
public List<List<String>> getMasterTableData(String name)
{
String designMaster = "tbl_design_master"+name;
String masterTableName = "tbl_master"+name;
String[][] res ;
List<List<String>> list = new ArrayList<List<String>>();
try
{
st = connection.createStatement();
ResultSet rs1 = st.executeQuery("select * from "+designMaster);
int len = 0;
while(rs1.next())
{ len++; }
ResultSet rs2 = st.executeQuery("select * from "+masterTableName);
while(rs2.next())
{
List<String> ll = new ArrayList<String>();
for(int i=1;i<=len; i++)
{
ll.add(rs2.getString(i));
}
list.add(ll);
}
}
catch (SQLException e) {
e.printStackTrace();
}
return list;
}
flex code :
<mx:RemoteObject id="RO" destination="adminServiceImpl">
<mx:method name="getMasterDesign" result="getMasterDesignRH(event)" fault="FH(event)" />
<mx:method name="getMasterTableData" result="getMasterTableDataRH(event)" fault="FH(event)"/>
</mx:RemoteObject>
<mx:Script>
<![CDATA[
[Bindable] private var ac:ArrayCollection = new ArrayCollection();
public function init(Str:String):void
{
RO.getMasterDesign(Str);
Application.application.selectedgridItem = Str;
RO.getMasterTableData(Str);
}
private function getMasterDesignRH(event:ResultEvent):void
{
Application.application.designList = event .result as ArrayCollection;
var aColumns:Array = new Array();
for(var i:int=0; i< Application.application.designList.length; i++)
{
var dgc:DataGridColumn = new DataGridColumn();
dgc.headerText = Application.application.designList.getItemAt(i).colName;
//dgc.dataField = Application.application.designList.getItemAt(i).colName;
aColumns.push(dgc);
}
mainGrid.columns = aColumns;
}
private function getMasterTableDataRH(event:ResultEvent):void
{
ac = event.result as ArrayCollection;
mainGrid.dataProvider = ac;
}
private function FH(event:FaultEvent):void{
Alert.show(event.fault.faultString);
}
]]>
</mx:Script>
<mx:HBox width="100%" height="80%">
<mx:DataGrid id="mainGrid" width="100%" height="100%" />
</mx:HBox>
getMasterDesign is an ArrayCollection, which is filled with the column names and components to be displayed
Ex : getMasterDesign(emp)
empMasterDesign table looks like as follows
colName component
--------------------
EmpName textBox
empSal textBox
empDesi ComboBox
empMasterData:
empName | EmpSal | EmpDesi
abc 1000 Cler## Heading ##ck
xyz 2000 Manager
Now i want this create a Datagrid in flex dynamically by using its design & master data table in action script i done everyting , my dataGrid had formed as for his master design,but data is not showing ?
You must set the dataField to the appropriate value. From the given data, it looks like colName field in the metadata and its corresponding name in the table are not the same. For example it is EmpName in the design and empName in the original table; none of the fields match - empSal vs EmpSal, empDesi vs EmpDesi. Fix that, assign colName to the dataField, and you should be good to go.

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.

Resources