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?
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.
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?
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.
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?
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.
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.
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!
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 variablevar 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 1numOfArticles++;
}
}
// Display total number of articlestrace("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 Arrayvar 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 nodeaArticles.push(levelTwo[j]);
}
}
// Display total number of articles by checking number of indexestrace("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.
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.
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 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();
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.
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;
}
}
}
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!
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!
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.
-------------------------------------------------
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.
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. =)
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?
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.
// 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.
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.