bgx:components logo
© 2004 -2005
Bernhard Gaul



Bgx Flexible List Component (Flash MX 2004) : Usage examples

Overview

Preparing the Data

Unlike the Macromedia List component, the Bgx Flexible List has no separate label and data properties. More like with the Datagrid component you need to provide an Array of Objects and can then decide how individual properties of these Objects shall appear in the list. By default the entire Object will be set as the data of each item. This way you have always access to any other data you might need.

For the following examples we use some random data, lets say something resembling a list of paintings and drawings for a catalogue.

Code example:

var ListData = new Array();

for (var i = 1; i < 11; i ++)
{
    var ListObj = new Object();

    if ( i == 1 || (i > 4 && i < 8) || i >= 9)
    {
        ListObj["icon"] = "IconPainting";
        ListObj["description"] = "Painting " + i;
        ListObj["ordercode"] = "PA/" + i;
    }
    else
    {
        ListObj["icon"] = "IconDrawing";
        ListObj["description"] = "Drawing " + i;
        ListObj["ordercode"] = "DR/" + i;
    }
    ListObj["price"] = i * 3 + ",00 €";
    ListObj["preview"] = "prev" + i + ".swf";
    ListData.push(ListObj);
}

Note: Using an XML structure like

<catalogue>
    <item icon="IconPainting"
         description="Painting 1"
         ordercode="PA/1"
         price="3,00 €"
         preview="prev1.swf"/>
  <item icon="IconPainting"
         description="Painting 2"
         ordercode="PA/2"
         price="6,00 €"
         preview="prev2.swf"/>
</catalogue>

you could easily use the Bgx Serialization Classes to create the same ListData Array, using the following:

//import the class
import bgx.BgxDesObject;

//global variables to hold deserialized data
var Data:Object;
var ListData:Array
;

//load xml from external file
var listXML:XML = new XML();
listXML.ignoreWhite = true;
listXML.onLoad = parseListData;
listXML.load("sample.xml");

//parse list data
function parseListData() {
    var rootNode:XMLNode = listXML.firstChild;
    Data = new BgxDesObject();
    Data.xmlNode = rootNode;
    Data.onParsed = getListData;
    Data.parse();
}

function getListData()
{
    ListData = Data.item;
}

back to top


Basic Usage

The following shows the minimum requirement to populate an instance of the Bgx Flexible List.

For this example an instance of the Bgx Flexible List component was dragged onto the stage and called mcBasicList.

The deafult itemClip BgxDefaultRecord resembles the standard Macromedia List in that there is only one label field and the option to define a standard icon image. The following binds the description property of each item to the label (i.e. the TextField called tbx0, see Documentation) and loads Movieclips from the Library with linkage names corresponding to the icon property into the icon image position.

mcBasicList.columnNames = ["description"];
mcBasicList.iconField = "icon";
mcBasicList.dataProvider = ListData;

Note: To populate the list it is enough to assign an appropriate Array as the dataProvider.

back to top


Scrolling

So far so good, but usualy you would like a list of that kind in a scroll pane:

To do so you can use the standard Macromedia ScrollPane. In this case, instead of dragging an instance of the Flexible List component onto the stage, make sure that you have a copy of the component in your Library and then use the linkage identifier "BgxFlexibleList" as the contentPath of the ScrollPane as shown below:

Then use the content Object of the ScrollPane almost in the same way as the component instance was used in the Basic Usage example:

var scrollList = mcScrollPane.content;
scrollList.columnNames = ["description"];
scrollList.iconField = "icon";
scrollList.dataProvider = ListData;

Note also that the background of the default itemClip as well as the ones of the StandardHighlight item examples in the Bgx List Item Samples available from the Common Libraries adjust automatically to the width of the SrollPane.

back to top


Multiple fields

You can easily bind more than one property to several TextFields. To do so it is necessary to use an itemClip that contains more than one TextField which must be named in sequence tbx0, tbx1, tbx2 etc.

For this example the Movieclip called BgxList3FieldsStandardHL was copied from the Bgx List Item Samples into the local library. The code below assigns this clip as the one to use as itemClip and defines the properties description, price and ordercode to be used for the TextFields.

Otherwise the code is the same as shown in the Scrolling example above.

var scrollList = mcScrollPane.content;
scrollList.itemClip = "BgxList3FieldsStandardHL";
scrollList.columnNames = ["description","price","ordercode"];
scrollList.iconField = "icon";
scrollList.dataProvider = ListData;

Simply add/remove other TextFields to/from this item clip or copies of the clip to create the item appearance you need.

back to top


Using Checkboxes

The Bgx List Item Samples available from the Common Libraries contain also two item examples to display Checkboxes.

The list on the left uses the BgxListBasicCheckboxes item, the right one BgxListCheckboxesStandardHL, which not only provides Checkboxes but also highlights the selected item (Note: an Item can be checked without being highlighted and vice versa).

The left item does not provide a background but you could change the bgClip as you like or draw a background behind the ScrollPane.

The following populates the lists and submits ordercode as the label field for the Checkboxes:

var scrollList = mcScrollPane.content;
scrollList.itemClip = "BgxListBasicCheckboxes";
scrollList.columnNames = ["ordercode"];
scrollList.rowHeight = 20;
scrollList.dataProvider = ListData;

var scrollList2 = mcScrollPane2.content;
scrollList2.itemClip = "BgxListCheckboxesStandardHL";
scrollList2.columnNames = ["ordercode"];
scrollList2.rowHeight = 19;
scrollList2.dataProvider = ListData;

Both item clips contain a Checkbox called cbx. To automatically select all items that have "Drawing" in the description property the following line was added to the item clips in the library:

cbx.selected = (data.description.indexOf("Drawing") > -1);

The following functions are assigned to the two buttons to select either drawings or paintings when the buttons are clicked:

function selectDrawings()
{
    for (var i = 0; i < ListData.length; i++)
    {
        var item = scrollList.getItemAt(i);
        item.cbx.selected = (item.data.description.indexOf("Drawing") > -1);
        item = scrollList2.getItemAt(i);
        item.cbx.selected = (item.data.description.indexOf("Drawing") > -1);
    }
}

function selectPaintings()
{
    for (var i = 0; i < ListData.length; i++)
    {
        var item = scrollList.getItemAt(i);
        item.cbx.selected = (item.data.description.indexOf("Painting") > -1);
        item = scrollList2.getItemAt(i);
        item.cbx.selected = (item.data.description.indexOf("Painting") > -1);
     }
}

btnSelectDrawings.onRelease = selectDrawings;
btnSelectPaintings.onRelease = selectPaintings;

back to top


Using Indicators + Text Highlighting

The item clip BgxListIndicatorItem from the Bgx List Item Samples shows just one way how highlighting can be controlled with the Bgx Flexible List. Each item clip contains a Movielclip called bgClip with 4 frames for the states default, selected, rollover and selectedover that will be automatically addressed when rollover and change events occur.

Simply use these frames any way you like (using background graphics, scripting to change text styles and TextField position etc.) to create any highlight effect you like.

The code for this example is very basic:

mcBasicList.columnNames = ["description"];
mcBasicList.itemClip = "BgxListIndicatorItem";
mcBasicList.dataProvider = ListData;

back to top


Custom Appearance 1 (Horizontal Repeat, Image Preview)

The example below uses the item clip BgxListImgAnd3Fields from the Bgx List Item Samples. The clip contains three TextFields and an instance of the Loader component together with some custom code that loads the file defined by the preview property into the Loader instance.

More than a useful item clip itself this may be a good template to start other customizations from.

To use horizontal repeat you have to set the horizontalRepeat property to a number greater than 1. You may also want to change the default values of rowHeight and hRepeatOffset:

mcList.columnNames = ["description","ordercode","price"];
mcList.itemClip = "BgxListImgAnd3Fields";
mcList.rowHeight =134;
mcList.horizontalRepeat = 4;
mcList.hRepeatOffset = 140;
mcList.dataProvider = ListData;

Note: Like other users I experienced problems with using Loader.scaleContent = true with multiple simultaneous loads, especially over the internet where loading times are slower than locally. I have tracked this down to what seems to be an oversight in the mx.core.ExtrenalContent class. For more details and solution see Fixing scaleContent Problems of the Macromedia Loader Component

back to top


Custom Appearance 2 + Catching Events

The example below uses item clip BgxListCustomBtn from the Bgx List Item Samples. As with BgxListImgAnd3Fields this may be a good example to study for your own customizations.

The item in this clip consits basically of a button and a yellow rectangle in the bgClip to mark the selected item. Clicking on an item will show/hide a clip called detailClip and set its properties, including loading the preview file into a Loader instance called mcLoader.

Check out the line if(!detailClip._visible) mcList.selectedIndex = null; that is used to deselect the item if it was the selected one before, turning it this way into a toggle button.

The tooltip is created using the Bgx Tooltip component.

PS: Try also the UP, DOWN, LEFT and RIGHT arrows and the HOME key!

tooltip.delay = 0;

detailClip._visible = false;


mcList.itemClip = "BgxListCustomBtn";
mcList.rowHeight =40;
mcList.horizontalRepeat = 4;
mcList.hRepeatOffset = 40;

var listener = new Object()

listener.itemRollOver = function(eventObj)
{
    tooltip.label = eventObj.itemData.description + " " + newline;
    tooltip.label += eventObj.itemData.ordercode;
    tooltip.showTooltip();
}

listener.itemRollOut = function(eventObj)
{
    tooltip.hideTooltip();
}

listener.itemPress = function(eventObj)
{
    //toggle visibility of detailClip if clicked on the
    //same item twice

    if (detailClip.ordercode == eventObj.itemData.ordercode)
    {
        detailClip._visible = !detailClip._visible;
        //deselect button if detailCLip is not visible
        if(!detailClip._visible) mcList.selectedIndex = null;
    }
    else
    {
        detailClip._visible = true;
        detailClip.description = eventObj.itemData.description;
        detailClip.price = eventObj.itemData.price;
        detailClip.ordercode = eventObj.itemData.ordercode;
        detailClip.mcLoader.contentPath = eventObj.itemData.preview;
        detailClip.mcLoader.load();
    }
}

mcList.addEventListener("itemRollOver",listener);
mcList.addEventListener("itemRollOut",listener);
mcList.addEventListener("itemPress",listener);

mcList.dataProvider = ListData;

Note: Like other users I experienced problems with using Loader.scaleContent = true with multiple simultaneous loads, especially over the internet where loading times are slower than locally. I have tracked this down to what seems to be an oversight in the mx.core.ExtrenalContent class. For more details and solution see Fixing scaleContent Problems of the Macromedia Loader Component

back to top


Triggering External Events (RollOver, RollOut, Setting Selections - Synchronizing Two Lists)

The following uses two instances of the Bgx Flexible List. The one on the left uses horizontal repeat like in the example above, the list on the right corresponds the one in the scrolling example. The list on the right is then syncronized to the one on the left as described below.

First lets have a look at how the list on the left is created:

Instead of binding any of the properties to a visible TextField, the itemClip (NumberBtn) for the list on the left contains a TextField called tbxIndex and then displays a number corresponding to the item index by placing the following line into the itemClip:

tbxIndex.text = itemIndex + 1;

Note: To get a nicer display the ListData was reduced to 9 items for this example.

Now lets have a closer look at the synchronization:

The following code captures the itemRollOver, itemRollOut and itemPress events of the lists and triggers them in the other list for the same itemIndex. The tricky part is that using triggerItemRollOver, triggerItemRollOut or triggerItemPress will also raise an event in the other list which would in turn call the original list, etc.

To avoid entering a recursive loop it is necessary to only execute the actions for the list where the mouse interaction took place.

mcList.itemClip = "NumberBtn";
mcList.rowHeight =29;
mcList.horizontalRepeat = 3;
mcList.hRepeatOffset = 29;

var scrollList = mcScrollPane.content;
scrollList.columnNames = ["description"];
scrollList.iconField = "icon";
scrollList.dataProvider = ListData;


var listener = new Object();

var lastRollOver:MovieClip;

listener.itemRollOver = function(eventObj)
{
	//we use triggerItemRollOver to set the rollover in the other list
	//as this will trigger also an itemRollOver event in the other list
	//we must make sure that the following is only executed from the list
	//on which the mouse event occurred
	
	//check if mouse is over the item
	if (checkHit(eventObj.item))
	{
		//remember on which list the rollover event occurred
		lastRollOver = eventObj.target;
		var targetList = (eventObj.target == scrollList) ? mcList : scrollList
		//trigger events for the other list
		targetList.triggerItemRollOver(eventObj.itemIndex);
		targetList.setScrollPosition(eventObj.itemIndex);
	}
}

listener.itemRollOut = function(eventObj)
{
	//we use triggerItemRollOut to set the rollover in the other list
	//as this will trigger also an itemRollOut event in the other list
	//we must make sure that the following is only executed from the list
	//on which the mouse event occurred
	
	//as we stored the information on which list the rollover
	//occurred, we can use lastRollOver also to check if the 
	//rollout occurred on the same list
	if (lastRollOver == eventObj.target)
	{
		var targetList = (eventObj.target == scrollList) ? mcList : scrollList;
		//trigger events for the other list
		targetList.triggerItemRollOut(eventObj.itemIndex);
		if (targetList == scrollList)
		{
			var selIndex = targetList.selectedIndex;
			var restoreIndex = (isNaN(selIndex)) ? 0 : selIndex;
			targetList.setScrollPosition(restoreIndex);
		}
	}
}

listener.itemPress = function(eventObj)
{
	//we use selectedIndices to set the selection in the other list
	//as this triggers only the change event but not the itemPress event
	//it is not necessary to check where the mouse is;
	//see the documentation for further info 
	var targetList = (eventObj.target == scrollList) ? mcList : scrollList
	//trigger events for the other list
	targetList.selectedIndices = eventObj.target.selectedIndices;
	scrollList.setScrollPosition(targetList.selectedIndex);
}

function checkHit(obj:Object):Boolean
{
	return (obj._xmouse < obj._width && 
			   obj._xmouse > 0 &&
			   obj._ymouse > 0 &&
			   obj._ymouse < obj._height);
}

mcList.addEventListener("itemRollOver",listener);
mcList.addEventListener("itemRollOut",listener);
mcList.addEventListener("itemPress",listener);

scrollList.addEventListener("itemRollOver",listener);
scrollList.addEventListener("itemRollOut",listener);
scrollList.addEventListener("itemPress",listener);

mcList.dataProvider = ListData;

//HANDLE TAB FOCUS

//set size of FlexibleList instances
//which will be the size of the focus rectangle
mcList.setSize(85,85);
//this will hide the focus rectangle of the Flexible List
//embedded in the ScrollPane, the one of the ScrollPane itself
//will be enough to identify focus
scrollList.setSize(0,0);
//pass the focus from the ScrollPane to the List
var scrollPaneListener = new Object();
scrollPaneListener.focusIn = function()
{
	scrollList.setFocus();
}
mcScrollPane.addEventListener("focusIn",scrollPaneListener);				

 

back to top

 

 

 

For further information please contact info@bgxcomponents.com.

 

Resources

View the documentation


Buy now