Are you Flex-ing in Europe or the UK?

english mobile

The European eLearning Summit (EeLS) is offering quality Flex training at a great price at Nottingham University on August 22nd. The class will be taught by Matthew Boles, and pricing starts at UK£50 (plus VAT), and the price includes lunch.

Musings on AdvancedDataGrid (Part 5)

english mobile

Up to part 4, I've been talking about the AdvancedDataGrid itself and the properties it has that are supposed to make your life easier, like styleFunction and iconFunction. And they do, once you understand them. But now I'd like to turn my attention to the data source I was using to drive my AdvancedDataGrid (ADG).

My AdvancedDataGrid is being used as a menu on an eLearning application. The application has various tasks that the user must complete. Once a task is complete, it is shown again in review mode, which provides the student with remediation on what he did wrong or right. The student can also view reports of what he did in a given task. So each task will be available in three modes: normal, review, and analysis. The mode will be determined by the top-level container.
To this end, I created an array of MenuContainer Value Objects (VO) that contained a number of Task VO's. I assigned these to a HeirarchicalData dataProvider in the ADG. I immediately realized that the itemClick event just gave me the Task VO, and the Task knew nothing about its parent (and rightly so). Apparently, the itemRenderer also knew nothing about where the Task fell in the data structure, nor anything else in the ADG.

I realized it was a slippery problem, since even if I were to loop through the MenuContainers and find the Task that was selected, I would only find the first instance of it. So I decided to wrap my Task class in another class that had two properties, task and UID. In this class, TaskUID, I simply used UIDUtil to create a UID for this instance of the task.

Once I had that accomplished, I decided to take one more squint at the docs before I built a function to loop through and find my TaskUID. I trolled the language reference only on the word hierarchical. I'd looked at the HierarchicalCollectionView before, but the description implies that this is for making flat collections look hierarchical (heck, it actually says it!). However, this class does include a method, getParentItem(), which looked perfect for my needs.

In a wild leap of faith, I cast the event.currentTarget.dataProvider from the itemClick event from HierarchicalData to HierarchicalCollectionView and the method worked! It gave me a reference to the MenuContainer from the TaskUID. I have no idea what the differences are between those classes, so I wouldn't guarantee all methods would work when you do this kind of casting, but this worked for me!

Musings on AdvancedDataGrid (Part 4)

english mobile

So, in part 3, I gave up on my extension of the AdvancedDataGridItemRenderer altogether and set my extended AdvancedDataGridGroupItemRenderer as both the itemRenderer and groupItemRenderer on the AdvancedDataGrid. This gave me a nice uniform appearance on all of my itemRenderers. So I set off happily to write my iconFunction.

This turned out to work exactly as advertised, with only one hitch--my leaf icons weren't rendering. Had I misunderstood? Did the iconFunction (as opposed to groupIconFunction) work only for grouping rows? Well, no, as it turns out.

If you'll recall, way back in Part 2 I had a problem getting my styles to show up in my first column, so I set the itemRenderer on that column to my extended AdvancedDataGridItemRenderer. Even after I did this, though, some cells still didn't show my styles. At the time, I didn't understand what that meant.

Lesson Number 3: All itemRenderers in the tree column will use the specified groupItemRenderer, unless you specifically tell that column to use something else. Even if you do tell that column to use something else, it will still use the groupItemRenderer for (ahem) grouped items.

Once I figured that out, it was obvious to me that by removing the itemRenderer property on that column, I would then have 100% of cells using my extended AdvancedDataGridGroupItemRenderer, which had the existing icon functionality plus my added functionality for setting the background based on a style passed in through the styleFunction.

Great! Wonderful! But I then found that my particular data structure depended on knowing something about both the parent node and the child node in order to know what to do with an item click, and I couldn't figure out how to get the information about a strongly typed parent from a strongly typed child that might be the child of more than one parent.

Tomorrow, I will write about how I got this information.

Musings on AdvancedDataGrid (Part 3)

english mobile

Review Part 2

The author of the blog post I originally found that inspired this journey said that this method would not cause the selection and rollover indicators to be obscured in the same way as this method. But I really wanted to be able to see these indicators, rather than a tiny edge around each row. So I was determined that I was going to get my AdvancedDatagridItemRenderer to allow me to see these indicators through it.

The first thing I'd tried, just setting the alpha property, hadn't worked. The next thing I tried was to try to use the graphics functions to draw a background like I did in the AdvancedDatagridGroupItemRenderer. Unfortunately, since the AdvancedDatagridItemRenderer does not inherit from UIComponent or DisplayObjectContainer, so it neither had a graphics object of its own nor any way to add one.

So I stuck my nose back into the docs and discovered that my TextField had a colorTransform object that I should be able to manipulate to change the alpha transparency. Well, I was able to change its alpha property, but there was absolutely no visible change.

Finally, I realized I was going to have to leave the Flex world and see what the Flash world had to offer. So I came across this post and was able to get the transparency by changing the blend mode. Still, my AdvancedDatagridItemRenderer and AdvancedDatagridGroupItemRenderer did not match, because the text in the AdvancedDatagridItemRenderer was semitransparent and the AdvancedDatagridGroupItemRenderer text was not. Lesson Number 2: Anything that inherits from TextField is only going to be able to support alpha transparency with difficulty, and even then the entire component, including the text, will be alpha transparent.

So I had the simple idea that I could use the AdvancedDatagridGroupItemRenderer to do all the item rendering.

Tomorrow, I will talk about getting the icons to render properly.

Musings on AdvancedDataGrid (Part 2)

english mobile

Review Part 1

I'd found a neat little sample that shows how to change the background color on the row by extending AdvancedDataGridItemRenderer (ADGIR) to set the existing background and backgroundColor properties based on a style set on the component.

I had no trouble copying this, but I found that for some reason the entire first column stubbornly refused to pick up my carefully applied color. Undaunted, I set the itemRenderer property of the first column explicitly to my extended ADGIR.

The result I had was closer to what I wanted--most of the cells in that column now had the color my styleFunction had insisted upon--but the ones with the triangle in them remained white. Aha! Clearly this was a different thing altogether, so I went back to the docs and looked for inspiration. It seems that the uncolored cells were being rendered by another component, the AdvancedDataGridGroupItemRenderer (ADGGIR).

So I set about extending that worthy component. At first, I thought I'd be able to just cut and paste the code I'd modified for my ADGIR, but no such luck. Unfortunately, the ADGGIR had no background or backgroundColor properties. So I fell back on more conventional tactics, drawing a rectangular background on the component when the style changed. First lesson: the AdvancedDataGridItemRenderer is based on the Flash TextField component and the AdvancedGridGroupItemRenderer is based on UIComponent. These two components have completely different capabilities and must be dealt with in entirely different ways.

As soon as I saw my extended ADGGIR next to the extended ADGIR, I realized that the ADGIR was not yeilding to my attempts to set its alpha transparency. I'd included code in both to set the alpha transparency, but it was only working in the ADGGIR.

Tomorrow, I'll talk about my attempts to add alpha transparency to the ADGIR.

Musings on AdvancedDataGrid (Part 1)

english mobile

This last week, I had my first experience with the AdvancedDataGrid component. I knew I needed to have multi-column heirarchical data display. I also needed to be able to dynamically color and also set an icon each row based on the content of the data item. I scoured the docs for a component that would meet these requirements, and the ADG's styleFunction and iconFunction seemed like they would fit the bill perfectly--and ultimately they did. But in the meantime, they led me on a merry chase because the docs didn't include all the pieces I needed to understand what was happening. Ultimately I did understand it, so I thought I'd pass my surmises along in the hope that others can shortcut the many hours I spent on the problem.

Tomorrow, I'll talk about the relationship between AdvancedDataGridItemRenderer and AdvancedDataGridGroupItemRenderer.

Using a CSS TypeSelector with an itemRenderer

english mobile

Today, I had more fun with item renderers. I had a component I was working on to try to prototype some new functionality, and I had set up styles for it in the <mx:styles> declaration of the Application tag. If I put my component in a container in the main Application, the style came through fine. If I used it as an itemRenderer of a List based class, only the text styles worked.

It seems that when you use a component this way, Flex will assign ListBaseContentHolder as the style name instead of the class name, but for some reason this only negates things like backround colors—text declarations come through just fine. This interesting feature isn't documented anywhere, so it took me a whole day to figure out the fix, which is so simple I wanted to pound my head against the wall till I couldn't see straight.

override protected function commitProperties():void{
this.styleName = this.className;
}

Hope this saves someone some time!