Dynamic XML with flex - actionscript-3

I'm trying to build a type of query GUI, which returns queries from a php script in xml format via an httpservice.
Each query returns different results
eg.
rep with most and leat quotes
store with highest $ value
I'm really stuck on how to display the queries and access the node names and values.
Here's an example of an xml:
<node>
<action>query</action>
<quotes name="Most Quotes">
<first>John</first>
<last>Smith</last>
<quote_num>71</quote_num>
</quotes>
<quotes name="Least Quotes">
<first>Dave</first>
<last>Cook</last>
<quote_num>6</quote_num>
</quotes>
</node>
Id like to present the data in a readable way.
Thanks

Here the example code for read your XML (it works perfectly):
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()" horizontalAlign="center">
<mx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.utils.ObjectUtil;
private var tempXML:XML;
public function init():void{
tempXML = myXML;
txtA.text = myXML.toString();
readXml();
}
public function readXml():void{
var str:String = "";
var myXML:XMLList = new XMLList(myXML);
for each(var node:XML in myXML){
str = str + "action:" + node["action"] + "\n";
for each(var obj2:XML in node.quotes){
str = str + " name:" + obj2.attributes().toXMLString() + "\n";
str = str + " first:" + obj2["first"] + "\n";
str = str + " first:" + obj2["last"] + "\n";
str = str + " quote_num:" + obj2["quote_num"] + "\n";
}
txtB.text = str;
}
}
]]>
</mx:Script>
<mx:XML id="myXML">
<node>
<action>query</action>
<quotes name="Most Quotes">
<first>John</first>
<last>Smith</last>
<quote_num>71</quote_num>
</quotes>
<quotes name="Least Quotes">
<first>Dave</first>
<last>Cook</last>
<quote_num>6</quote_num>
</quotes>
</node>
</mx:XML>
<mx:HBox width="100%">
<mx:TextArea id="txtA" width="400" height="400" />
<mx:TextArea id="txtB" width="400" height="400" />
</mx:HBox>
Note: This code was created in actionscript 3, but should also work in your version. Please try it and tell me if will be useful, otherwise I'll have to post a code for your version. Remember that there are many ways to do this, i posted this way because maybe is more simple.
You can try this HERE.
Please visit this link for more explanation Working with XML
Second Version
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()" horizontalAlign="center">
<mx:Script>
<![CDATA[
import mx.collections.XMLListCollection;
import mx.utils.ObjectUtil;
private var tempXML:XML;
public function init():void{
tempXML = myXML;
txtA.text = myXML.toString();
readXml();
}
public function readXml():void{
var str:String = "";
var quotes:XMLList = myXML.quotes;
str = str + "action:" + myXML["action"] + "\n";
for (var i:int = 0; i < quotes.length(); i++){
str = str + "----quote name:" + XMLList(quotes[i]).attributes().toXMLString() + "\n";
var quotes_child:XMLList = quotes[i].children();
for (var j:int = 0; j < quotes_child.length(); j++){
str = str + "--------" + XML(quotes_child[j]).name() + ":" + quotes_child[j] + "\n";
}
}
txtB.text = str;
}
]]>
</mx:Script>
<mx:XML id="myXML">
<node>
<action>query</action>
<quotes name="Most Quotes">
<first>John</first>
<last>Smith</last>
<quote_num>71</quote_num>
</quotes>
<quotes name="Least Quotes">
<first>Dave</first>
<last>Cook</last>
<quote_num>6</quote_num>
</quotes>
<quotes name="other">
<first>other_first</first>
<last>other_last</last>
<quote_num>other_num</quote_num>
<other_property>other_prop</other_property>
</quotes>
</node>
</mx:XML>
<mx:HBox width="100%">
<mx:TextArea id="txtA" width="400" height="400" />
<mx:TextArea id="txtB" width="400" height="400" />
</mx:HBox>
You can try this HERE.
Check that in this new version, I iterate over each child using a "for" statement with increment variable.

Here's a way to do it without knowing what the node names or attribute names will be
for each(var item : XML in yourXML.children()) {
trace(item.name());//this will get the name of the node
for each(var attribute : XML in item.attributes()) {
trace(attribute.name() + " = " + attribute.toXMLString()); // prints out the attribute names and values
}
}

Related

Listing huge amount files and directories include subdirectories in Adobe AIR

I am trying to list files and directories and copy all files existing into any other folder.
By the way, there are many files and directories more than 1000 000+.
Here is a part of code.
private function getFileList(sourceDir:String):void{
var file:File = File.userDirectory.resolvePath(sourceDir);
file.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
file.getDirectoryListingAsync();
}
private function directory_listing(e:FileListEvent):void{
var getfiles:Array = e.files;
for each(var item:File in e.files){
if(checkDir(item.nativePath)){
// It is a directory, more logic!
totalDirNum++;
item.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
item.getDirectoryListingAsync();
}
else{
// It is a file, more logic!
totalFileNum++;
if(analyzeFile(item) === true){
if(overwriteChk.selected === false){ // Don't overwrite same file
if(checkFile(destinationDir.nativePath + "\\" + item.name) === false){
copyInto(item, destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
copiedNum++;
}
else uncopiedNum++;
}
else{ // Overwrite same file
copyInto(item,destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
copiedNum++;
}
}
else{
skippedNum++;
}
}
}
As you see, it executes recursive directory_listing().
In case of little files and directories, it works clearly.
But, for example, in the following case it not works clearly(appear not responding.)
Root Directory : A!
A includes 500 000+ subdirectories.
Each subdirectories include 4 or 5 files and one or two subdirectories.
And also the subdirectoy include a 4 or 5 files.
So, I need to copy all files of "A" folder to the specific folder (B!).
Program is stopped in first before loop. i.e. Named "A" folder include huge subfolders, so when program run to select a "A" folder, then it is stopped just in "A" folder listing(stopped at getDirectoryListingAsyc()). So, actually it is not called recursive.
Here is my full source code.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="800" height="600"
title="eveningCopier - Niao Jina"
creationComplete="initApp()">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
public var sourceDir:File;
public var destinationDir:File;
public var totalDirNum:uint;
public var totalFileNum:uint;
public var copiedNum:uint;
public var skippedNum:uint;
public var uncopiedNum:uint;
public var startTime:String;
public var finishTime:String;
/**
* Boot Function
**/
public function initApp():void{
sourceBtn.addEventListener(MouseEvent.CLICK, click_sourceBtn);
destinationBtn.addEventListener(MouseEvent.CLICK, click_destinationBtn);
startBtn.addEventListener(MouseEvent.CLICK, click_startBtn);
totalDirNum = 0;
totalFileNum = 0;
copiedNum = 0;
skippedNum = 0;
uncopiedNum = 0;
}
/**
* Event Listener when click "Source" button
**/
protected function click_sourceBtn(e:MouseEvent):void{
sourceDir = new File();
sourceDir.addEventListener(Event.SELECT, select_source);
sourceDir.browseForDirectory("Please select a source directory...");
}
private function select_source(evt:Event):void {
sourceTxt.text = sourceDir.nativePath;
}
/**
* Event Listener when click "Destination" button
**/
protected function click_destinationBtn(e:MouseEvent):void{
destinationDir = new File();
destinationDir.addEventListener(Event.SELECT, destination_select);
destinationDir.browseForDirectory("Please select a source directory...");
}
private function destination_select(evt:Event):void {
destinationTxt.text = destinationDir.nativePath;
}
/**
* Event Listener when click "Start" button
**/
protected function click_startBtn(e:MouseEvent):void{
if(sourceTxt.text == "") Alert.show("Please select a source directory", "Warning");
else if(destinationTxt.text == "") Alert.show("Please select a destination directory", "Warning");
if(checkDir(sourceTxt.text) === false) Alert.show("A selected Source folder:\n" + sourceTxt.text + "\n is not exist. Please check!", "Warning");
else if(checkDir(destinationTxt.text) === false) Alert.show("A selected Destination folder:\n" + destinationTxt.text + "\n is not exist. Please check!", "Warning");
//Alert.show(checkFile("D:\\New Folder\\f.txt").toString());
//Alert.show(checkDir("D:\\New Folder\\f.txt").toString());
workedTextArea.text = "";
currentLabel.text = "";
timeLabel.text = "";
totalDirLabel.text = "";
totalFileLabel.text = "";
copiedLabel.text = "";
skippedLabel.text = "";
uncopiedLabel.text = "";
totalDirNum = 0;
totalFileNum = 0;
copiedNum = 0;
skippedNum = 0;
uncopiedNum = 0;
startTime = getNow() + "\n";
getFileList(sourceTxt.text);
}
/**
* Get a current date and time as format - YYYY-MM-DD HH:II:SS
*
* #return String
**/
public function getNow():String{
var now:Date = new Date();
return now.getFullYear() + "-" + now.getMonth() + "-" + now.getDate() + " " + now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds();
}
/**
* Check if the directory is exist.
* #param dirName:String Path of the directory
* #return Boolean true or false
**/
private function checkDir(dirName:String):Boolean{
var dir:File = File.userDirectory.resolvePath(dirName);
return dir.isDirectory;
}
/**
* Check if the file is exist.
* #param fileName:String Path of the file
* #return Boolean true or false
**/
private function checkFile(fileName:String):Boolean{
var file:File = File.userDirectory.resolvePath(fileName);
return file.exists;
}
/**
* Ananlyze a structure of files and directory
* If is a folder, loop in its subfolder.
* If is a file, copy to the destination folder
*
* #param sourceDir:String
**/
private function getFileList(sourceDir:String):void{
var file:File = File.userDirectory.resolvePath(sourceDir);
file.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
file.getDirectoryListingAsync();
}
private function directory_listing(e:FileListEvent):void{
var getfiles:Array = e.files;
for each(var item:File in e.files){
trace(item.nativePath);
currentLabel.text = "Latest In : " + item.nativePath;
if(checkDir(item.nativePath)){
// It is a directory, more logic!
totalDirNum++;
item.addEventListener(FileListEvent.DIRECTORY_LISTING, directory_listing);
item.getDirectoryListingAsync();
}
else{
// It is a file, more logic!
totalFileNum++;
if(analyzeFile(item) === true){
if(overwriteChk.selected === false){ // Don't overwrite same file
if(checkFile(destinationDir.nativePath + "\\" + item.name) === false){
copyInto(item, destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
copiedNum++;
}
else uncopiedNum++;
}
else{ // Overwrite same file
copyInto(item, destinationDir.resolvePath(destinationDir.nativePath + "\\" + item.name));
copiedNum++;
}
}
else{
skippedNum++;
}
}
}
finishTime = getNow();
timeLabel.text = startTime + finishTime;
totalDirLabel.text = "Total Dir : " + totalDirNum;
totalFileLabel.text = "Total Files : " + totalFileNum;
copiedLabel.text = "Copied Files : " + copiedNum;
skippedLabel.text = "Skipped Files : " + skippedNum;
uncopiedLabel.text = "Uncopied Files : " + uncopiedNum;
}
/**
* Copy files
* #param sourceFilePointer:File
* #param destinationDirPointer:File
* #return void
**/
private function copyInto(sourceFilePointer:File, destinationDirPointer:File):void{
sourceFilePointer.copyTo(destinationDirPointer, true);
if(logsChk.selected === true)
workedTextArea.text += sourceFilePointer.nativePath + "\n";
}
private function analyzeFile(filePointer:File):Boolean{
//Alert.show(filePointer.extension + "\n" + filePointer.size + "\n" + filePointer.name.indexOf("#"));
if((filePointer.extension) == null && (filePointer.size/1024 > 2) && (filePointer.name.indexOf("#") == -1))
return true;
else
return false;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:BorderContainer width="100%" height="100%">
<s:VGroup width="90%" height="5%" left="0">
<s:HGroup width="100%">
<s:Button id="sourceBtn" label="Source"/>
<s:TextInput id="sourceTxt" width="90%" fontSize="11"/>
</s:HGroup>
<s:HGroup width="100%">
<s:Button id="destinationBtn" label="Destination"/>
<s:TextInput id="destinationTxt" width="90%" fontSize="11"/>
</s:HGroup>
</s:VGroup>
<s:Button id="startBtn" label="Start" height="48" top="0" right="0"/>
<s:HGroup top="50" width="100%">
<s:Label id="currentLabel" width="90%" height="19" text="Latest In : "
textAlign="left" verticalAlign="middle"/>
<s:CheckBox id="overwriteChk" label="Overwrite" selected="false"/>
<s:CheckBox id="logsChk" label="Logs" selected="false"/>
</s:HGroup>
<s:TextArea id="workedTextArea" x="0" top="77" width="100%" height="90%" editable="false"/>
<s:HGroup width="100%" height="5%" bottom="0">
<s:Label id="timeLabel" width="20%" height="100%" textAlign="center" verticalAlign="middle" fontSize="11"/>
<s:Label id="totalDirLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
<s:Label id="totalFileLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
<s:Label id="copiedLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
<s:Label id="skippedLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
<s:Label id="uncopiedLabel" width="16%" height="100%" textAlign="center" verticalAlign="middle"/>
</s:HGroup>
</s:BorderContainer>
</s:WindowedApplication>
Your problem lies within the execution time. If you're trying to perform everything in one go it will use all the CPU it can get. If one thread is being executed for longer than X seconds (usually 15), flash will abort it saying it takes too much.
Before starting your loop, take a timestamp with getTimer() and in the loop, in the beginning of your loop check if the startTimestamp - currentTimestamp is less than 5000 (5 seconds). If it is, break the array and start it over (with or without delay, flash will allow it) from the place you've left.
For this type of operations it would make sense to use workers, check this.
Here's an abstract example:
var counter:int = 0; // our progress
var startTime:int;
function increaseCounter():void
{
startTime = getTimer();
while(true) // infinite loop
{
if (getTimer() - startTime > 5000)
{
increaseCounter();
break;
}
counter++;
if (counter >= int.MAX_VALUE) // our custom loop exit
{
trace(counter);
break;
}
}
}
Though this thread seems to be quite old but I am posting a working code here which I wrote for searching files with given search string. It goes through all subfolders and pretty fast to respond in comparison to File.getDirectoryListing()
Here is my code
protected function performSearch(event:MouseEvent):void
{
searchResults = new Array(); // instance variable
foldersToBeSearched = new Array(); // instance variable
// keep file search list empty at start
fileSearchList.dataProvider = searchResults;
// instance level variable to store search string
searchString = searchText.text.toLowerCase();
// add root folder to array
foldersToBeSearched.push(File.applicationStorageDirectory);
findoutFolderNames(File.applicationStorageDirectory);
// keep and eye on folder search counter
setTimeout(checkAsyncFolderCounter, 500);
// show controls if search is on
showHideControlsAsPerSearchNeed();
}
// Because folder search is async hence use timeout to confirm if all folders are listed
private function checkAsyncFolderCounter():void
{
if(foldersToBeSearched.length === counterCapturedLast)
{
// I am done searching all folders and subfolder
// show this data now
fileSearchList.dataProvider = searchResults;
trace(searchResults.length);
}
else
{
// I am not yet done with folders...keep finding
counterCapturedLast = foldersToBeSearched.length;
setTimeout(checkAsyncFolderCounter, 500);
}
}
// Find out all folders in this folder
private function findoutFolderNames(folder:File):void
{
folder.addEventListener(FileListEvent.DIRECTORY_LISTING, directoryListingHandler);
folder.getDirectoryListingAsync();
}
// CHECK ALL FILES AND FOLDER AND FIND FOR SEARCH STRING OTHERWISE ADD FOLDER TO SEARCH FOLDERS LIST
private function directoryListingHandler(event:FileListEvent):void
{
event.target.removeEventListener(FileListEvent.DIRECTORY_LISTING, directoryListingHandler);
var list:Array = event.files;
for (var i:uint = 0; i < list.length; i++)
{
var file:File = list[i];
if(file.isDirectory)
{
foldersToBeSearched.push(file);
findoutFolderNames(file);
}
else
{
if(file.extension === "drl" && file.name.toLowerCase().indexOf(searchString) !== -1)
{
searchResults.push({label: file.name, creationDate: file.creationDate, nativePath: file.nativePath});
}
}
}
trace("Folder Count " + foldersToBeSearched.length);
}

ArcGIS API for Flex : dynamic InfoSymbols

I am trying to add some InfoSymbols in my map, here is what I did :
<esri:InfoSymbol id="infoSymbol1">
<esri:infoRenderer>
<fx:Component>
<s:DataRenderer>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:Image id="eventImg" source="{imgSource}"/>
<s:Label id="eventName" text="{eventTitle}"/>
</s:DataRenderer>
</fx:Component>
</esri:infoRenderer>
</esri:InfoSymbol>
And I am filling a list from the data passed to the view, ( the application is a mobile view based app)
public function fillDataGrid():void {
for each(var object:Object in data) {
initDG.addItem(object);
drawEvent(object);
}
}
Finally I add the InfoSymbols the drawEvent(objt) method :
private function drawEvent(object:Object):void{
var myGraphicText:Graphic = new Graphic(new WebMercatorMapPoint(
object.local.longitude, object.local.latitude));
var event:InfoSymbol = new InfoSymbol();
imgSource = "http://192.168.0.22:3000" + object.logo_thumb_url;
eventTitle = object.name;
event = infoSymbol1;
myGraphicText.symbol = event;
myGraphicsLayer.add(myGraphicText);
}
of course imgSource and eventTitle are Bindable,
The issue is that I am getting
Description Resource Path Location Type
1120: Access of undefined property eventTitle.
And the same message for imgSource,
Any help would be much appreciated !!
You need to declare eventTitle before you assign a value to it.
var eventTitle:String = object.name;

Why Alivepdf generate double table header?

I'm attempting to create a pdf table on my flex application using AlivePdf:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mh="mh.components.*"
layout="absolute" width="500" height="500">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import org.alivepdf.colors.RGBColor;
import org.alivepdf.display.Display;
import org.alivepdf.drawing.Caps;
import org.alivepdf.fonts.FontFamily;
import org.alivepdf.fonts.Style;
import org.alivepdf.grid.Grid;
import org.alivepdf.images.ImageFormat;
import org.alivepdf.layout.Orientation;
import org.alivepdf.layout.Resize;
import org.alivepdf.layout.Size;
import org.alivepdf.layout.Unit;
import org.alivepdf.pages.Page;
import org.alivepdf.pdf.PDF;
import org.alivepdf.saving.Method;
import org.alivepdf.visibility.Visibility;
import org.alivepdf.grid.*;
private var myPDF:PDF;
//print chart in pdf format
protected function savePDF(e:MouseEvent):void
{
var myPDF:PDF = new PDF ( Orientation.PORTRAIT, Unit.MM);
myPDF.setDisplayMode(Display.FULL_PAGE);
myPDF.addPage();
myPDF.setXY( 10, 70);
myPDF.textStyle ( new RGBColor ( 0x000000 ) );
var dp:ArrayCollection = new ArrayCollection();
dp.addItem( { firstName : "Bob Geldorf akjaskaj skajs as kajs kaj k dklfj sdkfjl sdkjf ksdj fkjs dkfj ksdj ", lastName : "Groove", city : "Paris" } );
dp.addItem( { firstName : "Bob", lastName : "Wise", city : "Paris" } );
dp.addItem( { firstName : "Bob", lastName : "Wise", city : "Paris" } );
dp.addItem( { firstName : "Bob", lastName : "Wise", city : "Paris" } );
var grid:Grid = new Grid ( dp.toArray(), 200, 100, new RGBColor (0x00DEFF));
myPDF.addGrid( grid, 0, 0, true );
myPDF.save( Method.REMOTE, "coldfusion/pdf.cfm", "inline", "test.pdf" );;
}
]]>
</mx:Script>
<mx:VBox width="100%" height="100%">
<mx:HBox width="100%" backgroundColor="#FFFFFF">
<mx:Spacer width="100%"/>
<mx:Button horizontalCenter="0" label="Save to PDF" height="22" click="savePDF(event)" id="savePDFBtn" toolTip="SAVE TO PDF"/>
</mx:HBox>
</mx:VBox>
The strange thing is that the script create a table with double header and I don't know why. You can see the pdf generated at this link: https://docs.google.com/viewer?url=prestitiinpdap.biz/pdf/myPDF.pdf
Which version of the library do you use? I have tried to compile your code with the current version 0.1.5RC and the compiler could not find some classes.
After correction of the class paths I have found that the "new Grid(...)" constructor needs 7 parameters (in your case only 4).
Another issue is "width" in "Grid(...)". I don't know, what the developers wanted to express with it. I could get I normal view only with 60.
I have got the following PDF after all:
Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="500" height="500">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import org.alivepdf.colors.RGBColor;
import org.alivepdf.data.Grid;
import org.alivepdf.display.Display;
import org.alivepdf.drawing.Caps;
import org.alivepdf.fonts.FontFamily;
import org.alivepdf.fonts.Style;
import org.alivepdf.images.ImageFormat;
import org.alivepdf.layout.Orientation;
import org.alivepdf.layout.Resize;
import org.alivepdf.layout.Size;
import org.alivepdf.layout.Unit;
import org.alivepdf.pages.Page;
import org.alivepdf.pdf.PDF;
import org.alivepdf.saving.Method;
import org.alivepdf.visibility.Visibility;
import org.alivepdf.layout.*;
private var myPDF:PDF;
protected function savePDF(e:MouseEvent):void
{
var myPDF:PDF = new PDF( Orientation.PORTRAIT, Unit.MM);
myPDF.setDisplayMode( Display.FULL_PAGE, Layout.SINGLE_PAGE );
var newPage:Page = new Page ( Orientation.PORTRAIT, Unit.MM);
myPDF.addPage(newPage);
myPDF.textStyle ( new RGBColor ( 0x000000 ) );
var dp:ArrayCollection = new ArrayCollection();
dp.addItem( { firstName : "Bob Geldorf akjaskaj skajs as kajs kaj k dklfj sdkfjl sdkjf ksdj fkjs dkfj ksdj ", lastName : "Groove", city : "Paris" } );
dp.addItem( { firstName : "Bob", lastName : "Wise", city : "Paris" } );
dp.addItem( { firstName : "Bob", lastName : "Wise", city : "Paris" } );
dp.addItem( { firstName : "Bob", lastName : "Wise", city : "Paris" } );
//var grid:Grid = new Grid ( dp.toArray(), 200, 100, new RGBColor (0x00DEFF));
var grid:Grid = new Grid (dp.toArray(), 60, 100, new RGBColor(0x00DEFF), new RGBColor (0xFFFFFF), false, new RGBColor (0x000000));
myPDF.addGrid( grid, 0, 0, true );
//myPDF.save( Method.REMOTE, "coldfusion/pdf.cfm", "inline", "test.pdf" );
var f:FileReference = new FileReference();
var b:ByteArray = myPDF.save(Method.LOCAL);
f.save(b, "test.pdf");
}
]]>
</fx:Script>
<mx:VBox width="100%" height="100%">
<mx:HBox width="100%" backgroundColor="#FFFFFF">
<mx:Spacer width="100%"/>
<mx:Button horizontalCenter="0" label="Save to PDF" height="22" click="savePDF(event)" id="savePDFBtn" toolTip="SAVE TO PDF"/>
</mx:HBox>
</mx:VBox>
</s:Application>
Try it, may be it will help you.
When creating a PDF with a Grid, I had the same problem of duplicate headers, as reported here. It's a few years after your problem, but since i came across it now, here's my solution...
To ensure using the latest AlivePDF version, I have downloaded the latest source code from their SVN: http://alivepdf.googlecode.com/svn/trunk/AlivePDFBeta/src
I believe this is distributed as AlivePDF 0.1.5 RC, however the distributed SWCs seem to have differences in some method signatures.
While scanning the AlivePDF source code for behaviour related with adding the Grid header, I noticed the class org.alivepdf.pdf.PDF, public method addGrid.
That method is indeed adding the Grid header 2 times, possibly by mistake.
This was fixed by commenting lines 4178 to 4180, as shown in the following source code.
Full method with the commented portion included:
public function addGrid ( grid:Grid, x:Number=0, y:Number=0, repeatHeader:Boolean=true ):void
{
if ( textColor == null )
throw new Error("Please call the setFont and textStyle method before adding a Grid.");
currentGrid = grid;
currentGrid.x = x;
currentGrid.y = y;
var i:int = 0;
var j:int = 0;
currentGrid.generateColumns(false);
columns = currentGrid.columns;
var row:Array;
columnNames = new Array();
var lngColumns:int = columns.length;
var item:*;
for (i = 0; i< lngColumns; i++)
columnNames.push ( new GridCell(columns[i].headerText, currentGrid.headerColor ) );
var rect:Rectangle = getRect ( columnNames, currentGrid.headerHeight );
if ( checkPageBreak(rect.height) )
addPage();
// Commented to avoid the duplicate header issue:
//setXY (x +currentGrid.x, y+getY() );
//addRow( columnNames,'', rect);
//endFill();
setXY ( x+getX(), y+getY() );
addRow( columnNames, GridRowType.HEADER, rect );
if (grid.cells == null)
grid.generateCells();
var buffer:Array = grid.cells;
var lngRows:int = buffer.length;
for (i = 0; i< lngRows; i++)
{
item = buffer[i];
row = new Array();
for (j = 0; j< lngColumns; j++)
{
row.push (item[columns[j].dataField] != null ? item[columns[j].dataField] : "");
nb = Math.min(nb,nbLines(columns[j].width,row[j]));
}
row = buffer[i];
rect = getRect ( row, currentGrid.rowHeight );
setX ( x + getX());
if ( checkPageBreak(rect.height) )
{
addPage();
setXY ( x+getX(),nextPageY );
//setXY ( x+getX(),y+getY() ); hacked to allow user to set the next Page Y of Grid
if ( repeatHeader )
{
addRow (columnNames, GridRowType.HEADER, getRect(columnNames, currentGrid.headerHeight) ); // header
setX ( x + getX() );
}
}
if ( grid.useAlternativeRowColor && Boolean(isEven = i&1) )
addRow( row, GridRowType.ALTERNATIVE, rect );
else addRow( row, GridRowType.NORMAL, rect );
}
}

Get a href from xml file into a flash button

I have a flash file where I'm trying to change the value of the same button depending on the image that is clicked but I can't make it work with different values (I can only make it work with a static value).
AS:
var weblinkXML:XML = new XML();
weblinkXML.ignoreWhite = true;
weblinkXML.load("xml/main.xml");
weblinkXML.onLoad = function(success) {
trace("success = "+success);
for (var i:Number = 0; i< weblinkXML.childNodes.length; i++) {
PPTBUTTON.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage_1);
function fl_ClickToGoToWebPage_1(event:MouseEvent):void
{
navigateToURL(new URLRequest("test/test.html"), "_blank");
}
}
}
my XML:
<?xml version="1.0" encoding="iso-8859-1"?>
<content>
<!-- general vars -->
<settings>
<item name="copyright"><![CDATA[<font letterspacing="0.5">© 2012 | PRIVACY POLICY</font>]]></item>
<item name="companyName"><![CDATA[<font letterspacing="-2"><b>TANITA</b></font>]]></item>
<item name="companySlogan"><![CDATA[<font letterspacing="1">PHOTO PORTFOLIO</font>]]></item>
<!--mp3Url srcUrl="music.mp3"/-->
<imagesPage>
<image imageUrl="images/tfile_splash_pic_main.jpg" />
</imagesPage>
</settings>
<!-- menu -->
<menu>
<button><![CDATA[PORTFOLIO]]></button>
<button><![CDATA[ABOUT]]></button>
<button><![CDATA[NEWS]]></button>
<button><![CDATA[CONTACTS]]></button>
</menu>
<gallery gallName="Crystal Cabin Awards 2012">
<image imageUrl="gallery/tfile_gall_small_01.jpg" imagesBig="gallery/tfile_gall_big_01.jpg" buttonName="PPTBUTTON" targ="_self" href="http://www.google.com"/>
<image imageUrl="gallery/tfile_gall_small_02.jpg" imagesBig="gallery/tfile_gall_big_02.jpg" buttonName="PPTBUTTON" targ="_self" href="http://www.youtube.com"/>
<image imageUrl="gallery/tfile_gall_small_03.jpg" imagesBig="gallery/tfile_gall_big_03.jpg" buttonName="PPTBUTTON" targ="_self" href="http://www.yahoo.com"/>
<image imageUrl="gallery/tfile_gall_small_04.jpg" imagesBig="gallery/tfile_gall_big_04.jpg"/>
<image imageUrl="gallery/tfile_gall_small_05.jpg" imagesBig="gallery/tfile_gall_big_05.jpg"/>
<image imageUrl="gallery/tfile_gall_small_06.jpg" imagesBig="gallery/tfile_gall_big_06.jpg"/>
<image imageUrl="gallery/tfile_gall_small_07.jpg" imagesBig="gallery/tfile_gall_big_07.jpg"/>
<image imageUrl="gallery/tfile_gall_small_08.jpg" imagesBig="gallery/tfile_gall_big_08.jpg"/>
</gallery>
I realize my xml is complex but it's being used through the entire flash. Maybe I could reduce it to a stand alone xml just like:
<image imageUrl="gallery/tfile_gall_small_02.jpg" imagesBig="gallery/tfile_gall_big_02.jpg" buttonName="PPTBUTTON" targ="_self" href="http://www.youtube.com"/>
my issue is that I've tried to get the href into a variable and use it instead of "test/test.html" but it never works.
I also realize I have a method inside a for but at this point I've iterated so much over this code that I'm unsure how to proceed.
Here's how i would retrieve the list of href attributes:
var loader:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest("xml/main.xml");
loader.addEventListener(IOErrorEvent.IO_ERROR, function errorHandler(event:IOErrorEvent):void {
trace("Error loading XML" + event.type);
});
loader.addEventListener(Event.COMPLETE, function(event:Event):void {
trace("success = " + event);
var xml:XML = new XML(loader.data);
var xmllist:XMLList = xml.gallery.children();
for (var i:Number = 0; i < xmllist.length(); i++) {
trace(XML(xmllist[i]).attribute("href"));
}
});
loader.load(request);
I had the following output:
success = [Event type="complete" bubbles=false cancelable=false eventPhase=2]
http://www.google.com
http://www.youtube.com
http://www.yahoo.com
I hope that helps.

Using .text() to get formatting of JSON data

I'm using:
function pipeCallback(obj) {
to get the contents of a Yahoo pipe (in JSON). I then create a string inside:
document.write("<div......);
var buildstring = ".......;
document.write(buildstring);
document.write("</div>");
Everything works, except that one item in the string:
obj.value.items[x].description.content
contains a lot of text and is stripped of its formatting. Is there a way to define a var (using .text()?) to keep the formatting and then to use the defined term in the string - e.g. something like:
var description = (obj.value.items[x].description.content).text()
and then to use the term 'description' in buildstring in place of obj.value.items[x].description.content.
Thanks for any suggestions/help.
EDIT
#Barmar Thanks. I tried that (I think...):
var description = function() {return (obj.value.items[x].description.content).text()};
var buildstring = "<table><tr><img src=" + imageurl + "> <b>" + obj.value.items[x].title + "</b><br /><td>" + description() + "</td></tr></table><br />";
(imageurl is a separately defined variable). I think I must have missed the point of your suggestion (or not given the right information at first). Anyhow..it didn't work.
EDIT #2
function pipeCallback(obj) {
document.write("<div id=testdiv><b>LATEST NEWS</b><hr>");
var x;
for (x = 0; x < obj.count ; x++)
{
var imageurl = (typeof obj.value.items[x]["media:content"] == 'undefined') ? "http://default.png" : obj.value.items[x]["media:content"].url;
var buildstring = "<table><tr><img src=" + imageurl + "> <b>" + obj.value.items[x].title + "</b><br /><td>" + obj.value.items[x].description.content + "</td></tr></table><br />";
document.write(buildstring);
buildstring = null;
}
document.write("</div>");
}
You can do:
var description = function() {return (obj.value.items[x].description.content).text()};
and then use description() to get this.