Can the items in the cells contain hyperlinks - if yes, any thoughts to help with this would be great. Thanks.
This is a discussion on How to populate a DataGrid from an XML file within the Tutorials forums, part of the Flash English category; After having seen how to populate a ComboBox with Flash CS3 , let's see how to use the datas of ...
After having seen how to populate a ComboBox with Flash CS3 , let's see how to use the datas of an XML file and insert them in a Flash DataGrid component.
This article will take as example a CD's catalogue.
To my opinion, the Flash CS3 DataGrid component is a very valid method for this type of applications.
Clearly, the XML file is completly rewritable, meaning that voices can be added or taken away as you like.
Let's get into it...
I create a FLA and save it as 'data_grid.fla' inside which:
- I drag on stage a DataGrid and name it 'dg'
- I create a dynamic text field to embed the fonts into the swf (more details in the article: Embed fonts into SWF
I create a Document Class, an AS file saved as 'Main.as', implemented the following way:
I create a class which loads the XML, an AS file saved as 'LoadingXML.as':Code:package { import flash.display.MovieClip; import fl.controls.DataGrid; import fl.controls.ScrollPolicy; import flash.display.Sprite; import flash.events.Event; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFieldAutoSize; public class Main extends MovieClip { private var xml:LoadingXML; public var objects_array:Array; public var colonne_array:Array; public var titolo:String; private var titolo_txt:TextField; public function Main() { init(); loadXML(); } private function init():void { stage.frameRate=31; objects_array=new Array(); colonne_array=new Array(); } private function loadXML():void { xml=new LoadingXML(this); } public function creaTitolo():void { titolo_txt=createField(26,'Century Gothic'); addChild(titolo_txt); titolo_txt.text=titolo+' CD'; titolo_txt.x=stage.stageWidth/2-titolo_txt.width/2; } private function createField(n:Number,f:String):TextField { var field:TextField=new TextField(); field.autoSize=TextFieldAutoSize.LEFT; field.selectable=false; field.embedFonts=true; field.defaultTextFormat=getFormat(n,f); return(field); } private function getFormat(n:Number,f:String):TextFormat { var tf:TextFormat=new TextFormat(); tf.font=f; tf.size=n; tf.bold=true; tf.letterSpacing=0; tf.color=0x666666; return(tf); } public function initDataGrid():void { dg.move(25,50); dg.width=650; dg.rowCount=10; dg.columns=colonne_array; dg.verticalScrollPolicy=ScrollPolicy.ON; for(var i:int=0;i < objects_array.length;i++) { dg.addItem(objects_array[i]); } } } }
Code:package { import flash.display.MovieClip; import flash.display.Loader; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLRequest; import flash.xml.*; public class LoadingXML extends XMLDocument { private var my_root:MovieClip; public function LoadingXML(m:MovieClip) { my_root=m; this.loadXML(); } private function loadXML():void { var loader:URLLoader=new URLLoader(); loader.addEventListener(Event.COMPLETE,completeHandler); var request:URLRequest=new URLRequest('catalogo.xml'); try { loader.load(request); } catch(error:Error) { trace('Impossibile caricare il documento.'); } } private function completeHandler(event:Event):void { var loader:URLLoader=URLLoader(event.target); var result:XML=new XML(loader.data); var myXML:XMLDocument=new XMLDocument(); myXML.ignoreWhite=true; myXML.parseXML(result.toXMLString()); var node:XMLNode=myXML.firstChild; var n:int=node.childNodes.length; my_root.titolo=node.nodeName; for(var i:int=0;i < n;i++) { var obj:Object=new Object(); var s:Number=node.childNodes[i].childNodes.length; for(var j:int=0;j < s;j++) { if(i==0) my_root.colonne_array.push(node.childNodes[i].childNodes[j].nodeName); if(j==0) obj.titolo=node.childNodes[i].childNodes[j].firstChild.nodeValue; if(j==1) obj.artista=node.childNodes[i].childNodes[j].firstChild.nodeValue; if(j==2) obj.nazione=node.childNodes[i].childNodes[j].firstChild.nodeValue; if(j==3) obj.casa_discografica=node.childNodes[i].childNodes[j].firstChild.nodeValue; if(j==4) obj.prezzo='? '+node.childNodes[i].childNodes[j].firstChild.nodeValue; if(j==5) obj.anno=node.childNodes[i].childNodes[j].firstChild.nodeValue; } my_root.objects_array.push(obj); } my_root.creaTitolo(); my_root.initDataGrid(); } } }Click here to view the XML file.
The result:
Let's analise the code.
LoadingXML.as class
This is the same class used in this article: Loading external XML files with Flash CS3
I want to concentrate the attention on the following lines:
I assign to the variable titolo of the Main.as the name of the principal node of the XML file
my_root.titolo=node.nodeName;
for each child of thenode, I create an object
for(var i:int=0;i < n;i++)
var obj:Object=new Object();
with a second nested cycle, I add properties to the object and assign to it the value of each child childNodes of the main node
for(var j:int=0;j < s;j++)
{
if(i==0)
my_root.colonne_array.push(node.childNodes[i].childNodes[j].nodeName);
if(j==0)
obj.titolo=node.childNodes[i].childNodes[j].firstChild.nodeValue;
if(j==1)
obj.artista=node.childNodes[i].childNodes[j].firstChild.nodeValue;
if(j==2)
obj.nazione=node.childNodes[i].childNodes[j].firstChild.nodeValue;
if(j==3)
obj.casa_discografica=node.childNodes[i].childNodes[j].firstChild.nodeValue;
if(j==4)
obj.prezzo='? '+node.childNodes[i].childNodes[j].firstChild.nodeValue;
if(j==5)
obj.anno=node.childNodes[i].childNodes[j].firstChild.nodeValue;
}
And I insert the object in the array objects_array of Main.as class
my_root.objects_array.push(obj);
after which I call the creaTitolo() and initDataGrid() method of the main.as class
my_root.creaTitolo();
my_root.initDataGrid();
Main.as Class
Properties
an instance of my LoadingXML class
private var xml:LoadingXML;
two arrays in which I will insert the datas loaded by the LoadingXML class from the XML file
public var objects_array:Array;
public var colonne_array:Array;
the name of the application which is nothing else that the name of the main node of the XML file (catalogo)
public var titolo:String;
an instance of a text field
private var titolo_txt:TextField;
Methods
init();
I impost the frame rate
stage.frameRate=31;
I initialize the two arrays
objects_array=new Array();
colonne_array=new Array();
loadXML();
I create an instance of the LoadingXML class passing to it the value of the root ('this' in this case is the Document Class, o my FLA, my timeline, the _root of the application...)
xml=new LoadingXML(this);
creaTitolo();
I create a text field calling the function createField to which I pass the value of the dimension of the text and the font family used. The function createField will return the created text field, included the TextFormat
titolo_txt=createField(26,'Century Gothic');
I add the text field to the DisplayObject otherwise it would not be visible
addChild(titolo_txt);
I impost the test to the text field
titolo_txt.text=titolo+' CD';
I position the text field
titolo_txt.x=stage.stageWidth/2-titolo_txt.width/2;
createField(n:Number,f:String):TextField
I create a text field and I assign to its properties some value
var field:TextField=new TextField();
field.autoSize=TextFieldAutoSize.LEFT;
field.selectable=false;
field.embedFonts=true;
I assign a TextFormat to the text field calling the function getFormat() which returns a textFormat and passing to it the values returned by the function creaTitolo();
field.defaultTextFormat=getFormat(n,f);
I return the text field
return(field);
getFormat(n:Number,f:String):TextFormat
I create a new TextFormat and I assign to it as fonts and dimensions the values passed to the function createField() which received them from the function creaTitolo()
var tf:TextFormat=new TextFormat();
tf.font=f;
tf.size=n;
tf.bold=true;
tf.letterSpacing=0;
tf.color=0x666666;
I return the TextFormat
return(tf);
initDataGrid();
I position the DataGrid
dg.move(25,50);
I impost the width of the DataGrid
dg.width=650;
I impost the number of row of the DataGrid
dg.rowCount=10;
I impost the number of columns of the DataGrid equal to the value of the array colonne_array length
dg.columns=colonne_array;
I activate the scrollBar of the DataGrid
dg.verticalScrollPolicy=ScrollPolicy.ON;
I load the datas in the DataGrid using the addItem() method to which I pass each index of the array objects_array
for(var i:int=0;i < objects_array.length;i++)
{
dg.addItem(objects_array[i]);
}
Not bad eh ?! ...
Can the items in the cells contain hyperlinks - if yes, any thoughts to help with this would be great. Thanks.
Hi,
you can add an url in the XML file.
Add a .url property at the object in the LoadingXML.as file.
Use the ITEM_CLICK event to get the url for that item:
Code:dg.addEventListener(ListEvent.ITEM_CLICK,setClick);Code:private function setClick(evt:ListEvent):void { trace(evt.target.selectedItem.url); }
Does this have to be done via xml file vs. the datagrid that is created/populated via actionscript? I am a Rookie - Thanks
Has to be done with Actionscript .
Try the code and you'll see a Flash Output when you click an item of DataGrid.
That helped me really a lot, but I have another question regarding the Datagrid. Is it possible to add an extra column containing e.g. an image of the cover? Maybe by defining the path to the image in the xml file an then somehow load it? I'm relatively new to Falsh and Actionscript and that would help me a lot.
Greetings
please help me and tell me if you can where can i put the code
i am confused....
Re: How to populate a DataGrid from an XML file
Hi,
you can add an url in the XML file.
Add a .url property at the object in the LoadingXML.as file.
Use the ITEM_CLICK event to get the url for that item:
Code:
dg.addEventListener(ListEvent.ITEM_CLICK,setClick) ;
Code:
private function setClick(evt:ListEvent):void
{
trace(evt.target.selectedItem.url);
}
Thanks for the help; together with another port from the Adobe Forum I solved my problem...
Great tutorial! Thanks.
I'm looking to do something similar to this, but would like to be able to then edit the cell value and then save it back to the XML file. I'm planning on using Adobe Air, so the flash air file and the XML file will be on the users computer.
Can this be done easily?
Thanks for the tutorial. What I'm running into is that when numerical values are entered into columns 2 & 3, I'm getting the error - Cannot access a property or method of a null object reference.
If I use CDATA, or otherwise make them strings it runs ok. The problem then is that if it's read as a string, then it doesn't sort in numerical order. (i.e. it's 1, 11, 12..., 2, 21, etc).
Try editing your XML file and let me know if you get the same result.
Bookmarks