A Flash Developer Resource Site

Page 1 of 2 12 LastLast
Results 1 to 20 of 31

Thread: Parsing with a 2nd Array

  1. #1
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286

    Parsing with a 2nd Array

    Hi everyone,

    I'm using Flash 6, AS 1.
    I know how to parse xml-data like:
    Code:
    <?xml version="1.0"?>
    <galery>
    <img>
    	<url>url1</url>
    	<caption>caption1</caption>
    </img>
    <img>
    	<url>url2</url>
    	<caption>caption2</caption>
    </img>
    </galery>
    I then parse the data in Flash with:
    Code:
    	var hItems = this.firstChild.childNodes
    	createEmptyMovieClip("hold", 1);
    	for (n=0; n<hItems.length; n++) {
    etcetera

    But here'my problem: I have to parse an xml-file with another (higher) level, and I haven't been able so far to create a 2nd array that parses nodes parsed by the first array. Here's the xml-sample:

    Code:
    <?xml version="1.0"?>
    <thedata>
    <category>
    	<categoryname>category 1</categoryname>
    	<article>
    			<articlename>articlename 1 of category 1</articlename>
    			<articletext>articletext 1 van category 1</articletext>
    			<articlelink>mailform.php?artikelID=1</articlelink>
    	</article>
    	<article>
    			<articlename>articlename 2 of category 1</articlename>
    			<articletext>articletext 2 van category 1</articletext>
    			<articlelink>mailform.php?artikelID=2</articlelink>
    	</article>
    </category>
    <category>
    	<categoryname>category 2</categoryname>
    	<article>
    			<articlename>articlename 1 of category 2</articlename>
    			<articletext>articletext 1 van category 2</articletext>
    			<articlelink>mailform.php?artikelID=3</articlelink>
    	</article>
    	<article>
    			<articlename>articlename 2 of category 2</articlename>
    			<articletext>articletext 2 van category 2</articletext>
    			<articlelink>mailform.php?artikelID=4</articlelink>
    	</article>
    </category>
    <category>
    	<categoryname>category 3</categoryname>
    	<article>
    			<articlename>articlename 1 of category 3</articlename>
    			<articletext>articletext 1 van category 3</articletext>
    			<articlelink>mailform.php?artikelID=5</articlelink>
    	</article>
    	<article>
    			<articlename>articlename 2 of category 3</articlename>
    			<articletext>articletext 2 van category 3</articletext>
    			<articlelink>mailform.php?artikelID=6</articlelink>
    	</article>
    </category>
    </thedata>
    The categories and articles will vary in number, the child nodes of article stay the same in number.
    So, with my earlier Actionscript I can see all the nodes, but how can I substract the child nodes of the article-nodes?

    Thank you very much for helping me!

  2. #2
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    I think you'll save yourself a lot of trouble if you restructure your xml. There seems to me a loss of focus in your tags and structure.

    Lets see, your root tag is "<thedata>". That is too general and should be more specific. What is your xml about? Is it a container for articles? If so then this should be "<articles>" and not "<thedata>".

    Now your next tag is "<category>". Your xml is a collection of articles, not a collection of categories, so you should change this to "<article>" and instead use a child tag of "category" within the "<article>" tag.

    Next you have "<articlename>","<articletext>", and "<articlelink>". No problem there. These are ok, although I find using "article" redundant since these are part of the parent tag "<article>" already. Why not rename them at just "<name>","<text>", and "<link>"? And also add a "<category>" tag here since we got rid of the parent "category" tag.

    So here's your revised XML. This should be easier to parse since you don't have as many levels, and less sibling nodes in the higher levels. All the sibling nodes are at the lowest level (the article level).



    Code:
    <?xml version="1.0"?>
    <articles>
    <article>
    	<name>articlename 1 of category 1</name>
    	<text>articletext 1 van category 1</text>
    	<link>mailform.php?artikelID=1</link>
    	<category>category 1</category>
    </article>
    <article>
    	<name>articlename 2 of category 1</name>
    	<text>articletext 2 van category 1</text>
    	<link>mailform.php?artikelID=2</link>
    	<category>category 1</category>
    </article>
    <article>
    	<name>articlename 1 of category 2</name>
    	<text>articletext 1 van category 2</text>
    	<link>mailform.php?artikelID=3</link>
    	<category>category 2</category>
    </article>
    <article>
    	<name>articlename 2 of category 2</name>
    	<text>articletext 2 van category 2</text>
    	<link>mailform.php?artikelID=4</link>
    	<category>category 2</category>
    </article>
    <article>
    	<name>articlename 1 of category 3</name>
    	<text>articletext 1 van category 3</text>
    	<link>mailform.php?artikelID=5</link>
    	<category>category 3</category>
    </article>
    <article>
    	<name>articlename 2 of category 3</aname>
    	<text>articletext 2 van category 3</text>
    	<link>mailform.php?artikelID=6</link>
    	<category>category 3</category>
    </article>
    </articles>
    There you go, much nicer and way easier to parse since there are less nodes to traverse. You should be able to parse it just like you did with your gallery xml.
    Last edited by pigpen32; 07-18-2006 at 01:17 AM.

  3. #3
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    Thanx for your reply. The problem is that I will make MC's of categories that will eventually show the corresponding articles. So, after clicking on one mc out of a list of mc's (created with the nodes of category) a number of articles that belong to that specific category will be shown in another mc's (like a column next to the column with the categories).
    So my thought was that first I have to find out how many categories there are, and next, how many articles there are per category. Is that possible with your xml-format?

    Thanx again!
    Michiel

  4. #4
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    Ah I just noticed you are from Holland. Coincidently, my parents are visiting there right now as I type. And I've been there a couple times in the last few years. We've got some European friends over there (we live in the US).

    Anyway, as to your xml issue, I can see why you'd want the categories as a separate node. If that's the case, I'd structure your xml this way:

    Code:
    <?xml version="1.0"?>
    <articles>
    <category name="category 1">
    	<article>
    		<name>articlename 1 of category 1</name>
    		<text>articletext 1 van category 1</text>
    		<link>mailform.php?artikelID=1</link>
    	</article>
    	<article>
    		<name>articlename 2 of category 1</name>
    		<text>articletext 2 van category 1</text>
    		<link>mailform.php?artikelID=2</link>
    	</article>
    </category>
    <category name="category 2">
    	<article>
    		<name>articlename 1 of category 2</name>
    		<text>articletext 1 van category 2</text>
    		<link>mailform.php?artikelID=3</link>
    	</article>
    	<article>
    		<name>articlename 2 of category 2</name>
    		<text>articletext 2 van category 2</text>
    		<link>mailform.php?artikelID=4</link>
    	</article>
    </category>
    <category name="category 3">
    	<article>
    		<name>articlename 1 of category 3</name>
    		<text>articletext 1 van category 3</text>
    		<link>mailform.php?artikelID=5</link>
    	</article>
    	<article>
    		<name>articlename 2 of category 3</aname>
    		<text>articletext 2 van category 3</text>
    		<link>mailform.php?artikelID=6</link>
    	</article>
    </category>
    </articles>
    Notice I put the name of the category as an attribute inside the category node. You can access the attribute of a node by using the attribute property followed by the value of the attribute.

    Code:
    var levelOne = this.firstChild.childNodes;
    trace(levelOne[0].attributes.name); // displays "category one"
    Ok here is the answer to your original question regarding how to access the article node which is inside the parent node, the category node.

    Just make two "for loops". One inside another. In the example below, I'm tracing out each category node as well as each article node within each category node.

    Code:
    var levelOne = this.firstChild.childNodes;
    for (i=0; i<levelOne.length; i++) {
    
    	// display name attribute for each category node
    	trace("levelOne name: "+levelOne[i].attributes.name);
    
    	// setup the next loop to go through article nodes
    	var levelTwo = levelOne[i].childNodes;
    	for (j=0; j<levelTwo.length; j++) {
    
    		// display nodeName for articles nodes under each category
    		trace("levelTwo: "+levelTwo[j].nodeName);
    
    		// to show the nodeValue for the name node under article node use
    		// levelTwo[j].childNodes[0].childNodes[0].nodeValue
    	}
    }
    The first loops goes through 1st category node, then the 2nd loop goes through each article node. Once the 2nd loop is done, the whole process repeats. The first loops now goes through the 2nd category node, and then the 2nd loop goes through the 2nd category node's set of article nodes, etc, etc.

    It should be fairly easy for you to modify it to create arrays or your mc's. Its the same as using one loop, but instead you have two loops. Each loop has to have the necessary array code or mc creation code inside it.

    I hope that makes sense.

  5. #5
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    Wow, your help was exactly what I was looking for! Somehow I wasn't able to create the 2nd loop correctly, you've earned many beers next time you visit Holland! Just let me know (I mean that)!
    Where are your parents? Amsterdam?

    One question still: I can't extract the other nodes, <text> and <link>. I tried for the text node:
    Code:
    var artikeltekst = (levelTwo[j].firstChild.nextSibling.childNodes[0].nodeValue);
    but than the last node give "undefined". How can I do that?

    Thanx again,
    Michiel
    Last edited by Schenkius; 07-19-2006 at 10:35 AM.

  6. #6
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    Here you go.
    Code:
    trace("text node: "+ levelTwo[0].childNodes[1]);
    trace("text nodeValue: "+ levelTwo[0].childNodes[1].childNodes[0].nodeValue);
    //
    trace("link node: "+ levelTwo[0].childNodes[2]);
    trace("link nodeValue: "+ levelTwo[0].childNodes[2].childNodes[0].nodeValue);
    Yeah it can get confusing trying to figure out which node to access. So don't worry if you're having a hard time. Most people do.

    Personally, I use xPath which is a custom made class that works with the xml (and xmlNode) class. With xPath, I can target certain nodes by their name (category, article, etc) instead of by their relativity in the xml hierarchy (firstSibling, childNodes, etc). I find it easier.

    Moreover, and this is what many people forget, is that all of the built-in xml and xmlNode methods and properties are available too (like nodeValue, etc) so I can use the power of both either xPath and xmlNode.

    http://www.osflash.org/xpath4as2

    Yeah my parents went to Amsterdam. Usually they go to our friends home town, but I'm forgetting the name at the moment. This time though they were invited by the Dutch Royal Navy because of my father's research and help regarding Japanese submarines involved with fighting Dutch submarines in World War II. So this time they went to Den Helder as well.

    Actually my father a few years ago, through intensive research, found out that his father (my grandfather), who was a Japanese officer on a Japanese submarine, had sunk a Dutch submarine during World War II off the coast of Malaysia. My grandfather died during the war so not much was known about it at the time.

    Once my dad figured out which Dutch submarine had been sunk, he immediately wanted to pay homage to the Dutch submariners by visiting the memorial at the Navy base in Den Helder and to make a long story short, he unexpectedly and happily met the daughter of one of the Dutch submariners who died on the submarine. Like my dad, she never knew her father either. Since then, both of them have shared research info on trying to discover the locations of the two submarines. Both of them are still undiscovered despite several diving attempts.

  7. #7
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    That's quite an impressive story! I hope they will find the submarines someday to have a closure for alle people involved.

    I managed to extract the nodes, for instance:
    var link = levelTwo[j].firstChild.nextSibling.nextSibling.firstChild.nod eValue;

    Now the thing is (also new for me) is that on mouse over on one of the category names, I would like to show the corresponding article in movieclips. Again, I know how to create those mc's, but I have no clue how to combine the right articles to the right category... do you have any idea how to do that?

    So far my code is:
    Code:
    System.useCodePage = true;
    percent = "Bezig met laden...";
    myXML = new XML();
    myXML.load("data.xml");
    myXML.ignoreWhite = true;
    myXML.onLoad = function() {
    	//var levelOne = this.firstChild.childNodes;
    	//trace(levelOne[0].attributes.name); // displays "category one"
    	var levelOne = this.firstChild.childNodes;
    	//trace(levelOne);
    	createEmptyMovieClip("hold", 1);
    	createEmptyMovieClip("hold1", 2);
    	for (i=0; i<levelOne.length; i++) {
    		var category = levelOne[i].attributes.name;
    		var mc = hold.createEmptyMovieClip("description"+i, i);
    		mc.createTextField("destext", 1, 0, 0, 200, 20);
    		mc.destext.html = true;
    		mc.destext.selectable = false;
    		mc.destext.autoSize = true;
    		mc.destext.multiline = true;
    		mc.destext.wordWrap = true;
    		mc.destext.htmlText = category;
    		mc.destext.background = true;
    		mc.destext.embedFonts = true;
    		mc.destext.backgroundColor = 0x292E4C;
    		titleStyle = new TextFormat();
    		titleStyle.color = 0xffffff;
    		titleStyle.font = "Myriad Pro";
    		titleStyle.size = "14";
    		titleStyle.leftMargin = 2;
    		titleStyle.align = "left";
    		titleStyle.bold = true;
    		mc.destext.setTextFormat(titleStyle);
    		var levelTwo = levelOne[i].childNodes;
    		for (j=0; j<levelTwo.length; j++) {
    			var artikelnaam = levelTwo[j].firstChild.firstChild.nodeValue;
    			//trace(artikelnaam)
    			var tekst = levelTwo[j].firstChild.nextSibling.firstChild.nodeValue;
    			//trace(tekst)
    			var link = levelTwo[j].firstChild.nextSibling.nextSibling.firstChild.nodeValue;
    			//trace(link)
    		}
    		var mcartikelnaam = mc.createEmptyMovieClip("tipp"+j, j);
    		mcartikelnaam.createTextField("artik", 2, 250, 0, 200, 20);
    		mcartikelnaam.artik.htmlText = artikelnaam;
    		mcartikelnaam._y = y1;
    		y1 += mcartikelnaam._height+5;
    		mc.destext.setTextFormat(titleStyle);
    		mc._y = y;
    		y += mc._height+10;
    	}
    };
    stop();
    As of "var artikelnaam" the code doesn't correspond to the category mc's.
    The update (more articles) xml-file is:

    Code:
    <?xml version="1.0"?>
    <articles>
    <category name="Category 1">
    	<article>
    		<name>articlename 1 of category 1</name>
    		<text>articletext 1 van category 1</text>
    		<link>mailform.php?artikelID=1</link>
    	</article>
    	<article>
    		<name>articlename 2 of category 1</name>
    		<text>articletext 2 van category 1</text>
    		<link>mailform.php?artikelID=2</link>
    	</article>
    	<article>
    		<name>articlename 3 of category 1</name>
    		<text>articletext 3 van category 1</text>
    		<link>mailform.php?artikelID=3</link>
    	</article>
    </category>
    <category name="Category 2">
    	<article>
    		<name>articlename 1 of category 2</name>
    		<text>articletext 1 van category 2</text>
    		<link>mailform.php?artikelID=4</link>
    	</article>
    	<article>
    		<name>articlename 2 of category 2</name>
    		<text>articletext 2 van category 2</text>
    		<link>mailform.php?artikelID=5</link>
    	</article>
    	<article>
    		<name>articlename 3 of category 2</name>
    		<text>articletext 3 van category 2</text>
    		<link>mailform.php?artikelID=6</link>
    	</article>
    </category>
    <category name="Category 3">
    	<article>
    		<name>articlename 1 of category 3</name>
    		<text>articletext 1 van category 3</text>
    		<link>mailform.php?artikelID=7</link>
    	</article>
    	<article>
    		<name>articlename 2 of category 3</name>
    		<text>articletext 2 van category 3</text>
    		<link>mailform.php?artikelID=8</link>
    	</article>
    	<article>
    		<name>articlename 3 of category 3</name>
    		<text>articletext 3 van category 3</text>
    		<link>mailform.php?artikelID=9</link>
    	</article>
    	<article>
    		<name>articlename 4 of category 3</name>
    		<text>articletext 4 van category 3</text>
    		<link>mailform.php?artikelID=10</link>
    	</article>
    </category>
    </articles>
    I'm sorry for the Dutch words, I hope you get the idea. Thanx very much again for any help!

    Best regards,
    Michiel
    Last edited by Schenkius; 07-20-2006 at 06:43 AM.

  8. #8
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    Many ways to find the number of articles. If using xPath, its just a very simple one line command. Alternatively, you could create a custom recursive function to search each node and find all the nodeNames with article

    But for the sake of simplicity since you already got your loop code setup, here are two other methods.

    Method 1) create a number variable that will act as a counter for the number of articles. Put it inside your article loop (2nd loop) and have it increment the value during each iteration of the loop.

    Code:
    // create number variable
    var numOfArticles = 0;
    var levelOne = this.firstChild.childNodes;
    for (i=0; i<levelOne.length; i++) {
    
    	// display name attribute for each category node
    	trace("levelOne name: "+levelOne[i].attributes.name);
    
    	// setup the next loop to go through article nodes
    	var levelTwo = levelOne[i].childNodes;
    	for (j=0; j<levelTwo.length; j++) {
    
    		// display nodeName for articles nodes under each category
    		trace("levelTwo: "+levelTwo[j].nodeName);
    
    		// to show the nodeValue for the name node under article node use
    		// levelTwo[j].childNodes[0].childNodes[0].nodeValue
    
    		// increment counter by 1
    		numOfArticles++;
    	}
    }
    // Display total number of articles
    trace("numOfArticles: "+numOfArticles);
    Method 2) Create an array to hold the article nodes. Use Array.push to add the nodes into the array during the article loop. Then use Array.length to show the number of indexes (article nodes) in the array.

    Code:
    // create Array
    var aArticles = new Array();
    var levelOne = this.firstChild.childNodes;
    for (i=0; i<levelOne.length; i++) {
    
    	// display name attribute for each category node
    	trace("levelOne name: "+levelOne[i].attributes.name);
    
    	// setup the next loop to go through article nodes
    	var levelTwo = levelOne[i].childNodes;
    	for (j=0; j<levelTwo.length; j++) {
    
    		// display nodeName for articles nodes under each category
    		trace("levelTwo: "+levelTwo[j].nodeName);
    
    		// to show the nodeValue for the name node under article node use
    		// levelTwo[j].childNodes[0].childNodes[0].nodeValue
    
    		add the article node
    		aArticles.push(levelTwo[j]);
    	}
    }
    // Display total number of articles by checking number of indexes
    trace("aArticles.length: "+aArticles.length);
    I just added the entire article node to my aArticles array, but ofcourse you could add a specific node (or nodes). It's just an example. Also I named my array as "aArticles" just because I liked using the "a" prefix to remind me its an array.

  9. #9
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    Ah, I see you've edited your post while I was replying. LOL. As to your new question. I'll take a look at your code and answer you back in a bit.

  10. #10
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    Now the thing is (also new for me) is that on mouse over on one of the category names, I would like to show the corresponding article in movieclips. Again, I know how to create those mc's, but I have no clue how to combine the right articles to the right category... do you have any idea how to do that?
    Yeah easy to do, but a bit harder to explain. I'm assuming you want each category movieclip to show their list of articles, represented by movieclips with the article name.

    Read this on how to set an id value to buttons, in your case the category movieclip. I wrote it (see the "pigpen" post) to someone who was trying have each of his buttons have a corresponding number to his database. If you understand this, then it'll give you an idea on how to use custom id to control specific article movieclips during dynamically created button events (onRelease, rollOver functions).

    The key is knowing how to assign an id value to dynamic created movieclips/buttons, and then how to retrieve that id during a button event (ie rollOver or onRelease).

    But you may think that your situation is different. On a mouse over of the category movieclip, you want to show a bunch of article movieclips, not just a single movieclip. Hint: use a container movieclip to hold each set of article movieclips. That way you can have the category button, show and hide that container movieclip, instead of needing to have code that goes through each of the article movieclips for that category.

    You'll probably have many questions, so feel free to ask. I just wanted you to first understand the coding logic of this first.

  11. #11
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    Thank you very much for your guidance. Still I'm stuck with the second array. If you look at the attached fla, and test the movie, the output shows that I managed to trace the articles, but in creating mc's with the articles, something goes wrong. Of course only the article names of the last category are shown, I tried positioning the 2nd array at different places in the code, but I had no succes. I have no clue how to solve this...
    I get your point that the category mc's can display and hide the corresponding articles, I did that myself with a "linear" xml-file.

    I'm very interested on how to solve this!

    Below you'll find the code that's in the fla.

    Thanks!

    Michiel

    Code:
    System.useCodePage = true;
    percent = "Bezig met laden...";
    myXML = new XML();
    myXML.load("data.xml");
    myXML.ignoreWhite = true;
    myXML.onLoad = function() {
    	//var levelOne = this.firstChild.childNodes;
    	//trace(levelOne[0].attributes.name); // displays "category one"
    	var levelOne = this.firstChild.childNodes;
    	createEmptyMovieClip("hold", 1);
    	createEmptyMovieClip("hold1", 2);
    	for (i=0; i<levelOne.length; i++) {
    		var category = levelOne[i].attributes.name;
    		var mc = hold.createEmptyMovieClip("description"+i, i);
    		mc.createTextField("destext", 1, 0, 0, 200, 20);
    		mc.destext.html = true;
    		mc.destext.selectable = false;
    		mc.destext.autoSize = true;
    		mc.destext.multiline = true;
    		mc.destext.wordWrap = true;
    		mc.destext.htmlText = category;
    		mc.destext.background = true;
    		mc.destext.embedFonts = true;
    		mc.destext.backgroundColor = 0x292E4C;
    		titleStyle = new TextFormat();
    		titleStyle.color = 0xffffff;
    		titleStyle.font = "Myriad Pro";
    		titleStyle.size = "14";
    		titleStyle.leftMargin = 2;
    		titleStyle.align = "left";
    		titleStyle.bold = true;
    		mc.destext.setTextFormat(titleStyle);
    		mc._y = y;
    		y += mc._height+10;
    		mc.id = i;
    		var levelTwo = levelOne[i].childNodes;
    		for (j=0; j<levelTwo.length; j++) {
    		var article = levelTwo[j].childNodes;
    		trace(article);
    		var articlename = levelTwo[j].firstChild.firstChild.nodeValue;
    		//trace(articlename);
    		var tekst = levelTwo[j].firstChild.nextSibling.firstChild.nodeValue;
    		//trace(tekst);
    		var link = levelTwo[j].firstChild.nextSibling.nextSibling.firstChild.nodeValue;
    		//trace(link)
    		var mcart = hold1.createEmptyMovieClip("arti"+j, j);
    		mcart.createTextField("titel", 1, 300, 0, 200, 20);
    		mcart.titel.autoSize = true;
    		mcart.titel.multiline = true;
    		mcart.titel.wordWrap = true;
    		mcart.titel.htmlText = articlename;
    		mcart._y = mcarty;
    		mcarty += mcart._height+10;
    		//trace(levelTwo);
    		mc.onRelease = function() {
    			trace("id: "+this.id);
    		};
    	}
    	
    	}
    };
    stop();
    Attached Files Attached Files

  12. #12
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    I'm a bit further now, I'm able to create an mc with textfield when clicking on a category. The textfield shows the id of the button. Is this the way I should go, and what would be the next step?

    Below you'll find the code,. thanx again for your help!

    Michiel

    Code:
    //#include "RegExp.as"
    System.useCodePage = true;
    percent = "Bezig met laden...";
    myXML = new XML();
    myXML.load("data.xml");
    myXML.ignoreWhite = true;
    myXML.onLoad = function() {
    	var levelOne = this.firstChild.childNodes;
    	createEmptyMovieClip("hold", 1);
    	createEmptyMovieClip("hold1", 2);
    	for (i=0; i<levelOne.length; i++) {
    		var category = levelOne[i].attributes.name;
    		var mc = hold.createEmptyMovieClip("description"+i, i);
    		mc.createTextField("destext", 1, 0, 0, 200, 20);
    		mc.destext.html = true;
    		mc.destext.selectable = false;
    		mc.destext.autoSize = true;
    		mc.destext.multiline = true;
    		mc.destext.wordWrap = true;
    		mc.destext.htmlText = category;
    		mc.destext.background = true;
    		mc.destext.embedFonts = true;
    		mc.destext.backgroundColor = 0x292E4C;
    		titleStyle = new TextFormat();
    		titleStyle.color = 0xffffff;
    		titleStyle.font = "Myriad Pro";
    		titleStyle.size = "14";
    		titleStyle.leftMargin = 2;
    		titleStyle.align = "left";
    		titleStyle.bold = true;
    		mc.destext.setTextFormat(titleStyle);
    		mc._y = y;
    		y += mc._height+10;
    		mc.id = i;
    		var levelTwo = levelOne[i].childNodes;
    		for (j=0; j<levelTwo.length; j++) {
    			var article = levelTwo[j].childNodes;
    			//trace(article);
    			var articlename = levelTwo[j].firstChild.firstChild.nodeValue;
    			//trace(articlename);
    			var tekst = levelTwo[j].firstChild.nextSibling.firstChild.nodeValue;
    			//trace(tekst);
    			var link = levelTwo[j].firstChild.nextSibling.nextSibling.firstChild.nodeValue;
    			//trace(link)
    			mc.onRelease = function() {
    				//trace("id: "+this.id);
    				var mcart = this.createEmptyMovieClip("mcartg", 50);
    				mcart.createTextField("titel", 1, 300, 0, 200, 20);
    				mcart.titel.autoSize = true;
    				mcart.titel.multiline = true;
    				mcart.titel.wordWrap = true;
    				mcart.titel.htmlText = this.id;
    			};
    		}
    	}
    };
    stop();

  13. #13
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    Hi Michiel,

    Glad to see you progressed. I was away for the weekend and just got back. I wrote this example for you to illustrate what I mentioned earlier.

    This code loads your xml document "data.xml" and creates category movieclips that acts as buttons, and creates article movieclips. If you click on the category buttons it will toggle the display of the article movieclips for that category. Read the following to understand how I do this.

    The key here to understand is that I group each set of articles into container movieclips, "articleHolder"+i" for each category.

    So articleHolder0, holds all the article movieclips for category 1, articleHolder1 holds all the article movieclips for category 2, etc, etc. That way I can easily hide and show the article movieclips for that category by simply setting the visibility of the appropriate articleHolder movieclip (ie. articleHolder0._visible = false). Otherwise I'd have to go through each article movieclip for that category, and change all of their visibility settings.

    I made a simple toggle by using this line to keep switching the false and true value on each click of the category button.

    _root["articleHolder"+this.id]._visible = !_root["articleHolder"+this.id]._visible;

    Anyway I hope this gives you an idea on how to proceed. It's just meant to show you the coding logic. BTW, I separated the mc making code into its own function called "createMenu". You don't have to do this ofcourse, but it was just easier for me to take it out of the xml loading code, as the code is getting rather long and easier to edit for me if it was in its own function. Just a personal preference.

    If you still get stuck, let me know.

    Code:
    my_xml = new XML();
    my_xml.ignoreWhite = true;
    my_xml.load("data.xml");
    my_xml.onLoad = parseXMLData;
    function parseXMLData(success) {
    	if (success) {
    		var theRoot:XMLNode = this.firstChild;
    		createMenu(theRoot); 
    	} else {
    		trace("There was an error parsing the XML data");
    	}
    }
    
    function createMenu(theRoot) {
    	var levelOne = theRoot.childNodes;
    	//
    	// category loop
    	for (i=0; i<levelOne.length; i++) {
    		
    		var levelTwo = levelOne[i].childNodes;
    		//
    		// // creating movieclips out of the xml
    		// make variable to use as label for textfield
    		var categoryName = levelOne[i].attributes.name;
    
    		// create mcs
    		var cat = this.createEmptyMovieClip("cat"+i, this.getNextHighestDepth());
    		// position mcs
    		cat._y += i * 22;
    
    		// textfield
    		var tf:TextField = cat.createTextField("tf", 0, 0, 0, 0, 20);
    		tf.autoSize = "left";
    		tf.border = true;
    		tf.text = categoryName;
    
    		// clip to hold article movieClips, so I can target them as a group
    		var articleHolder = this.createEmptyMovieClip("articleHolder"+i, this.getNextHighestDepth());
    		articleHolder._x = (i * 145) + 75; // 75 is an indent so no overlap over cat buttons
    		//
    		cat.id = i;
    		cat.onRelease = function() {
    
    			// toggle articleHolder mc visibility
    			_root["articleHolder"+this.id]._visible = !_root["articleHolder"+this.id]._visible;
    		}
    
    		// article loop
    		for (j=0; j<levelTwo.length; j++) {
    			
    			var articleName = levelTwo[j].childNodes[0].childNodes[0].nodeValue;
    			// mc creation
    			var mcArticle = articleHolder.createEmptyMovieClip("mcArticle"+j, articleHolder.getNextHighestDepth());
    			// position mcs
    			mcArticle._y += j * 20;
    			var articleTF:TextField = mcArticle.createTextField("articleTF", 0, 0, 0, 0, 20);
    			articleTF.autoSize = "left";
    			articleTF.border = true;
    			articleTF.text = articleName;
    		}
    	}
    }

  14. #14
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    Yeah, I think I have everything right now! Now I can brush it up and go on with the development of another functionality, but that shouldn't be a problem: when visitors click on one the links, then a form will show up with the variable "articleLink" hidden somewhere, to be sent to a mailscript.

    I've attached the current fla, do you also think everything works right now? I hope other people will use this post to learn this "a bit deeper" xml-functionality.
    I'll show the final result for my client in a couple of days, okay?

    I've just a little question though: I would like the article columns only to disappear when another cat-mc has a RollOver. Now, the visibility changes on every mc RollOver, but of course people should be able to select an article. So instead of toggling in the same button, I would like only other cat-buttons to be able to let another's category articles disappear (I hope you understand waht I mean.

    Pigpen, many thanks for your patience and infinite wisdom . You really take the time to help people, also on other boards I noticed. Great job!

    I still mean it: have a drink with me the next time you visit Holland. My house is at 15 minutes drive from Schiphol and/or Amsterdam, so drop by if you want!

    Best regards,
    Michiel

    Code:
    System.useCodePage = true;
    myXML = new XML();
    myXML.load("data.xml");
    myXML.ignoreWhite = true;
    myXML.onLoad = function() {
    	var levelOne = this.firstChild.childNodes;
    	createEmptyMovieClip("hold", 1);
    	createEmptyMovieClip("hold1", 2);
    	createEmptyMovieClip("hold2", 3);
    	for (i=0; i<levelOne.length; i++) {
    		var levelTwo = levelOne[i].childNodes;
    		var categoryName = levelOne[i].attributes.name;
    		var cat = hold.createEmptyMovieClip("cat"+i, i);
    		cat._y += i*22;
    		cat.createTextField("tf", 1, 0, 0, 200, 20);
    		cat.tf.autoSize = true;
    		cat.tf.border = true;
    		cat.tf.htmlText = categoryName;
    		cat.id = i;
    		var articleHolder = hold1.createEmptyMovieClip("articleHolder"+i, i);
    		articleHolder._x = (i*145)+75;
    		hold1["articleHolder"+i]._visible = false;
    		cat.onRollOver = function() {
    			hold1["articleHolder"+this.id]._visible = !hold1["articleHolder"+this.id]._visible;
    		};
    		
    		for (j=0; j<levelTwo.length; j++) {
    			var articleName = levelTwo[j].childNodes[0].childNodes[0].nodeValue;
    			var articleText = levelTwo[j].childNodes[1].childNodes[0].nodeValue;
    			var articleLink = levelTwo[j].childNodes[2].childNodes[0].nodeValue;
    			var mcArticle = articleHolder.createEmptyMovieClip("mcArticle"+j, j);
    			mcArticle._y += j*20;
    			mcArticle.createTextField("articleTF", 1, 0, 0, 200, 20);
    			mcArticle.articleTF.autoSize = true;
    			mcArticle.articleTF.border = true;
    			mcArticle.articleTF.htmlText = articleName;
    			mcArticle.createEmptyMovieClip("linkHold", 50);
    			mcArticle.linkHold.artText = articleText;
    			mcArticle.linkHold.linkText = articleLink;
    			mcArticle.onRelease = function() {
    				theText.htmlText = this.linkHold.artText;
    				theLink.htmlText = this.linkHold.linkText;
    			};
    		}
    	}
    };
    stop();
    Attached Files Attached Files

  15. #15
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    Almost eveything is in place now, except for the article-name placement. See the example at this address . Click on the dark blue box, left center of the screen, to enter the functionality.
    If you move your mouse over the categories, the articlename-groups are not all at the same _y as the first article group. I couldnt figure ut how to change it so that all article groups will appear at the right _y (so, at the same place on top of each other).

    Also I didn't manage to create a goo toggle functionality, I really hope you can help me with these last two steps!

    Thanx again,

    Michiel

  16. #16
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    Quote Originally Posted by Schenkius
    Almost eveything is in place now, except for the article-name placement. See the example at this address . Click on the dark blue box, left center of the screen, to enter the functionality.
    I can't see your example. Your flash home page and loads fine, but when I click on the menu item, all I get is a loading message "bezeg met laden...".

    Maybe I'm not click on the right menu item. I tried clicking on "applicatieservices" and "projectservices" button.

    -------------------------------------------------
    Quote Originally Posted by Schenkius
    Also I didn't manage to create a goo toggle functionality,
    So you want to hide all the other articles except for the one currently rollOver. Sure that's easy to do. Using my example code I posted earlier I would do this:

    Create an array to hold all category button movieclips.
    Code:
    var categories = new Array();
    In the loop that creates the category movie clips, I'll fill my array with the category clips by using the Array.push method.
    Code:
    categories.push(cat);
    In the rollOver function for the category clip, I then loop through all the category clips in the array and change the visiblity to false. In this loop I also, and this is the important part, check the id of each category clip before setting its visibility to false.
    Code:
    for (items in categories) {
    	if (categories[items].id != this.id) {
    		trace("categories id besides current: "+categories[items].id);
    		// hide other article container clips
    		_root["articleHolder"+ categories[items].id]._visible = false;
    	}
    }
    Notice the "if" check -- as long as the id is not equal to the current id of the currently rolled over category clip, then its ok to change the visibility to false.

    Also be sure to hide the articleHolder container clip as its default state. So in the category loop, after you made your articleHolder clip, you'd have:
    Code:
    articleHolder._visible = false;
    Completed code with above modifications (with important bits bolded):
    Code:
    var categories = new Array();
    
    my_xml = new XML();
    my_xml.ignoreWhite = true;
    my_xml.load("data.xml");
    my_xml.onLoad = parseXMLData;
    function parseXMLData(success) {
    	if (success) {
    		var theRoot:XMLNode = this.firstChild;
    		createMenu(theRoot); 
    	} else {
    		trace("There was an error parsing the XML data");
    	}
    }
    
    function createMenu(theRoot) {
    	var levelOne = theRoot.childNodes;
    	//
    	// category loop
    	for (i=0; i<levelOne.length; i++) {
    		
    		var levelTwo = levelOne[i].childNodes;
    		//
    		// // creating movieclips out of the xml
    		// make variable to use as label for textfield
    		var categoryName = levelOne[i].attributes.name;
    
    		// create mcs
    		var cat = this.createEmptyMovieClip("cat"+i, this.getNextHighestDepth());
    		cat._y += i * 22;
    
    		// texfield
    		var tf:TextField = cat.createTextField("tf", 0, 0, 0, 0, 20);
    		tf.autoSize = "left";
    		tf.border = true;
    		tf.text = categoryName;
    
    		// clip to hold article movieClips, so I can target them as a group
    		var articleHolder = this.createEmptyMovieClip("articleHolder"+i, this.getNextHighestDepth());
    		articleHolder._x = (i * 145) + 75; // 75 is an indent so no overlap over cat buttons
    		//
    		// hide articleHolder
    		articleHolder._visible = false;
    		//
    		cat.id = i;
    		//
    		// add category mc clips to categories array
    		categories.push(cat);
    		//
    		// add rollOver event handler to category mc clips
    		cat.onRollOver = function() {
    			//
    			// show articleHolder associated with this category
    			_root["articleHolder"+this.id]._visible = true;
    			//
    			// hide all other category button except for current selected
    			// loop through categories array
    			for (items in categories) {
    				//
    				// make sure id does not match current id
    				if (categories[items].id != this.id) {
    					trace("categories id besides current: "+categories[items].id);
    					// hide other article container clips
    					_root["articleHolder"+ categories[items].id]._visible = false;
    				}
    			}
    			//
    			/* alternative loop method
    			for (var n=0; n < categories.length; n++) {
    				//trace("categories[n].id: "+categories[n].id);
    				if (categories[n].id != this.id) {
    					//
    					trace("other id's: "+categories[n].id);
    					_root["articleHolder"+ categories[n].id]._visible = false;
    				}
    			}*/
    		}
    
    		// article loop
    		for (j=0; j<levelTwo.length; j++) {
    			
    			var articleName = levelTwo[j].childNodes[0].childNodes[0].nodeValue;
    			// mc creation
    			var mcArticle = articleHolder.createEmptyMovieClip("mcArticle"+j, articleHolder.getNextHighestDepth());
    			mcArticle._y += j * 20;
    			var articleTF:TextField = mcArticle.createTextField("articleTF", 0, 0, 0, 0, 20);
    			articleTF.autoSize = "left";
    			articleTF.border = true;
    			articleTF.text = articleName;
    		}
    	}
    }
    You may not be familiar with the "for...in" loop which I used to loop though the array elements of the categories array. You could also use a regular "for" loop and use the Array.length (ie. categories.length) as a max number of iterations. I put that version in comments (see: "alternative loop method"), right below the "for...in" loop for comparison. I did that for your educational purposes.

    Either method is fine, although for this case, I used the "for in" loop method as it resulted in shorter code.

    Let all of that digest as I'm sure thats a lot to take in. Believe me its way easier to do than to explain. I hope that makes sense.
    Quote Originally Posted by Schenkius
    I still mean it: have a drink with me the next time you visit Holland. My house is at 15 minutes drive from Schiphol and/or Amsterdam, so drop by if you want!
    I may have to take you up on that offer next time I'm in Holland. =)

  17. #17
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi Pigpen,

    Ow, I wouldn't have created that one on my own, thanx! I learn a lot about arrays, traditionally for outside my comfort zone, lol!

    There's only one problem left: I would like every bunch of articles appear at the top.

    The solution lies somewhere in this piece of code:
    Code:
    //mcArticle._y += j*18;
    mcArticle._y = yart;
    yart += mcArticle._height+2;
    When I try
    Code:
    mcArticle._y += j*18;
    as in your sample, every bunch appears at top. How ever, if you look in the attached fla, test it en move your mouse over category 2, you will see that I made the first article name longer than one line, the article mc is bigger than the others. Then your sample
    Code:
    mcArticle._y += j*18;
    does not work.

    When I try my usual code,
    Code:
    mcArticle._y = yart;
    yart += mcArticle._height+2;
    the articles are all aligned perfectly from one to another, but then every bunch of articles start at their "own" ._y=0.

    I tried everything I could think of, do you know how to solve this?

    Thanx again!

  18. #18
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    I downloaded your .fla but didn't see any overlapping issues with the article mcs when using:
    Code:
    mcArticle._y += j*18;
    Perhaps its because I don't have the fonts you are using -- Myriad and Avenir.

    However, I could see the different height problem when plugging in your code:

    Code:
    mcArticle._y = yart;
    yart += mcArticle._height+2;
    Try this instead:

    Code:
    mcArticle._y = j * (mcArticle._height+2);
    Important, make sure the above line comes somewhere after the line that assigns a value to the textField.text property. Because you are using the height property "mcArticle_height", you want it calculated after some text has been assigned to the textfield inside mcArticle, otherwise the height for mcArticle will be "0" or "1" or some small number.

    For example, this is ok.
    Code:
    mcArticle.articleTF.htmlText = articleName;
    mcArticle.createEmptyMovieClip("linkHold", 50);
    mcArticle.linkHold.artText = articleText;
    mcArticle.linkHold.linkText = articleLink;
    mcArticle.onRelease = function() {
    	theText.htmlText = this.linkHold.artText;
    	theLink.htmlText = this.linkHold.linkText;
    };
    // this is ok placement. 
    mcArticle._y = j * (mcArticle._height+2);
    This is not ok:
    Code:
    // this is not ok since mcArticle height is still small
    // since its textField (articleTF) does not have any text yet.
    mcArticle._y = j * (mcArticle._height+2);
    
    mcArticle.articleTF.htmlText = articleName;
    mcArticle.createEmptyMovieClip("linkHold", 50);
    mcArticle.linkHold.artText = articleText;
    mcArticle.linkHold.linkText = articleLink;
    mcArticle.onRelease = function() {
    	theText.htmlText = this.linkHold.artText;
    	theLink.htmlText = this.linkHold.linkText;
    };
    If you still have problems, maybe show a screenshot of the problem, and another screenshot of the way you want it to be.

  19. #19
    Senior Member
    Join Date
    May 2001
    Location
    Holland
    Posts
    286
    Hi,

    I tried your suggestion but that didn't work either. I've attached a new .fla with Verdana, that way you can see what I mean when you move over category 2.

    Thanx!
    Attached Files Attached Files

  20. #20
    Senior Member
    Join Date
    Oct 2005
    Posts
    148
    downloaded your new fla. I still don't see the problem.

    I rolled over category 2 and the article mcs on the right side look fine. They are in the same exact place as the articles for category 1 and 3.

    Can you provide a screenshot of how it looks on your computer?

    I'm attaching a screenshot what it looks like on mine when category 2 is rolled over.

    BTW, I'm using the latest xml document that you posted here. Maybe your xml doc is different?
    Attached Images Attached Images

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center