PDA

View Full Version : Database simulated with arrays on a cd-rom


lecasn5
05-07-2003, 01:53 PM
Hi there

I'm trying to make a presentation where people can search information by typing a number (ex: 102425) in a input text box and then click on a search button to go to a specified frame where the needed information is displayed. I could do that by using the if command, but the problem is that I have more than 4000 items and I'm not very eager to make 4000 lines of if commands. I suspect I have to use arrays and loops but I don't know how. Can anybody help me?

Thanks

Eduardo

retrotron
05-07-2003, 02:46 PM
4000 items shouldn't be too slow, especially if its in a standalone on a cdrom.

If you're using MX, I'd put the information in a RecordSet. You can write a loop to build that RecordSet (see example below).

Once you have a RecordSet full of your items, you can write a function which will "query" the RecordSet (it will use a loop to walk through each item and check for the number you're looking for). An array might be a tiny bit faster, but it'd be much easier with a RecordSet (which is nothing but an array anyways).

Here's a sample of how this would work. I first build a RecordSet, then I query that RecordSet for the information, displaying the result:

// include the NetServices code so you can use the RecordSet object
#include "NetServices.as"

var allItems = new RecordSet(["itemID","itemName"])
for (var i=0; i < 5; i++) {
var itemToAdd = {itemID: i, itemName: "item_" + i};
allItems.addItem(itemToAdd);
} // end for loop

function queryItems(x) {
// x: the value to search for
for (var i=0; i < allItems.getLength(); i++) { // loop through all items
var thisRecord = allItems.getItemAt(i);
if (thisRecord.itemID == x) {
return thisRecord;
} // end if statement
} // end looping through all items
} // end queryItems()

var result = queryItems(3);
trace("Item number: " + result.itemID + " is " + result.itemName);
As you can see, this uses a loop to put some information into a RecordSet (the manner for building this RecordSet can be modified to suit your database. Let me know if you want some more info on building your particular RecordSet). Then the "queryItems()" function searches that RecordSet for the matching item. When it finds it, it stops looping and returns the record. This can easily be modified for the possibility that a search might return more than one record.

The nice element to doing it this way is you can have your "database" as a text file on the cd, load it with LoadVars, then put the information into a RecordSet which can be "queried" in the manner above.

retrotron

lecasn5
05-07-2003, 08:32 PM
Hi

I don't have the slightest idea of what a Recordset is, so I couldn't understand the code at all. I also have already solved the problem with arrays and a while loop. The only problem is that whenever I have to change the product number of the items (because a product might be discontinued) I have to be very careful to keep the arrays exactly related. Here's the code:

enter_btn.onRelease = function() {
productnumber = new Array(123, 124, 125);
items = new Array("pl 101", "pl 102", "pl 103");
i = 0;
while (productnumber[i] != input && i<productnumber.length) {
i++;
}
if (productnumber[i] == input) {
output = items[i];
} else {
output = "no matches found.";
}
};

Input and output is the var for a input text box and dinamic text box respectevily.
But I was very interested on that misterious (I couldn't find it it in the Flash help) recordset because you mentioned that we could have a kind of database in a txt file on the user computer (no need for server side). That would be very handy whenever I needed to make changes on the products.

retrotron
05-07-2003, 08:43 PM
Yeah, your solution does pretty much the same thing as mine. It works.

The RecordSet object is a very nice way to "simulate" a database (in the manner I mentioned in my first post) when you don't have one.

The RecordSet object is a new object built for Flash Remoting. Download the FlashRemoting Components from macromedia's site, run the install program, and then you're ready to go. The install program will install a file that's pure actionscript called "NetServices.as" in the proper macromedia directory on your computer. Then you can include this file with the following as the first line of code in your .fla:

"#include "NetServices.as"
(no semicolon on the end, and give it a full blank line underneath it before you start typing any code again, otherwise it will throw an error). Once the NetServices.as file is in your .fla, you can work with RecordSets.

Since NetServices.as was released only later with Flash Remoting, it doesn't appear in Flash Help (too bad, it's a very useful object). However, here is the documentation on the RecordSet object:

http://livedocs.macromedia.com/frdocs/Using_Flash_Remoting_MX/UseASData6.jsp#1170158

If you like, we can keep this thread going and work through how to use the RecordSet object (and maybe even use a textfile with it).

lecasn5
05-07-2003, 08:50 PM
Yes, I'm very interested in going on with the thread but I've got the impression that you are talking about a Flash projector that as to rely on a server ( you mentioned downloading FlashRemoting Components) and I want it to work local, on the user's computer. Am I right?

retrotron
05-07-2003, 09:01 PM
Yeah, local, from a text file. Flash Remoting is built for working with a server, but the RecordSet object that comes with Flash Remoting is also a great tool for use without a server, especially if you're reading large numbers of organized records from a text file (when, for example, you are running the file from a cd and don't have a database or server running).

lecasn5
05-07-2003, 09:12 PM
That's just what I wanted to listen (read)! I'm going to download the flash remoting and take a look at it. I'll be right back

lecasn5
05-07-2003, 09:55 PM
just downloaded it. But I can't find out help on how to relate the code with a txt file. Is there any recommended file extension for the text file? Does the code need to have some line calling the text file?

retrotron
05-09-2003, 05:24 PM
Hi lecasn5

Sorry I'm so delayed in answering, I was out of town for a few.

I'm not sure if there's any help out there regarding how to integrate Flash Remoting with a textfile (since technically you don't need Flash Remoting to work with a text file), but I can show you how. However, if you find any helps out there, let me know.

Just to be safe, let's test to be sure you have the Flash Remoting Components installed. Open up a blank .fla and insert this code into the first frame:

#include "RecordSet.as"

// create a new RecordSet object
var myRecords = new RecordSet();
// test whether the object was successfully created
trace(typeof myRecords);
The code first includes a file called "RecordSet.as" (this contains the code for RecordSets). The second line creates a new RecordSet object, and the third line tests whether it was created successfully.

Test the file. If the output window says "object", then the Flash Remoting Components have been installed and you're ready to go. If it says "undefined", then something's gone horribly, horribly wrong. Anytime you want to use a RecordSet, you must include this file in your code (just for kicks, remove the first line of code and run the file again).

Before we get too far along, let me ask you a question: how much do you know about object oriented programming?

retrotron

lecasn5
05-10-2003, 02:06 PM
Yes, it is installed.

Well, I was afraid you'd ask me that because I don't have much experience in object oriented programming, in fact I don't have much experience in programming. The first an only contact I had with programming was with AS and VBscipt. I know that this threads are supposed to be a place where people share mutual knowledge, so, and to be completely honest, i must tell you that if we move on with this thread I'm almost certain that I will be the only one getting something out of it because I don't have the knowledge for you to learn something from me. For this reason I will understand if you're not willing to keep this thread going.

CyanBlue
05-10-2003, 02:51 PM
Howdy, retrotron...

Thank you for the good explanation of the RecordSet...

I was wondering if you could tell me the difference between the RecordSet and the Associative Array??? I just don't see the difference between two... :(

retrotron
05-10-2003, 04:46 PM
Hi Cyan Blue -

There isn't really much difference between an associative array and a RecordSet. It's been a while since I looked at the code for the RecordSet, but if I remember correctly the RecordSet is simply a 2D associative array. The first degree of the array contains the column names, e.g. myArray["employeeID","lastName","firstName"]. Each element of that array contains an array of values corresponding to all the values in the query or database which fills the RecordSet. E.g. myArray["lastName"] might have these values: ["Johnson","Handy","Farley"]. The index of this second dimension corresponds to the index of the "rows" or "records" of your query or database. E.g. myArray["lastName"][1] corresponds to the value of the second record of the "lastName" column in your query or database. It is this second dimension index, I believe, which is used by various methods to push or pop the array via methods like RecordSet.addItemAt(i)/removeItemAt(i)/getItemAt(i). It is certainly easy enough to build your own class or associative array to function just like the RecordSet (which I did for php reasons before I realized the RecordSet was out there :( . . . ), but the RecordSet class has all those methods already built which make for a convenient and friendly object interface.

Well, I think that's the idea behind the RecordSet, but like I said, it's been a long time. Hope my sleepy, no-coffee-yet, Saturday morning brain has miraculously managed to be clear here.


lecasn5 -

I was just asking so I know what to explain and what not to explain. No worries about lack of OOP experience. That's what these forums are for -- to learn. I have no intentions of discontinuing this thread, I'm excited about it, so maybe we can learn something together here.

lecasn5
05-10-2003, 05:10 PM
Nice. I'm just trying to figure out how to integrate the text file. I've been searching documentation about the recordset but all I find is Flash integration with ASP, PHP, CF. When I come up with something I''l let you know.

thx

retrotron
05-10-2003, 07:05 PM
Just curious: do you have a server side scripting engine (e.g. php, coldfusion, asp)?

CyanBlue
05-10-2003, 11:22 PM
Hi, retrotron...

Yup... Much clearer in my head at least... At the bottom level, if I do not understand all that stuff, there still is one good reason why I may go for the RecordSet... Which is the built-in methods that will make my life whole lot easier to navigate/manipulate the database... Thanks... ;) I guess I should know where you live in Chicago so that I can go and bug you when I go back to Chicago... :D (Don't know when it will be though...)

retrotron
05-11-2003, 06:21 AM
Yes CyanBlue, do look me up when you come back to Chicago. That way I can conveniently turn the tables -- as any good ninja would -- and bug you when I need help. Muh ha ha ha ha! :)

Yes, Chicago is an excellent city.

retrotron
05-11-2003, 06:54 AM
Okay lecasn5, lets start doing this textfile-to-RecordSet thing.

Here is the game plan: (1) put the information in a database into a textfile; (2) load the text file into a Flash movie; (3) convert the information from the textfile into a RecordSet object; (4) work with the RecordSet object as if it were a database.

I should mention that using xml instead of a textfile might be a better way to go, but just to keep the concept simple, we'll just use a textfile. Maybe later we can try and do this with xml. Also, we'll do this without too much object oriented stuff at first, but again, maybe after we get a working script we can do it OO. Okay, on to the fun.

The first thing we need to do is convert the information in a database into a textfile (the classic "flat text database").

We'll worry about your 4000 record database later, right now lets do this with a database small enough that our minds can track with all the records. Suppose we have a database table that tracks basic employee information. It has three columns: employeeID, lastName, firstName. Suppose we have three records in our table. We'll call the table "tbl_employeeData".


tbl_employeeData
------------------------------------------------
| | employeeID | lastName | firstName |
------------------------------------------------
| 0 | 1 | Johnson | Randy |
| 1 | 2 | Handy | Jack |
| 2 | 3 | Knightly | I.P. |
------------------------------------------------
Note that the numbers on the far left column (0-2) are not numbers in the database, they are simply there to indicate the record or row number.

We have to get this information into a string. I've thought about a number of ways to do this, but I'll tell you what I think is the simplest. We include two basic categories of variables: (1) a list of the table columns, and (2) for each column, a variable which contains a list of all the values in the table for that column.

(1) a list of the table columns. This is simply named "columnList" and has a comma-delimited list of the columns:

columnList=employeeID,lastName,firstName
(2) for each column, a variable which contains a list of all the values in the table for that column. Each of these variables is named identical to the column it represents (e.g. the variable which will hold the values of the employeeID column will be named "employeeID"). So we'd have three of these variables because our table has three columns:

employeeID=1|2|3
lastName=Johnson|Handy|Knightly
firstName=Randy|Jack|I.P.
You may be wondering why I used the pipe ("|") to separate the values for these lists. The reason is because the values in these columns often contain commas (e.g. if we had a field called "comments", it might have this entry: "I didn't like it, but it seemed to work."). Thus, I want to separate the items in the list with a character that is most likely not going to be used in the items themselves. You can choose anything for this character, really, just so long as an item in the list does not also contain the same character. In any case, each of these variables is a pipe-delimited list.

Okay, that's the variables we'll need for our textfile. Since Flash can only read url-encoded text files, we need to put all this into a url-encoded string. Variables are indicated in url-encoding with an ampersand ("&"), so we simply place each variable after an ampersand into one long string:

&columnList=employeeID,lastName,firstName&employeeID=1|2|3&lastName=Johnson|Handy|Knightly&firstName=Randy|Jack|I.P.

There, that's the content of the textfile we'll use. It is simply a url-encoded string that contains a set of variables which in turn contain the values in a database. So type this string into a textfile with NotePad or whatever other text-editor you prefer, and save it as "tbl_employeeData.txt". Make sure the textfile is in the same directory as the .fla which will use the textfile.

Okay, let me know when you get this textfile made, and make me explain anything that's not clear.

CyanBlue
05-11-2003, 08:42 AM
Hm... Ninja??? Alrighty... I'll do that... :)

lecasn5
05-11-2003, 05:26 PM
Ok, the txt is done. What I still can't understand is how we're going to call the txt:confused:

retrotron
05-12-2003, 12:53 AM
I'm glad you asked, because that's the next step we need to do. First, though, let me explain one thing: objects.

I know I said we'd keep the object stuff minimal, but I changed my mind about it. That's because we're working with two objects here -- the RecordSet and LoadVars -- so we might as well treat them right. I'm going to explain real quick like the basic terminology of object oriented programming (OOP) so we can at least speak about what we're doing here with proper diction. I'm sure we could do this without an explanation, but I'm feeling adventerous enough to want to explain it to myself, so here goes. :)

OOP is, as the name implies, a way of programming that orients itself towards working with "objects". An "object" is any entity in ActionScript that is self contained. That is, it is marked off from other entities and is considered by ActionScript to be a single "thing". An object can be anything: a variable, an array, a movieclip (technically, a movieclip is not an object, but it acts so much like an object that it is helpful to think of the movieclip as if it were an object). These are objects which are "native" to ActionScript, meaning they are predefined for you. One can, however, create custom objects. An object is often concrete, a movieclip for example (you can see it), but it might not be so simple: it might be a complex set of data that you wish to bundle together so ActionScript treats it as a single entity. An object is just that: any set of properties and processes that are bundled together and treated as a single entity. Basically, anything and everything can be (and often is, whether we know it or not) an object.

I just mentioned "properties" and "processes". Every object can be broken down into two kinds of parts: a property or a process. A property is anything which defines a quality or property of the object. For example, the x and y coordinates of visual objects, the width and height, the alpha setting, all of these are "properties" of objects. These are all predefined properties of objects, but we can of course also have custom properties. All properties are referred to in ActionScript like this: objectName.propertyName. Every property has a name and a value, just like a variable (hence, object properties are sometimes called "property variables" or "object variables"). For example, the line "myMovie_mc._x = 5;" takes the "_x" property of the "myMovie_mc" object and sets it to the value of 5. You get the picture: properties (or object variables) are qualities that define an object.

I also said that objects can have "processes", activities which an object may perform. For example, movieclips have as one of their processes "clear()". When a movieclip performs this process, it clears all the drawing content in the movieclip. These activities/processes are called methods. A method is any process or activity which is attached to and performed by an object. Methods are written as functions which are attached to their object. The syntax is: "objectName.methodName();". Thus, if I have a movieclip named "square_mc", I can execute its "clear" method like this: "square_mc.clear();".

Okay, so we've covered the proper terminology for objects, properties, and methods. There's only one last part to mention. Sometimes an object is also called a "class". The general idea is this: a class is the general definition of an object, and an object is an actual instance of a class. The classic example uses humans: if we were making a game which used a lot of humans, it might be beneficial to define a human class. The class would give the object properties such as 2-3 arms (my humans would have 3 arms, anyways), 2 eyes, a head, 2 legs, 5 fingers, a ninja sword (oh yes, all humans would have ninja swords in my game, even if it was a poker game).

Now, the class is simply the set of properties and methods which define what an object would look like were there an actual instance of the object. So we can have a "human" class, but have no actual humans in our game. Once we create a human in our game, we have created an instance of the class. You can see this in action: when you drag a movieclip symbol onto the stage in the authoring environment, you'll notice in the properties panel a field which says "<Instance Name>". That means Flash has just created an instance of your symbol, and you can now give that particular instance a name. In our human example, I could create two instances of the human class and give one an instance name of "joe" and give the other an instance name of "harry".

I mentioned above that properties and methods always are attached to their object when you call them: "objectName.propertyName" or "objectName.methodName();". That was a little misleading. Technically, properties and methods are attached to instance names. So if I wanted to define a "size" property for my humans, I would not write "human.size = 50;", not unless I wanted every human to have a size of 50. I would want to define the properties for each instance, so I use the instance name: "joe.size = 50;" and "harry.size = 70;".

You can see that its easy to use the terms "object" and "class" interchangeably in ActionScript, and indeed this happens. This is because in ActionScript, there's not much difference between a class and an object: a "class" is really an object and an "instance" is really just a copy of the object. Other programming languages, such as Java or C++, have a much stricter difference between classes and objects. In any case, I tend to use "object" and "class" interchangably, and I mostly just use "object". In any case, be aware of the terminology ambiguities. The context usually makes it clear what is intended.

Okay, that's objects in a nutshell. Like I said, we could definitely do this without discussing the objects, but this was good to explain this to myself. I hope it made sense to you too. Anyways, we'll be using two objects: the RecordSet object (or RecordSet class) and the LoadVars object. I'll just begin another post to talk about the LoadVars object. We'll use that to get our textfile into Flash.

retrotron
05-12-2003, 01:22 AM
Okay, let's get our textfile into the .fla.

Open up a new .fla (make sure it is in the same directory as your textfile). Put this as the first line of code:

#include "RecordSet.as"
When you installed FlashRemoting, this file was installed in a directory called "Flash/include". When Flash publishes the file, it looks in the /include directory and then pastes the code out of RecordSet.as into your file. RecordSet.as is simply the actionscript which defines the custom object called the "RecordSet". By including it, we don't need to define it ourselves, we just have to include the file. Nice and easy. Note that you must include this file, since it contains the code which defines the RecordSet object. If you don't include this file and try to work with the RecordSet, you'll get an undefined because it doesn't know what the RecordSet object is.

Next, give yourself a blank line of whitespace and then type this:

// create a new LoadVars object
var myVars = new LoadVars();
Now that you know all about objects, you can understand exactly what this line does. The LoadVars object is new to Flash MX, and it is a robust object that makes sending and loading variables in and out of Flash very easy. The older commands such as loadVariables() and loadVariablesNum() were not objects, and they weren't as robust as the LoadVars object. As we said, in order to use an object, you have to create an instance of the object. You create a new instance by typing "new" and then the name of the object followed by two parentheses (the two parentheses tell Flash to construct the object). In this case we want to create a new LoadVars object, so our code is "new LoadVars();". We also want to give our object an instance name so we can refer to it later on. Hence, we say "var myVars = ". Now we have an instance of the LoadVars object called "myVars".

The LoadVars object has some useful methods to send and load data. We'll use this one: load() -- for the sake of simplicity. Here is the next line of code:

// import textfile variables into the LoadVars object
myVars.load("tbl_employeeData.txt");
As you can see, the "load()" method is attached to our "myVars" object. The parameter is the name of the textfile to load. This method will thus load the variables found in tbl_employeeData.txt into our "myVars" instance.

When Flash loads these variables into the LoadVars object, it turns the variables into properties of the object. Each variable becomes its own property. Our first variable was "columnList=employeeID,lastName,firstName", where "columnList" is the name of the variable and the rest is the value. LoadVars thus converts "columnList" into a property of the object, so now we can reference it just like we would any other object property: objectInstanceName.propertyName. We could also refer to any of the other variables we passed in, such as employeeID.

trace(myVars.columnList); // output: employeeID,lastName,firstName
trace(myVars.employeeID); // output: 1|2|3
However, if you try and run this, you will get "undefined" for both of these values. This is because it takes some time to load the variables, but the parser does not stop and wait, instead it keeps on going. So trying to refer to the variables right after we call the load() method will fail because it hasn't had enough time to load the variables.

The way to get around this is to define a function which will execute only when the data is loaded. Here is how we do that:

// do this when the data is loaded
myVars.onLoad = function(success) {
// code goes here
} // end onLoad()
Here we define an event for our "myVars" instance: onLoad. When the data loads, this function will execute. One variable is passed to the function when data loads: "success". Success evaluates to either true or false, depending on whether the data loaded successfully. We want to test whether the data was loaded successfully or not, so we put an "if" statement that does this. Our onLoad() function then looks like this:

// do this when the data is loaded
myVars.onLoad = function(success) {
// the "swonking" test: check whether data was properly loaded
if (success) { // data was successfully loaded
trace("Success! Data was loaded successfully.");
} else { // no data was loaded, display error
trace("Error: no data was loaded!");
} // end swonking test
} // end onLoad()
As you can see, testing whether the data was loaded or not is called "swonking" (this is an informal name, but the common name for it nonetheless). Run this just to be sure you are getting the "Success!" message in your output window.

Once the data is successfully loaded and Flash is notified by the swonking function, you can then do something with the data. The easiest way to do this is to write a function which processes the data and then call that function from within the swonking function. Let's call our function "processVars()". We then replace the "trace("Success!...");" line with a simple function call: "processVars();". Here is the final swonking function:

// do this when the data is loaded
myVars.onLoad = function(success) {
// the "swonking" test: check whether data was properly loaded
if (success) { // data was successfully loaded
processVars(); // call this function to process the loaded variables
} else { // no data was loaded, display error
trace("Error: no data was loaded!");
} // end swonking test
} // end onLoad()
Then we can define our "processVars()" function to process the variables:

// this function processes the variables, it is called when data is loaded successfully
function processVars() {
// put code which processes data here . . .
} // end processVars()
Now, when the data is loaded successfully, the swonking function calls this "processVars()" function.

Let's test to be sure we have the variables from our text file properly imported into the LoadVars object. In the processVars() function, simply trace each variable:

// this function processes the variables, it is called when data is loaded successfully
function processVars() {
trace(myVars.columnList);
trace(myVars.employeeID);
trace(myVars.lastName);
trace(myVars.firstName);
} // end processVars()
When you test this, you should see the proper values displayed in your output window.

There, that's pretty much it. That's how you load the data into the LoadVars object. Now we have each variable as a property variable of the LoadVars object and it is thus easy to work with.

Is this making any sense? By "making sense", I mean is it clear enough that you could do it on your own in a different situation? Let me know when this much works and we'll start putting this data into a RecordSet.

lecasn5
05-12-2003, 08:31 AM
It's pretty clear so far. No problems aplying it in diferent but similar situations.

retrotron
05-13-2003, 04:03 PM
Great! You're awesome. We're at our last step here: putting the LoadVars variables into our RecordSet.

Our LoadVars variables are each a list of values. The first thing we need to do is get some way to cycle through each element in these lists. The obvious approach is to convert these lists into arrays, since each element of an array is indexed and we have precise control over each element. The command that converts a string list into an array is this: String.split(delimiter). So inside of our "processVars()" function, here's the first bit of code:

// convert the string variables into arrays that we can work with
// --------------------------------------------------------------

var columnList_arr = myVars.columnList.split(",");
var employeeID_arr = myVars.employeeID.split("|");
var lastName_arr = myVars.lastName.split("|");
var firstName_arr = myVars.firstName.split("|");
As you can see, we split each of these strings into an array. Notice that we used the comma delimiter for the columnList, but we used the pipe for the other three. Now "columnList_arr" is an array with three elements: columnList_arr[0] = "employeeID", columnList_arr[1] = "lastName", and columnList_arr[1] = "firstName". The same goes for the others.

Next, we'll assign the number of elements in these variables to a variable called "recordCount". This is because, if you remember back to our original database table, we had three records, and we put all the records for a column into a single variable. Thus, however many elements there are in that list, that's how many records we had.

// get how many records there are
var recordCount = employeeID_arr.length;
All well and good. Next we have to put each of these records into a RecordSet (this is what we've been waiting for all this time). We'll do this with a loop, and loop through each record and put the proper value into the RecordSet:

// build the RecordSet, adding the values of the array into a RecordSet
// --------------------------------------------------------------

// create a new RecordSet
var myRecords = new RecordSet([columnList_arr]);
// loop through each record, sending each value into the RecordSet
for (var i=0; i < recordCount; i++) {
var itemToAdd = {employeeID: employeeID_arr[i], lastName: lastName_arr[i], firstName: firstName_arr[i]};
myRecords.addItem(itemToAdd);
} // end looping through each record
In the first line of code, we create a new RecordSet object. The syntax for this is "var instanceName = new RecordSet([list of column names]);". Since we already have an array that has all the column names in it, we simply put that inside the parentheses to create a RecordSet with the columns "employeeID", "lastName", and "firstName".

Then we start the loop, from 0 to recordCount. The first line of code inside the loop creates a variable called "itemToAdd". Inside the curly brackets we have a number of name-value pairs (you always use curly brackets to indicate name-value pairs in ActionScript). The "name" part of the name-value pair is the column name. We're simply saying here "put the following value into this column". The "value" part of the name-value pair is the value from our array we just built, but it uses the index "i" so it pulls only the specific element we're looking for. Excellent. The same is true for the other two name-value pairs.

Finally, the last line of the code inside the loop adds the variable "itemToAdd" as a record to the RecordSet. Notice that we are using the object method "addItem(record)". This method takes only one parameter: a record to add, and this record has to be a list of all the name-value pairs for each column. A note of interest: we have used dynamic values in our "itemToAdd" variable for the value of the name-value pair, but I have not figured out a way to produce the "name" part of the name-value pair dynamically. If anyone has any ideas, let me know!

Okay, so we're done putting the records into the RecordSet. We've simply looped through each record, each time constructing an "itemToAdd" of the values from our arrays, then adding that "itemToAdd" into the RecordSet. Now we have a RecordSet that has our values and is very easy to work with.

If you want to test it, we can do this (still inside the "processVars()" function):

// loop through each record
for (var i=0; i < recordCount; i++) {
var thisRecord = myRecords.getItemAt(i); // get the current record for row "i" and set it to "thisRecord"
trace(thisRecord.employeeID + ", " + thisRecord.lastName + ", " thisRecord.firstName);
} // end looping through the records
As you can see, we use the RecordSet object method "getItemAt(recordNumber)" to retrieve the record at the specified row. Then we have that record as a variable named "thisRecord". Once there, we can refer to each column simply by typing the name of the column after the period. This should display all the records in the output window when you test the movie.

Okay, that's pretty much it, the RecordSet should be working. That's the process: first create a textfile with your database records, then import that textfile into a LoadVars() object, then put those values into a RecordSet. Now you can manipulate your RecordSet however you want, using any of the methods that come along with the RecordSet.

Just for kicks, let's display the RecordSet in a nicely formatted textfield (delete the last block of code that traced the values and replace it with this code):

// Just for kicks lets display this information in Flash dynamically
// --------------------------------------------------------------
this.createEmptyMovieClip("displayResults_mc",0); // create empty movieclip to "hold" the records
this.displayResults_mc.createTextField("records_txt",1,10,10,300,300); // create textfield for the records
// loop through the records, adding to the text field
var resultText = "";
for (var i=0; i < myRecords.getLength(); i++) {
var thisRecord = myRecords.getItemAt(i);
// this line has a problem, see the note after the code
resultText = resultText + "<b>employee no. " + thisRecord.employeeID + ":</b> " + thisRecord.firstName + " " + thisRecord.lastName + "<br>";
} // end looping through records

// format the textfield to look nice
var thisFormat = new TextFormat(); // create a new TextFormat object
thisFormat.font = "arial";
thisFormat.size = 12;
with (this.displayResults_mc.records_txt) {
html = true;
multiline = true;
wordWrap = true;
htmltext = resultText;
setTextFormat(thisFormat);
} // end "with" grouping
Note: the long line that displays "resultText" in this last bit of code has a problem. The final two quotes at the end, the ones which are empty right now, are supposed to have a "<br>" inside those two quotes, but it doesn't show up in the post. Be sure to display the "<br>" when you write this code yourself, otherwise your text won't line break.

You can, of course, do much more with these records. For example: for each record, you could create a nice little movieclip that has a nice border and a transparent background and display each of these in a scrollbox. Whatever you need to do.

retrotron

retrotron
05-13-2003, 04:17 PM
Here's all the code we did, in one place:

#include "RecordSet.as"

// create a new LoadVars object
var myVars = new LoadVars();

// import textfile variables into the LoadVars object
myVars.load("tbl_employeeData.txt");

// do this when the data is loaded
myVars.onLoad = function(success) {
// the "swonking" test: check whether data was properly loaded
if (success) { // data was successfully loaded
processVars(); // call this function to process the loaded variables
} else { // no data was loaded, display error
trace("Error: no data was loaded!");
} // end swonking test
} // end onLoad()

// the processing function called by the swonking function
function processVars() {

// convert the string variables into arrays that we can work with
// --------------------------------------------------------------

var columnList_arr = myVars.columnList.split(",");
var employeeID_arr = myVars.employeeID.split("|");
var lastName_arr = myVars.lastName.split("|");
var firstName_arr = myVars.firstName.split("|");
// get how many records there are
var recordCount = employeeID_arr.length;

// build the RecordSet, adding the values of the array into a RecordSet
// --------------------------------------------------------------

// create a new RecordSet
var myRecords = new RecordSet([columnList_arr]);
// loop through each record, sending each value into the RecordSet
for (var i=0; i < recordCount; i++) {
var itemToAdd = {employeeID: employeeID_arr[i], lastName: lastName_arr[i], firstName: firstName_arr[i]};
myRecords.addItem(itemToAdd);
} // end looping through each record

// --------------------------------------------------------------
// There, done. Now the information from the text file is in a RecordSet.
// Because it's a RecordSet, we have a plethora of useful methods to interface
// with the RecordSet. We could have simply worked with the arrays we
// built, but the RecordSet has such nice and easy methods that make accessing
// the records much less taxing on the brain.
// --------------------------------------------------------------

// Just for kicks lets display this information in Flash dynamically
// --------------------------------------------------------------
this.createEmptyMovieClip("displayResults_mc",0); // create empty movieclip to "hold" the records
this.displayResults_mc.createTextField("records_txt",1,10,10,300,300); // create textfield for the records
// loop through the records, adding to the text field
var resultText = "";
for (var i=0; i < myRecords.getLength(); i++) {
var thisRecord = myRecords.getItemAt(i);
// something strange happens with this next line when I post it, see the note after the code
resultText = resultText + "<b>employee no. " + thisRecord.employeeID + ":</b> " + thisRecord.firstName + " " + thisRecord.lastName + "<br>";
} // end looping through records

// format the textfield to look nice
var thisFormat = new TextFormat(); // create a new TextFormat object
thisFormat.font = "arial";
thisFormat.size = 12;
with (this.displayResults_mc.records_txt) {
html = true;
multiline = true;
wordWrap = true;
htmltext = resultText;
setTextFormat(thisFormat);
} // end "with" grouping

} // end processVars()
Note: the long line that displays "resultText" has a weird display problem: the final two quotes are supposed to have a "<br>" in them, but that <br> doesn't display on the page (for some reason I can't decipher). Be sure to manually insert the "<br>" in your own code before you run this.

subquark
05-13-2003, 06:54 PM
thanks for the flash remoting info, good stuff, a new area for me with my ongoing job search. how you doin' cyanblue?

CyanBlue
05-13-2003, 09:16 PM
Isn't retrotron, great??? You already did one tutorial on that subject, retrotron... That was pretty intense lecture and much appreciate it... ;)

subquark... Not much... Just killing time... Trying to get lazy as much as I can... :D

retrotron
05-13-2003, 09:26 PM
That was pretty intense lecture ... Unfortunately (for those reading my posts), I teach philosophy, so my natural way of communicating usually turns into lecture-detail information. Alas, Lady Brevity has not breathed her fortune on me. :)

DiDi
05-13-2003, 11:28 PM
I second my brother, this info is more than worth to be in the tutorial section... I just skimmed through, and can't wait to have enough time to dig in thoroughly... :)

retrotron, you just made my day... Seeing people who, like me, have more humanities background, and still walk (run...) freely in the OOP grounds, was just the encouragement I needed... ;)

We are grateful to Lady Brevity for breathing just the right amount of her fortune on you...

Cheers,

DD

retrotron
05-14-2003, 12:16 AM
DiDi - thanks! I Hope something here helps!

lecasn5 - Hey my friend, so we've done what we originally set out to do here. We've done it with a simple 3 record database, so you'll have to alter the original text file to match your 4000+ records database. Since you're running this only from a cd-rom, that shouldn't be too slow . . . it might take a couple of seconds to load a textfile that large into flash, but I doubt it will take much longer.

Also, typing out a textfile with 4000+ records would be no fun at all, so use a php, coldfusion, etc. script to generate the textfile. Let me know if you have anymore questions.

retrotron

retrotron
05-14-2003, 01:27 AM
It occurred to me that we ought to do this in XML too. The idea would be to do the same thing, except we'd use an xml file instead of a flat text file.

Here's my xml file:


<?xml version="1.0"?>
<employeeData>
<title>tbl_employeeData</title>

<columnList>
<item id="0">employeeID</item>
<item id="1">lastName</item>
<item id="2">firstName</item>
</columnList>

<data>
<employeeID>
<item id="0">1</item>
<item id="1">2</item>
<item id="2">3</item>
</employeeID>

<lastName>
<item id="0">Johnson</item>
<item id="1">Handy</item>
<item id="2">Knightly</item>
</lastName>

<firstName>
<item id="0">Randy</item>
<item id="1">Jack</item>
<item id="2">I.P.</item>
</firstName>
</data>
</employeeData>
And here's the code that does the same thing as before, it just uses the xml file:

#include "RecordSet.as"

// create a new xml object
var myxml = new XML();
myxml.ignoreWhite = true; // ignore the white space

// do this when xml loads
myxml.onLoad = function(valid) {
if (valid) {
processXML();
} else {
trace("Error: the XML appears to be invalid.");
} // end "if valid" statement
} // end onLoad()

// load the xml document
myxml.load("tbl_employeeData.xml");

function processXML() {

// convert xml information into arrays
// ------------------------------------------------------

// set the main nodes variables
var mainNode = myxml.firstChild;
var titleNode = myxml.firstChild.firstChild;
var columnNode = myxml.firstChild.firstChild.nextSibling;
var dataNode = columnNode.nextSibling;
var recordCount = dataNode.firstChild.childNodes.length;

// create and populate columnList array
var columnNodes = columnNode.childNodes;
var columnList = new Array();
for (var i=0; i < columnNodes.length; i++) { // loop through columnNodes
columnList[i] = columnNodes[i].firstChild.nodeValue;
} // end looping through columnNodes

// create and populate employeeID array
var employeeIDNodes = dataNode.firstChild.childNodes;
var employeeID_arr = new Array();
for (var i=0; i < employeeIDNodes.length; i++) { // loop through employeeIDs
employeeID_arr[i] = employeeIDNodes[i].firstChild.nodeValue;
} // end looping through employeeIDs

// create and populate lastName array
var lastNameNodes = dataNode.firstChild.nextSibling.childNodes;
var lastName_arr = new Array();
for (var i=0; i < lastNameNodes.length; i++) { // loop through lastNames
lastName_arr[i] = lastNameNodes[i].firstChild.nodeValue;
} // end looping through lastNames

// create and populate firstName array
var firstNameNodes = dataNode.firstChild.nextSibling.nextSibling.childN odes;
var firstName_arr = new Array();
for (var i=0; i < firstNameNodes.length; i++) { // loop through firstNames
firstName_arr[i] = firstNameNodes[i].firstChild.nodeValue;
} // end looping through firstNames

// build the RecordSet, adding the values of the array into a RecordSet
// --------------------------------------------------------------

// create a new RecordSet
var myRecords = new RecordSet([columnList_arr]);
// loop through each record, sending each value into the RecordSet
for (var i=0; i < recordCount; i++) {
var itemToAdd = {employeeID: employeeID_arr[i], lastName: lastName_arr[i], firstName: firstName_arr[i]};
myRecords.addItem(itemToAdd);
} // end looping through each record


// Just for kicks lets display this information in Flash dynamically
// --------------------------------------------------------------
this.createEmptyMovieClip("displayResults_mc",0); // create empty movieclip to "hold" the records
this.displayResults_mc.createTextField("records_txt",1,10,10,300,300); // create textfield for the records
// loop through the records, adding to the text field
var resultText = "";
for (var i=0; i < myRecords.getLength(); i++) {
var thisRecord = myRecords.getItemAt(i);
var employeeString = "<b>employee no. " + thisRecord.employeeID + ":</b> ";
var nameString = thisRecord.firstName + " " + thisRecord.lastName + "<br>";
resultText = resultText + employeeString + nameString;
} // end looping through records

// format the textfield to look nice
var thisFormat = new TextFormat(); // create a new TextFormat object
thisFormat.font = "arial";
thisFormat.size = 12;
with (this.displayResults_mc.records_txt) {
html = true;
multiline = true;
wordWrap = true;
htmltext = resultText;
setTextFormat(thisFormat);
} // end "with" grouping

} // end processXML()
Notice that the only stuff that's different is the code that loads an xml file and then converts the information into arrays. These are (conveniently) the same arrays that the code used earlier to add the items to the RecordSet. The last part of the code is thus unchanged from before.

Of course, the parsing of the xml could probably be seriously opitimized, but it's easier to understand like this.

lecasn5
05-14-2003, 10:38 AM
Well, what can I say, thank you so much for your time and knowledge. It's obvious you get pleasure from teaching! The thourough explanations were very precious. I'm still working around on how to apply the script to my exact needs but I'll get there.
I'm also having some problems due to my poor knowledge on some basic stuff on ActionScript: one thing is to mimetize something you already know it's going to work, other thing is to fully understand and problematize (don't know if this is good English) what you have learned. It's a lack of foundation. Speaking of foundation, my first and only book on AS was Foundation ActionScript from Friends of Ed. I stopped before I got to the end because at some point the authors started assuming that the reader has previous knowledge and understands certain concepts (function for instance). All this just to ask you if you know a good book on ActionScript that starts from scratch. Where do you started?

I guess that's it

Thanks again

P.S.

Is there some forum on Philosophy?(LOL) My background is Fine Arts with a strong scope on aesthetics. It would be nice changing some ideas with you

retrotron
05-14-2003, 03:42 PM
Hi lecasn5,

Great. Feel free to post any questions you have about your code, and don't hesitate to put up some problem code too . . . I'm sure we could figure it out if needed.

There are two Foundation ActionScript books: one is just Foundation ActionScript and the other is Foundation ActionScript for Flash MX. The latter is much better than the first, but maybe you're referencing the latter. I found the Friends of Ed Macromedia Flash MX Designer's ActionScript Reference to be helpful, especially the first couple hundred pages. Other than that, most beginner books are terrible.

Okay, here's my short rant: the problem for us humanities types is that books usually take a "tutorial" approach and explain what to do rather than explain why you do it that way. I.e. they explain the practical and not the theoretical. Even if they try and explain the "whys" they almost never really do (that's where they start assuming things, like you say). I haven't really found a book on ActionScript that explains things in a helpful way (not for the way my brain works, anyways).

The two good books that I really get a lot from (but they're not beginner books) are Robert Penner's Programming Macromedia Flash MX and Colin Moock's 2nd edition ActionScript for Flash MX: The Definitive Guide. These are fairly helpful once you get a little ActionScript under your belt.

Any philosophy forums? I'm sure there are plenty out there, but alas, I am not subscribed to any of them. Aesthetics, eh? Very cool!

retrotron

PS. Your mimetize and problematize is great English, I completely understand. I even say it's a clever way of putting it.

retrotron
05-14-2003, 04:56 PM
Okay, this is my last long rant for this thread. I promise. :)

We’ve done this with a textfile and with xml, but we might as well carry it out to the end and build a custom class which does all this. Such would certainly be useful to someone curious how to do that. I knew that explaining all that Object Oriented stuff would come in handy later. ;) I'm going to explain how to turn what lecasn5 and I have done so far into a custom class.

When you build a custom class, the first thing you have to do is define the constructor. The constructor is, simply put, the function which is called when you create a new instance of the class. Suppose we want to create a custom class called “Square”. The constructor function is simply defined like any other function:


// define the Square class constructor function
function Square() { // do these commands when a new instance is created
// commands here
} // end Square class constructor function definition
Once you define a constructor function, you have created a custom object. We can now create a new instance of the class if we want, just like we would create a new instance of any other object:


var mySquare = new Square();
Now we have an instance of the Square class which is named “mySquare”. When we create this instance here, all the commands which are defined in the Square() constructor function are executed (and this is done for each instance we create).

Just a note on the constructor function. It is customary to capitalize the names of classes. ActionScript doesn’t much care, but it’s good practice to set a class/object apart from simple variables by capitalizing the first letter. Apart from this first capital letter, the constructor function is no different from any other function. This means it could function as a mere function or as a constructor function. Thus, the burden for keeping track of which functions do what is up to the code architect.

Creating a custom class is basically that simple: create a constructor function and you’re class is defined. Then you can create as many instances of the class as you like. Well and good.

Now all that’s left is to define the methods of the class. To define a method of a class, you attach a function to the prototype of the class. Every class has a “prototype”. When you add methods to the class in ActionScript, you don’t actually add methods to the class, you add them to the class prototype.

Suppose our Square class has a property called “width”. It would be useful if our Square class had a method which returns this “width” property. To add this method to the class, we add it to the class prototype as such:


// define the getWidth() definition for the Square class
Square.prototype.getWidth = function() {
return this.width;
} // end Square.getWidth() method definition
Note first that we added the method to the prototype of the Square class. Note second that this is also just a standard function with the sole exception that it is attached to the Square prototype. Finally, note third that we used the “this” keyword to refer to the “width” property. Whenever you refer to an object’s property inside the constructor or method functions, you will refer to it with the “this” keyword. It simply means that you are telling ActionScript the property you are referencing belongs to “this”, i.e. the current object.

Once you have defined a method for your class, you can execute it by appending it to the instance name of your object: instanceName.methodName();. In the case of our Square class, we can first create a new instance, then execute the method “getWidth()”:


var mySquare = new Square(); // create a new instance of the Square class called “mySquare”
mySquare.getWidth(); // execute the “getWidth()” function of the “mySquare” instance
Since the getWidth() method returns a value, we could use this method in many ways, perhaps like this:


var thisWidth = mySquare.getWidth(); // assign the width of “mySquare” to “thisWidth”
So all in all, we have this code which defines our Square class:


// ------------------------------------------------------------
// the Square class
// ------------------------------------------------------------
// define the Square class constructor function
function Square() { // do these commands when a new instance is created
// commands here
} // end Square class constructor function definition

// define the getWidth() definition for the Square class
Square.prototype.getWidth = function() {
return this.width;
} // end Square.getWidth() method definition
// ------------------------------------------------------------
And then we can use it:


var mySquare = new Square(); // create a new instance of the Square class
trace(mySquare.getWidth()); // trace the width by executing the getWidth() method
Okay, that’s pretty much it for how to define a custom class. What I want to do is turn what we did earlier into a custom class. Since a textfile that serves as a database is often called a “flat text database”, let’s call our custom class “FlatDB”.

First we define the constructor:


// define FlatDB constructor
function FlatDB(name,parent) {
this.name = name;
this.parent = parent;
} // end FlatDB Constructor definition
Here our constructor takes two parameters: name and parent. The “name” is the name of the instance that is created, and “parent” is the name of the object in which the instance is created. They are each assigned to a property of the class: this.name and this.parent respectively. This is simply so that we can refer to the name and parent of the current instance from within our class constructor and method functions if we need to (this often comes in handy). So to create a new instance of the class, we’d do it like this:


var myFlatDB = new FlatDB(“myFlatDB”,this);
This lets “myFlatDB” get assigned to this.name, and the value of “this” (which is _root if this code is on the main timeline) is assigned to this.parent. Okay, that’s the constructor function.

Now we need to define the methods. Let’s do it for the textfile first, and then we can add on the xml methods later.

First, we want to write the method which loads the textfile into the LoadVars object:


FlatDB.prototype.loadText = function(textFile) {
// textFile: the url of the textfile to load
this.flatDB = new LoadVars(); // create a new LoadVars object
this.flatDB.parent = this; // set "this" as a property of the LoadVars object
this.flatDB.onLoad = this.swonkText; // set the swonking method
this.flatDB.load(textFile); // load the textfile
} // end FlatDB.loadText() method definition
This method takes one parameter: the url of the textfile to load. This can be absolute or relative, it doesn’t matter. First we create a new LoadVars object named “flatDB”. However, notice that we made it a property of the current instance. This means that this LoadVars object is only accessible from within this class, namely as a property of this class. Anytime we want to refer to it from within the class, we have to say “this.flatDB”, and anytime we want to refer to it from outside the class, we have to use the instance name: in this case “myFlatDB.flatDB”. Then we create a property called “parent” which equates to “this”. I’ll explain why we need this in the next method. Then we define that the onLoad function to be called will be named “swonkText”. This is the name of a method, which is part of “this” class. Finally, we load the text into the this.flatDB LoadVars object. The only thing we’ve really changed from before is making everything into a property of the class: it is all contained within the class. Everything we create or work with in this class is not some object floating around on ActionScript’s main timeline, it is self-contained within the class. This is called encapsulation: everything stays “inside”.

Great, that method is done. If we want to load our textfile into the class, we create a new instance of the class, then execute the “loadText()” method like so:


var myFlatDB = new FlatDB(“myFlatDB”,this);
myFlatDB.loadText(“tbl_employeeData.txt”);
This will do all that is defined in the method loadText(). Of course, it will call the “swonkText()” method when the data loads, so we need to define that method:


FlatDB.prototype.swonkText = function(success) {
var thisName = this.parent.name; // thisName = FlatDB object, "this" = LoadVars object
if (success) { // data was successfully loaded
eval(thisName).processVars(); // call this function to process loaded text
} else { // no data was loaded, display error
trace("Error: textfile failed to load.");
} // end swonking test
} // end FlatDB.swonkText() method definition
This is pretty much your standard swonking function, defined here as a method of FlatDB. The only thing to note is the use of the “thisName” variable. Here is one of the few exceptions of the use of “this” inside class definition functions. When an onLoad() function is called, the value of “this” refers to the object which called the onLoad function. In our case, that is not the FlatDB object; rather it is the LoadVars object. Thus, if we were to refer to “this”, it would point to this.flatDB rather than “myFlatDB”. That means that once we are inside the onLoad() function, we cannot reference the class, we can only reference the LoadVars object. So I added a property to the LoadVars object itself which tells us the name of the class. Once we get inside the onLoad() function, we simply need to retreive that name from the LoadVars object. So the first line of code in this method creates the variable “thisName” which has as its value the LoadVars property “parent” (which in turn, if you look back to the loadText() method, has as its value this.name). Now, notice the “eval(thisName).processVars();” line of code. The eval() command simply tells ActionScript to evaluate what’s in the parentheses before it executes the line of code, so it evaluates to this: “myFlatDB.processVars();”. This is a call to another method of our FlatDB class (which we haven’t defined yet) called processVars(). Earlier we had the swonking function call the “processVars()” function, so it makes sense to turn “processVars()” into a method of our FlatDB class. Okay, that pretty much covers this method.

Now we’re ready to define the processVars() method. Here is the code:


FlatDB.prototype.processVars = function() {
// convert the string variables into arrays that we can work with
this.columnList = this.flatDB.columnList.split(",");
this.employeeID_arr = this.flatDB.employeeID.split("|");
this.lastName_arr = this.flatDB.lastName.split("|");
this.firstName_arr = this.flatDB.firstName.split("|");
this.recordCount = this.employeeID_arr.length; // get how many records there are
// convert these arrays into a RecordSet and display them
this.dbToRecordSet();
this.displayRecordSet();
} // end FlatDB.processVars() method definition
You’ll notice that the code is almost exactly the same as the earlier version of “processVars()”, except here we use “this” a lot more. All we’re doing here is turning each of these arrays into not some array that is floating around on ActionScript’s _root timeline but as arrays that are themselves properties of the FlatDB class. I.e. we’re encapsulating these variables. The reason we want to do this is so that these properties can be used by other methods and we don’t have to pass them as arguments from function to function. If they are properties of the class itself, then every method for that class has access to the class properties.

The last two lines of code in this method call two other methods that we haven’t defined yet. The first will contain the code which converts these arrays into a RecordSet, and the second will contain the code that displays the RecordSet. Here is the code for the dbToRecordSet() method:


FlatDB.prototype.dbToRecordSet = function() {
// build the RecordSet, adding the values of the array into a RecordSet
this.records = new RecordSet([this.columnList]); // create a new RecordSet
// loop through each record, sending each value into the RecordSet
for (var i=0; i < this.recordCount; i++) {
var itemToAdd = {employeeID: this.employeeID_arr[i], lastName:
this.lastName_arr[i], firstName: this.firstName_arr[i]};
this.records.addItem(itemToAdd);
} // end looping through each record
} // end FlatDB.dbToRecordSet() method definition
You’ll notice again that there is not much that has changed from our code before. The only thing that is different is the use of “this” to (again) make all these variables properties of the FlatDB object. After this method executes, then FlatDB has a property called “records”. This property consists of the RecordSet. So now it is easy to refer to the RecordSet: instanceName.records:


myFlatDB.records; // this references the RecordSet, a property of the “myFlatDB” instance
Finally, we add the method for displaying the records:


FlatDB.prototype.displayRecordSet = function() {
// create the movieclip and textfield to display the records
_root.createEmptyMovieClip("displayResults_mc",0);
_root.displayResults_mc.createTextField("records_txt",1,10,10,300,300);
// loop through the records, adding to the text field
var resultText = "";
for (var i=0; i < this.records.getLength(); i++) {
var thisRecord = this.records.getItemAt(i);
var employeeString = "<b>employee no. " + thisRecord.employeeID + ":</b> ";
var nameString = thisRecord.firstName + " " + thisRecord.lastName + "<br>";
resultText = resultText + employeeString + nameString;
} // end looping through records
// format the textfield to look nice
var thisFormat = new TextFormat(); // create a new TextFormat object
thisFormat.font = "arial";
thisFormat.size = 12;
with (_root.displayResults_mc.records_txt) {
html = true;
multiline = true;
wordWrap = true;
htmltext = resultText;
setTextFormat(thisFormat);
} // end "with" grouping
} // end FlatDB.displayRecordSet() method definition
Again, this is all the same, with the exceptions of changing things around to work with “this” whenever possible. There’s one semi-sticky point here: I changed what used to be “this” to “_root”. This is because earlier “this” referred to “_root”. However, now that this function is a method of the FlatDB class, “this” refers to the object. Drawing movieclips and textfields can only be drawn inside other movieclips, and FlatDB is an object, not a movieclip. So if we tried to create an empty movieclip in “this” (i.e. in the FlatDB object), it would fail and return an undefined.

There, done. That’s the custom class for our FlatDB which imports the textfile. Here is the full code for the class we’ve done so far:


#include "RecordSet.as"

// ************************************************** *****************************
// FlatDB Class //

// define FlatDB constructor
function FlatDB(name,parent) {
this.name = name;
this.parent = parent;
} // end FlatDB Constructor definition

// methods dealing with text file
// ---------------------------------------------------

FlatDB.prototype.loadText = function(textFile) {
// textFile: the url of the textfile to load
this.flatDB = new LoadVars(); // create a new LoadVars object
this.flatDB.parent = this; // set "this" as a property of the LoadVars object
this.flatDB.onLoad = this.swonkText; // set the swonking method
this.flatDB.load(textFile); // load the textfile
} // end FlatDB.loadText() method definition

FlatDB.prototype.swonkText = function(success) {
var thisName = this.parent.name; // thisName = FlatDB object, "this" = LoadVars object
if (success) { // data was successfully loaded
eval(thisName).processVars(); // call this function to process loaded text
} else { // no data was loaded, display error
trace("Error: textfile failed to load.");
} // end swonking test
} // end FlatDB.swonkText() method definition

FlatDB.prototype.processVars = function() {
// convert the string variables into arrays that we can work with
this.columnList = this.flatDB.columnList.split(",");
this.employeeID_arr = this.flatDB.employeeID.split("|");
this.lastName_arr = this.flatDB.lastName.split("|");
this.firstName_arr = this.flatDB.firstName.split("|");
this.recordCount = this.employeeID_arr.length; // get how many records there are
// convert these arrays into a RecordSet and display them
this.dbToRecordSet();
this.displayRecordSet();
} // end FlatDB.processVars() method definition

FlatDB.prototype.dbToRecordSet = function() {
// build the RecordSet, adding the values of the array into a RecordSet
this.records = new RecordSet([this.columnList]); // create a new RecordSet
// loop through each record, sending each value into the RecordSet
for (var i=0; i < this.recordCount; i++) {
var itemToAdd = {employeeID: this.employeeID_arr[i], lastName:
this.lastName_arr[i], firstName: this.firstName_arr[i]};
this.records.addItem(itemToAdd);
} // end looping through each record
} // end FlatDB.dbToRecordSet() method definition

FlatDB.prototype.displayRecordSet = function() {
// create the movieclip and textfield to display the records
_root.createEmptyMovieClip("displayResults_mc",0);
_root.displayResults_mc.createTextField("records_txt",1,10,10,300,300);
// loop through the records, adding to the text field
var resultText = "";
for (var i=0; i < this.records.getLength(); i++) {
var thisRecord = this.records.getItemAt(i);
var employeeString = "<b>employee no. " + thisRecord.employeeID + ":</b> ";
var nameString = thisRecord.firstName + " " + thisRecord.lastName + "<br>";
resultText = resultText + employeeString + nameString;
} // end looping through records
// format the textfield to look nice
var thisFormat = new TextFormat(); // create a new TextFormat object
thisFormat.font = "arial";
thisFormat.size = 12;
with (_root.displayResults_mc.records_txt) {
html = true;
multiline = true;
wordWrap = true;
htmltext = resultText;
setTextFormat(thisFormat);
} // end "with" grouping
} // end FlatDB.displayRecordSet() method definition

// end FlatDB Class definition //
// ************************************************** *****************************
Be sure to remember to include the RecordSet.as file. Now that this code is all here, you can create a new instance and import the textfile into a RecordSet with these two simple lines of code:


var myFlatDB = new FlatDB(“myFlatDB”,this);
myFlatDB.loadText(“tbl_employeeData.txt”);
When you test this code, you should see exactly what we got before. What’s the advantage of making it a custom class? Well, it’s reusable. Another nice feature is being able to place the class code in an external text file and then simply include it. If you save all the code between the star-lines above in a file called “FlatDB.as”, then you can use it simply by including it. The above can then be accomplished with an #include rather than typing in all the class code:


#include “FlatDB.as”

var myFlatDB = new FlatDB(“myFlatDB”,this);
myFlatDB.loadText(“tbl_employeeData.txt”);
That’s much simpler and easy to use later on, especially if the application gets pretty script-heavy. If we wanted to, we could expand the class to work with any database textfile (or xml file), but that would be a good deal more complicated. If anybody wants to do that, please do post your code so we can all see it!

Okay, that’s the end of my rant on object oriented programming and doing this as a class. I’ll restrain my lack of brevity now.

retrotron

PS. I’ll post the entire class with the xml methods too.

retrotron
05-14-2003, 05:06 PM
Here's the full class, with xml and textfile methods. If you put all this code posted below into a file called "FlatDB.as", then you can simply include it and then run it with two lines:


#include "FlatDB.as"

var myFlatDB = new FlatDB("myFlatDB",this);
myFlatDB.loadXML("tbl_employeeData.xml");
// or myFlatDB.loadText("tbl_employeeData.txt");
That simple. If anyone wishes to improve this class (which it needs, since right now it only parses the specific text and xml), definitely post the code so I can make use of the improvements.

Here's the full class:

#include "RecordSet.as"

// ************************************************** *****************************
// FlatDB Class //

// define FlatDB constructor
function FlatDB(name,parent) {
this.name = name;
this.parent = parent;
} // end FlatDB Constructor definition

// methods dealing with text file
// ---------------------------------------------------

FlatDB.prototype.loadText = function(textFile) {
// textFile: the url of the textfile to load
this.flatDB = new LoadVars(); // create a new LoadVars object
this.flatDB.parent = this; // set "this" as a property of the LoadVars object
this.flatDB.onLoad = this.swonkText; // set the swonking method
this.flatDB.load(textFile); // load the textfile
} // end FlatDB.loadText() method definition

FlatDB.prototype.swonkText = function(success) {
// thisName = FlatDB object, "this" = LoadVars object
var thisName = this.parent.name;
if (success) { // data was successfully loaded
eval(thisName).processVars(); // call this function to process loaded text
} else { // no data was loaded, display error
trace("Error: textfile failed to load.");
} // end swonking test
} // end FlatDB.swonkText() method definition

FlatDB.prototype.processVars = function() {
// convert the string variables into arrays that we can work with
this.columnList = this.flatDB.columnList.split(",");
this.employeeID_arr = this.flatDB.employeeID.split("|");
this.lastName_arr = this.flatDB.lastName.split("|");
this.firstName_arr = this.flatDB.firstName.split("|");
this.recordCount = this.employeeID_arr.length; // get number of records
// convert these arrays into a RecordSet and display them
this.dbToRecordSet();
this.displayRecordSet();
} // end FlatDB.processVars() method definition

// methods dealing with xml file
// ---------------------------------------------------

FlatDB.prototype.loadXML = function(xmlFile) {
// xmlFile: the url of the xml file to load
this.flatDB = new XML(); // create a new xml object
this.flatDB.parent = this; // set "this" as a property of the XML object
this.flatDB.ignoreWhite = true; // ignore the white space
this.flatDB.onLoad = this.swonkXML; // set the swonking method
this.flatDB.load(xmlFile); // load the xml file
} // end FlatDB.loadXML() method definition

FlatDB.prototype.swonkXML = function(success) {
// thisName = FlatDB object, "this" = XML object
thisName = this.parent.name;
if (success) {
eval(thisName).processXML();
} else {
trace("Error: XML failed to load.");
} // end "if valid" statement
} // end FlatDB.swonkXML() method definition

FlatDB.prototype.processXML = function() {
// convert xml information into arrays
// ------------------------------------------------------

// set the main nodes variables
var mainNode = this.flatDB.firstChild;
var titleNode = this.flatDB.firstChild.firstChild;
var columnNode = this.flatDB.firstChild.firstChild.nextSibling;
var dataNode = columnNode.nextSibling;
this.recordCount = dataNode.firstChild.childNodes.length;

// create and populate columnList array
var columnNodes = columnNode.childNodes;
var columnList = new Array();
this.columnList = columnList;
for (var i=0; i < columnNodes.length; i++) { // loop through columnNodes
this.columnList[i] = columnNodes[i].firstChild.nodeValue;
} // end looping through columnNodes

// create and populate employeeID array
var employeeIDNodes = dataNode.firstChild.childNodes;
var employeeID_arr = new Array();
this.employeeID_arr = employeeID_arr;
for (var i=0; i < employeeIDNodes.length; i++) { // loop through employeeIDs
this.employeeID_arr[i] = employeeIDNodes[i].firstChild.nodeValue;
} // end looping through employeeIDs

// create and populate lastName array
var lastNameNodes = dataNode.firstChild.nextSibling.childNodes;
var lastName_arr = new Array();
this.lastName_arr = lastName_arr;
for (var i=0; i < lastNameNodes.length; i++) { // loop through lastNames
this.lastName_arr[i] = lastNameNodes[i].firstChild.nodeValue;
} // end looping through lastNames

// create and populate firstName array
var firstNameNodes = dataNode.firstChild.nextSibling.nextSibling.childN odes;
var firstName_arr = new Array();
this.firstName_arr = firstName_arr;
for (var i=0; i < firstNameNodes.length; i++) { // loop through firstNames
this.firstName_arr[i] = firstNameNodes[i].firstChild.nodeValue;
} // end looping through firstNames

// convert these arrays into a RecordSet and display them
this.dbToRecordSet();
this.displayRecordSet();

} // end FlatDB.processXML() method definition

// methods dealing with converting to RecordSet and displaying the RecordSet
// ---------------------------------------------------

FlatDB.prototype.dbToRecordSet = function() {
// build the RecordSet, adding the values of the array into a RecordSet
this.records = new RecordSet([this.columnList]); // create a new RecordSet
// loop through each record, sending each value into the RecordSet
for (var i=0; i < this.recordCount; i++) {
var itemToAdd = {employeeID: this.employeeID_arr[i], lastName:
this.lastName_arr[i], firstName: this.firstName_arr[i]};
this.records.addItem(itemToAdd);
} // end looping through each record
} // end FlatDB.dbToRecordSet() method definition

FlatDB.prototype.displayRecordSet = function() {
// create the movieclip and textfield to display the records
_root.createEmptyMovieClip("displayResults_mc",0);
_root.displayResults_mc.createTextField("records_txt",1,10,10,300,300);
// loop through the records, adding to the text field
var resultText = "";
for (var i=0; i < this.records.getLength(); i++) {
var thisRecord = this.records.getItemAt(i);
var employeeString = "<b>employee no. " + thisRecord.employeeID + ":</b> ";
var nameString = thisRecord.firstName + " " + thisRecord.lastName + "<br>";
resultText = resultText + employeeString + nameString;
} // end looping through records
// format the textfield to look nice
var thisFormat = new TextFormat(); // create a new TextFormat object
thisFormat.font = "arial";
thisFormat.size = 12;
with (_root.displayResults_mc.records_txt) {
html = true;
multiline = true;
wordWrap = true;
htmltext = resultText;
setTextFormat(thisFormat);
} // end "with" grouping
} // end FlatDB.displayRecordSet() method definition

// end FlatDB Class definition //
// ************************************************** *****************************
I promise I'll stop now.

flashdudette
07-18-2003, 03:12 PM
Can I ask a stupid question?
To get the as file you mentioned at the beginning, you suggested to download the flash remoting component. The flash remoting stuff is quite expensive. $ 999.
Can someone use the NetServices.as file without buying the flash remoting software? I am interested in looking into the database stuff for a project but I do not want to spend that kind of money right now.

retrotron
07-18-2003, 03:23 PM
Hi there flashdudette,

FlashRemoting components are a free download, they don't cost any money. The NetServices.as, Recordset.as, etc. are all files included in the download, so you'll get those from the download and can do database simulation like we discussed in this thread.

What costs money is the backend that works with the Flash Remoting. ColdFusion, for example, costs a hefty sum, but if you have CF, the Flash Remoting is already built in and you needn't pay any more. However, if you just want practice, you can use ColdFusion on your local machine all you want for free. Just download it and use it . . . when the 30 days expire it will then only work on your computer, you can't use it remotely anymore (but for development, this is just what you want). If you want to run a Java framework or something like that, then you have to pay that hefty price you mentioned to get Flash Remoting working.

There's another option that's totally free: PHP, MySQL, and AMFPHP. MySQL is your database, free, easy to use, easy to install, excellent. PHP is your scripting engine, also free, very powerful, a bit tricky to install, but well worth it as it's very much an industry standard. AMFPHP is the PHP version of Flash Remoting. AMFPHP allows Flash to communicate with PHP via remoting, just like Flash communicates with ColdFusion or Java via remoting.

Pax et bonum in Christi

flashdudette
07-18-2003, 03:33 PM
Hey, really cool.
I hate to mention the evil empire :D, but we are using MSaccess (we'll convert to mssql soon) and asp.
I suppose I can use the component with that, right ?

retrotron
07-18-2003, 03:37 PM
Yeah, but you need something to work in between the database and Flash . . . something like ColdFusion, PHP, Java, etc. I.e. Flash can't connect to a database directly, but it can connect to some of these middle men like CF/PHP/etc. (this is what remoting does: connects Flash to these middle men). It's the middle men that connect to the database, query for info, then send the results back to Flash.

But yeah, it really doesn't matter which database you're using, as CF/PHP/etc. can all connect to many kinds of databases, and MSAccess is included. ;)

flashdudette
07-18-2003, 03:46 PM
In our case ASP is the middle man, I think. I guess I'll download the components and start playing with them. Thanks. :)

freddycodes
07-18-2003, 05:10 PM
Great stuff rertotron, if I could make a few suggestions.

XML is not a good choice for 4000+ plus records, I can see Flash choking right now, without even testing.

Another thing to keep in mind, is when you use the format you did for the text file, the old query string format, flash has to decode that stuff and make name/value pairs out of it. It is possible to use the LoadVars onData handler to bypass that. Check it out.
flatDB.txt

employeeID|lastName|firstName
1|Johnson|Randy
2|Handy|Jack
3|Knightly|I.P.




#include "NetServices.as"

myVars = new LoadVars();
myVars.load("flatDB.txt");
myVars.onData = function(raw) {
var delim = (raw.indexOf("\r\n") > -1) ? "\r\n" : (raw.indexOf("\r") > -1) ? "\r" : "\n";
var temp = raw.split(delim);
myRecordSet = new RecordSet(temp.shift().split("|"));
fields = myRecordSet.getColumnNames();
for(var i=0;i<temp.length;i++) {
var row = temp[i].split("|");
if(row.length != fields.length) continue;
var tmpObj = {};
for(var j=0;j<row.length;j++) {
tmpObj[fields[j]] = row[j];
}
myRecordSet.addItem(tmpObj);
}

}


This has some unique advantages, one readability of the text file. Second skipping the creation of name/valuie pairs in flash, which might start show with 4000+ items.

retrotron
07-19-2003, 01:27 AM
Sweet freddycodes, that's a nice trick. We needed you with this insight when this thread was originally happening. :)

Lecasn may have long finished this project, but I still have the FlatDB class in my files (and use it on occasion), so I'll add your nice little onData move. Excellent.

flashdudette
07-21-2003, 09:17 AM
How could I structure the text file with the following needed information:
course
chapter
page
text
caption

I want to have a form that allows the course editor person to go to a course, choose a chapter, choose a page and then edit the text and caption. So the structure is more complicated since I have several courses, several chapters in a course, and several pages in a chapter.

Allow have you checked the Flashpash stuff? http://flashpash.sshnug.com/about.php

flashdudette
07-21-2003, 09:48 AM
I am so new to this stuff, could you tell me :confused: how do I get the info in the combobox, listbox and text fields from the recordset.
Also, about the remoting components, is this only the as files? or is there something visible in the component window? I cn'at see anything.
Sorry, there's got to be an idiot asking the idiot questions, and this seems to be my job today.:rolleyes:

retrotron
07-22-2003, 02:40 AM
about the remoting components, is this only the as files? or is there something visible in the component window?

Well, yes, it's just the as files. there shouldn't be anything in the component window. All questions are welcome at as.org. :)

I am so new to this stuff, could you tell me how do I get the info in the combobox, listbox and text fields from the recordset

As for the text fields, see the code I wrote earlier in the thread. After all the recordset stuff is done, there's some code for creating some textfields and displaying the recordset information in the textfields. As for combobox, listbox, etc. check out the macromedia documentation, they have some basic info on doing that:
http://livedocs.macromedia.com/frdocs/Using_Flash_Remoting_MX/UseASData6.jsp#1170158

This is also useful:
http://www.macromedia.com/support/flash_remoting/ts/documents/presalesfaq.htm#displayresults

I want to have a form that allows the course editor person to go to a course, choose a chapter, choose a page and then edit the text and caption. So the structure is more complicated since I have several courses, several chapters in a course, and several pages in a chapter.
How complicated things get generally doesn't matter if you set up the database right (or set up the fake textfile database right).

I'll have to think about how to set up the database to do this, because my brain isn't working quite right now as I'm working a graveyard. In any case, it's a simple task, no worries. ;)

flashdudette
07-22-2003, 08:14 AM
Thanks for the threads. I'll study those and see what I can do with them. :)

freddycodes
07-22-2003, 12:21 PM
You can use DataGlue to bind a recordset to a listbox or combobox. See the reference under the remoting section in the reference panel. Your code might looke like.


#include "NetServices.as"
#include "DataGlue.as"
myVars = new LoadVars();
myVars.load("flatDB.txt");
myVars.onData = function(raw) {
var delim = (raw.indexOf("\r\n") > -1) ? "\r\n" : (raw.indexOf("\r") > -1) ? "\r" : "\n";
var temp = raw.split(delim);
myRecordSet = new RecordSet(temp.shift().split("|"));
fields = myRecordSet.getColumnNames();
for(var i=0;i<temp.length;i++) {
var row = temp[i].split("|");
if(row.length != fields.length) continue;
var tmpObj = {};
for(var j=0;j<row.length;j++) {
tmpObj[fields[j]] = row[j];
}
myRecordSet.addItem(tmpObj);
}
//Bind the recordset to the list box, setting the last name to the label
//and the recordset index to the data
DataGlue.bindFormatStrings (lst_Emp, myRecordSet, "#lastName#", "#__ID__#");

//Set the change handler to show us the detail.
lst_Emp.setChangeHandler("showDetail");
}

function showDetail() {
//Attach our clip with the text fields
attachMovie("detailClip", "detailClip", 100, {_x:100,_y:lst_Emp._y});
//Get the record from the record set based on index passed from list box
var foo = myRecordSet.getItemAt(lst_Emp.getValue());
//Loop through record and find the corresponding text field in detailClip
//to assign the value to.
for(x in foo) {
detailClip[x].text = foo[x];
}
}


See attached

flashdudette
07-22-2003, 12:32 PM
This is great, FreddyCodes! Thanks for your taking the time to write it. I am sure many people will be grateful for it!

I am going to study the code and try to implement it.

I am also looking into using our database and asp to do the talking. But I know I also can use the flatdb for several different things.

Thanks again! :)

freddycodes
07-22-2003, 01:23 PM
Well where you get the data from is one thing, and its aways better to move the DAL or Data Access Layer outside of flash. Using the flat file approach the DAL is within Flash and makes changing it more diffcult. By putting the DAL in ASP, you remove that frmo the equation and changing databases, or table definitions means changing the ASP file not the .fla.

Anyways, after populating the RecordSet, everything else would be the same, and even using ASP, you can do the same thing I have done, by having ASP created the delimited text file for output to the screen, and flash can pick it up as its done in my example. Does that make since?


Here is how I could change it very easily to read from a asp script.

#include "NetServices.as"
#include "DataGlue.as"
myVars = new LoadVars();
myVars.load("http://freddyserver/relDB.asp");
myVars.onData = function(raw) {
var delim = (raw.indexOf("\r\n") > -1) ? "\r\n" : (raw.indexOf("\r") > -1) ? "\r" : "\n";
var temp = raw.split(delim);
myRecordSet = new RecordSet(temp.shift().split("|"));
fields = myRecordSet.getColumnNames();
for(var i=0;i<temp.length;i++) {
var row = temp[i].split("|");
if(row.length != fields.length) continue;
var tmpObj = {};
for(var j=0;j<row.length;j++) {
tmpObj[fields[j]] = row[j];
}
myRecordSet.addItem(tmpObj);
}
//Bind the recordset to the list box, setting the last name to the label
//and the recordset index to the data
DataGlue.bindFormatStrings (lst_Emp, myRecordSet, "#lastName#", "#__ID__#");

//Set the change handler to show us the detail.
lst_Emp.setChangeHandler("showDetail");
}

function showDetail() {
//Attach our clip with the text fields
attachMovie("detailClip", "detailClip", 100, {_x:100,_y:lst_Emp._y});
//Get the record from the record set based on index passed from list box
var foo = myRecordSet.getItemAt(lst_Emp.getValue());
//Loop through record and find the corresponding text field in detailClip
//to assign the value to.
for(x in foo) {
detailClip[x].text = foo[x];
}
}


The ASP script

<%@ Language = "VBScript" %>
<%
'set cnn = server.createobject("ADODB.Connection")
'cnn.open "PROVIDER=SQLOLEDB;DATA SOURCE=sqlservername;UID=username;PWD=password;DAT ABASE=databasename "

Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open "Provider=SQLOLEDB;Data Source=FREDDYSERVER\FREDDYSERVER;User Id=****;Password=********;Initial Catalog=flash"
Set objSql = Server.CreateObject("ADODB.Command")
Set objRS = Server.CreateObject ("ADODB.Recordset")
objRS.Open "Select * from Emp", objConn
Dim cnt
cnt = 0
'Response.Write(objRS.Fields.count)

for each x in objRS.Fields
Response.Write(x.name)
if cnt < objRS.Fields.count - 1 Then
Response.Write("|")
end if
cnt = cnt + 1
next
Response.Write(vbCrLf)

do until objRS.EOF
cnt = 0
for each x in objRS.Fields
Response.Write(trim(x.value))
if cnt < objRS.Fields.count - 1 Then
Response.Write("|")
end if
cnt = cnt + 1
next
Response.Write(vbCrLf)

objRS.MoveNext
loop

objConn.close()
Set objSql = Nothing
Set objRS = Nothing
Set objConn = Nothing
%>

flashdudette
07-22-2003, 01:47 PM
Man, you're faster to respond than I am to read the code!
I'll have to digest all this and I will let you know when I have it work for us.
Thank you very much!

CyanBlue
07-22-2003, 02:03 PM
There is a reason why I call him Masta... :)

Isn't he great??? :D

freddycodes
07-22-2003, 02:06 PM
Masta of Nothing that is.


Flashdudette, remember this sample assumes data is in SQL Server, but can be changed easily to grab from Access or whatever else your company uses.

flashdudette
07-22-2003, 02:29 PM
Well, we'll be moving to sql in the near future - but thanks for the info "Masta" :)

retrotron
07-22-2003, 05:52 PM
Masta of Nothing . . . very zen. Freddycodes realises deeply that all coding is ultimately impermanent, simply an illusionary moment in the process of eternal abstraction a la "satori". mmmm....zen. mmmmm....abstraction.

freddycodes
07-22-2003, 05:54 PM
Masta of Confusion!!!!

All programs as small as they may be solve a problem. Solving the problem is the hard part, the tool you use is relative to the tools in your toolbox.

flashdudette
07-24-2003, 08:58 AM
Do I need the jRUN4 software or are Flash, ASP and ACCESS (later MsSQL) sufficient to make all this work?

CyanBlue
07-24-2003, 09:58 AM
Your web host should provide you a server program usually Apache or IIS and that should be enough for you to run that sort of database interaction for ASP... Just my 2 cents... ;)

flashdudette
07-24-2003, 10:28 AM
I was just wondering because MM mentionned JRUN4 in the
"what you need for remoting" section.
Making some progress on this project. Lots to learn, but that's fun! :)
Thanks Mr. President :p

CyanBlue
07-24-2003, 11:18 AM
Mr. President??? :D

Your choice for Flash Remoting would be...
Flash Remoting MX/ColdFusion/JRun4 - Native support, I believe, $$$
PHP - through AMFPHP or PHPObject, free

Please add more if there is any other that supports Flash Remoting... :)

flashdudette
07-24-2003, 11:30 AM
Retroton mentioned that the remoting components can be used with ISS/ASP/MSAccess or MsSQL
sorry for mentioning the evil empire but that's what we're using here!
:rolleyes:

retrotron
07-24-2003, 08:16 PM
My email's been wacko for the past couple of days, I don't seem to be getting notified about these threads . . .

anyhoo . . .

you can use Remoting with .NET frameworks. I don't know much about .NET, but I thought that there was such a thing as a .NET version of ASP, in which case you can use Remoting with ASP. However, I believe you have to pay for that. JRun4 and ColdFusion MX come with Remoting already, if you want Remoting with .NET or SOAP, then you have to pay for Remoting. Does that help any?

retrotron
07-28-2003, 12:13 AM
Regarding freddycodes comment above about using onData to bypass the onLoad, he's explained it a bit more here:

http://www.actionscript.org/forums/showthread.php3?s=&threadid=31800

This is a very useful trick to understand and utilize when working with this kind of thing, so be sure to check that post out.

flashmani
09-07-2004, 11:40 AM
Great tut.....

can u people explain how can i add,delete, edit the recordset.....dynamically...

the following structure i need

displaying all the records

0--------------
1-------------
2--------------
add delete edit

the add, delete and edit buttons

add button adding the records from input text fields...after adding the records the added record will display immediatly...same in delete and edit also.....

after doing all these this things the save button is save in the xml file....

please explain me.......

my other post about this is here.....i did some work on that...but still now answer...

http://www.actionscript.org/forums/showthread.php3?t=53948

see this post for fla file

i thinks retrotron or freddycodes can answer me.....

without components is it possible.......

its better to explain in as2.0 becoz i am using flashmx2004 std version....

Flashmani