These instructions will help you create your first project using Flex FXT. For a description of FXT view the previous post. After you have downloaded the source code open a new Flex project.
1. Open your new Flex project. In the Navigator, go to the "html-template" directory and find the "index.template.html".
2. Make a copy of this file as backup. Name it something like, "index.template.original.html" or "whatever.html".
3. Open the "index.template.html" file. We are going to modify the following line:
-
"flashvars",'historyUrl=history.htm%3F&lconid=' + lc_id + '',
Change this line to:
-
"flashvars",'historyUrl=history.htm%3F&lconid=' + lc_id + '&model=' + escape( document.body.innerHTML ) + '',
Do you see what we are doing? We are grabbing the body of the html document and pulling it into our Flex app and assigning it to a variable. We can then access this variable through the Application.application.parameters object array. SAVE
NOTE! If you plan to use FXT more often you may want to add that code to your master html template page. If it was me I would rename the parameter variable to "htmlBody" because although it can be used as a model you can also use it as view into the html document. It may be possible to pull in the whole HTML document and not just the body. You would do this to view css, javascript and other information but I have not tested this.
NOTE! If you receive a "lc_id is undefined" error it is because, believe it or not, it is not defined on this HTML page. It is actually defined in JavaScript file. So if you get this error it means the history.js file is not being included. Check the paths to your includes.
4. Now we will place our data model in the HTML page. Insert the code below AFTER the body tag. It is important to add it AFTER the body tag. "Excuse me where do I add this data?" After the body tag. Copy and paste this text into your index.template.html page:
-
<script type="text/xml">
-
<!--TESTXML-->
-
<testxml>
-
<artist>Bob Dylan</artist>
-
<country>USA</country>
-
<company>Columbia</company>
-
<year>1985</year>
-
</cd>
-
<artist>Van Morrison</artist>
-
<country>UK</country>
-
<company>Polydor</company>
-
<year>1971</year>
-
</cd>
-
</testxml>
-
<!--TESTXML-->
-
<!--FXTMODEL-->
-
<!--REMOVE ME AND PLACE YOUR XML HERE-->
-
<!--FXTMODEL-->
-
</script>
This is the data we are storing in the html page. This is the model that we were talking about above. We can get this data at run-time and parse it into an xml object. We are using test xml here but the xml can be from any server side source. For example, php, asp, jsp, dvd, abc. Whatever. For now use this code for testing purposes. You will use your own data later. SAVE
6. Now, in your Flex app open up your MXML application, go into source view and paste in this code:
-
[Bindable]
-
public var model:XML;
-
-
// templateInit is called in the Application creationComplete event
-
public function templateInit():void
-
{
-
// the model is really the document body content, "document.body.innerHTML"
-
var strModel:String = unescape( Application.application.parameters.model );
-
//trace("the body is="+strModel);
-
-
// IMPORTANT NOTE!
-
// This code finds the xml between the TESTXML tags for testing purposes
-
// You must use FXTMODEL or whatever tag names you used in your
-
// page to see your data and not the test data
-
// ERRORS WILL GENERATE a Error #1088
-
// Find and extract the xml from between our test xml
-
var start:uint = strModel.indexOf( "<!--TESTXML-->" )+15;
-
var end:uint = strModel.lastIndexOf( "<!--TESTXML-->");
-
var xmlString:String = strModel.substring( start , end );
-
-
trace("the xml string is:\n"+xmlString);
-
-
// get the xml text and pass it into an xml object
-
model = new XML( xmlString );
-
-
trace("the xml from this page is:\n"+model);
-
-
if (model.name()!="TESTXML") {
-
// do stuff
-
trace("you are not grabbing the test xml! awesome!");
-
// assign it to a control. for example, a list, grid
-
// did you say the list works with xml? why yes i did
-
// myList.dataProvider = model.CD;
-
}
-
else {
-
trace("you are getting the test xml! awesome!");
-
trace("model.name()="+model.name());
-
-
}
-
}
7. Add creationComplete="init()" to your Application tag to pull in the data after the page loads.
-
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
-
creationComplete="init()">
8. Test your application. Look in the console and view the data that you are able to access.
Note: On testing this the first time the console "was not available". I could not see my trace statements. Make sure to close down all other instances of Flex in the browser and retry. I also received a "TypeError: Error #1088: The markup in the document following the root element must be well-formed." This is due to the XML not being formed correctly or more likely it is not even there. Trace the xmlString variable to make sure you are getting xml and the syntax is correct.
If you see data then you have successfully accessed your xml from the html.
Now you probably want to take this and put it in your own existing project. In that case view my other lame tutorial "Mixing your Flex app into an existing site". It is already done. Please request this so I know people are reading these things. :)
UPDATE!!!
This updated code adds a function that finds and parses the XML model out of the page. You only need to pass it the flash vars variable name and the comment tag string. It also includes comments on other errors that are likely to occur.
-
[Bindable]
-
public var model:XML;
-
-
// NOTE: Some code may be misformatted in the translation to html
-
public function returnXML(paramName:String, tagName:String):XML {
-
// the model is really the document body content. IE model = document.body.innerHTML
-
var strModel:String = unescape( Application.application.parameters[paramName] );
-
//trace("the body is="+strModel);
-
-
// IMPORTANT NOTE!
-
// This code finds the xml between the TESTXML tags by default. We do this for testing purposes
-
// You must change this to FXTMODEL or whatever tag name you used in your
-
// page to see your data and not the test data
-
// ERRORS WILL GENERATE if it does not find your tags or data. IE, Error #1088
-
-
// Find and extract the xml from between our test xml
-
// Why substring it? HTML is very rarely well formed XML
-
var start:uint = strModel.indexOf( tagName ) + tagName.length;
-
var end:uint = strModel.lastIndexOf( tagName );
-
var xmlString:String = strModel.substring( start , end );
-
//trace("the xml string is:\n"+xmlString);
-
-
// get the xml text and pass it into an xml object
-
//model = new XML( xmlString );
-
var xmlObj:XML = new XML( xmlString );
-
// Error #1088 see notes above
-
// Error #1009: node is not found or empty. possibly misspelled check your xml
-
// IE, trying to access xml.menuitems when the name is xml.menuitem or
-
// comparing the wrong type in an attribute:
-
// xml.menuitem.(@tabID=="2"); should be xml.menuitem.(@tabID==2);
-
-
// return the xml object
-
return xmlObj;
-
-
// this should really be put into a class that captures and handles errors
-
// ie, tagname not found error E#1088, no xml content between tags error E#1009,
-
// loop through parameters array and catch if "model" param tag exist
-
// find and parse nodes by nodeName rather than by comment string
-
// ie, pass in "myxml" and it extracts everything from "<myxml>" to ""
-
// etc
-
}
-
-
public function init():void
-
{
-
trace("creation complete");
-
-
// we are finding and parsing the xml from the document body content and returning an xml object
-
// first parameter is the flashvars parameter name, second is the beginning FXT comment tag
-
model = returnXML("model","<!--FXTMODEL-->");
-
-
if (model.name()!="TESTXML") {
-
// do stuff
-
trace("you successfully retrieved the '"+ model.name()+ "' xml object! awesome! you rule!");
-
trace("here is your xml model:\n"+model);
-
// assign it to a control. for example, a list, grid or your mom. yes, the list works with xml.
-
// myList.dataProvider = model.CD;
-
//populateLists(model);
-
}
-
else {
-
trace("you are getting the test xml! awesome!");
-
trace("model.name()="+model.name());
-
//populateLists(model);
-
}
-
}
Great to see you are still rocking! Thanks for the insight!
Hi Judah,
Thanks for providing such useful info about FXT! There isn't much out there beyond Ted Patrick's initial article in his blog. I'm starting to implement this feature and was wondering if embedding the XML Model in a "script tag" as you have shown in the example will allow search engines to find the Model data.
I've heard that search engines ignore content within "script tags." But I'm most definitely not an authority on SEO so I was just wondering if you had any insight into this issue?
Thanks again for sharing all of your great Flex knowledge with us thru your blog!
-Carl
From what I've read, content inside of script tags where type="text/xml" *is* searchable by search engines.
Note: I've been using ExternalInterface a lot lately and I think it may be a better choice for grabbing content off the page. You would call a javascript function that grabs the element with the xml and pass it back to your application. It is a lot less work.
What's even better is if you can use httpservice to get the xml content you need from the server. Though, if you want SEO then you would still through the xml on the page but for that reason only.
Hi Judah,
Thanks for the clarification about script tags and SEO.
I'll be sure to look at the ExternalInterface option too. It does sound like a lot less work. The appealing thing about FXT was that you could stay inside of Flex/Actionscript without going out to the browser/JavaScript.
But the deeper I dig into this stuff, the more I'm finding that you really need to know both environments so that you can use the best technology for the task at hand.
-Carl
[...] has some more details on using FXT. Looks like there’s a few different approaches in use, so I’ll need to put together my [...]