Recipe 11.4 Making Dependent Menus
11.4.1 Problem
You want to make the items
in one menu (list box or combo box)
dependent on the user's selection in another form
element.
11.4.2 Solution
Create a custom makeDependent( ) method
for all combo boxes and list boxes.
11.4.3 Discussion
Making a menu depend on the value of another form element is a common
practice. For example, you might want to present a list of minivans
instead of sports cars if the customer indicates that safety and
seating capacity are his top priorities when choosing a new car.
You can create a dependent menu by following these steps:
Create an array of data
providers (i.e., an array
of arrays) for the dependent menu. Each data provider element should
correspond to an item in the master menu. In other words, the index
of each data provider element should match up with the index of an
item in the master menu. Define the setChangeHandler( ) method of the
master menu so that it automatically calls a function when the user
selects an item from the master menu. In the callback function, use the getSelectedIndex(
) method to determine the selected index of the master
menu. Then set the data provider of the dependent menu to the element
from the data providers array of the same index.
This feature set is much easier to implement if you make a custom
makeDependent( ) method for
FSelectableListClass. This class is the
superclass for both list boxes and combo boxes, so our custom method
is available to both kinds of menus. The makeDependent(
) method should take two parameters:
- multiDataProvider
-
This should be a reference to an array of data providers. Each
element of the array should match up with one of the items in the
master menu.
- master
-
This is a reference to the master menu.
Here is our custom makeDependent( ) method:
FSelectableListClass.prototype.makeDependent = function (multiDataProvider, master) {
// Set the master menu's change handler to the updateView( ) method (see following)
// for the dependent menu.
master.setChangeHandler("updateView", this);
// Set the dependent menu's properties to the values passed in as parameters.
this.multiDataProvider = multiDataProvider;
this.master = master;
};
// updateView( ) is called whenever the user selects an item from the master menu.
FSelectableListClass.prototype.updateView = function ( ) {
// Get the index of the selected menu item from the master menu.
var selectedIndex = this.master.getSelectedIndex( );
// Get the data provider that corresponds to the selected index.
var dp = this.multiDataProvider[selectedIndex];
// Set the data provider for the dependent menu.
this.setDataProvider(dp);
};
Here is an example of the makeDependent( )
method in use:
// In this example, create two combo boxes. Space them 150 pixels apart.
_root.attachMovie("FComboBoxSymbol", "myComboBox1", 1);
_root.attachMovie("FComboBoxSymbol", "myComboBox2", 2, {_x: 150});
// Create the master menu's data provider array and use it to populate the menu.
items1 = ["a", "b", "c"];
myComboBox1.setDataProvider(items1);
// Create the multiDataProvider array. It has three elements, each corresponding to
// an item in the master menu. Each element is a data provider. In this case, they
// are each simple array data providers.
items2 = new Array( );
items2.push(["1 a", "2 a", "3 a"]);
items2.push(["1 b", "2 b", "3 b"]);
items2.push(["1 c", "2 c", "3 c"]);
// Call the makeDependent( ) method from the dependent menu. Pass it the
// multiDataProvider and a reference to the master menu.
myComboBox2.makeDependent(items2, myComboBox1);
It is important to note that the makeDependent(
) method sets the master menu's change
handler, which would conflict with another change handler defined for
the master menu. In the majority of situations this should not be an
issue because it is unlikely that you will need to add any other
actions to the master menu's change handler.
However, should you decide to do this, make sure to include a call to
the master menu's updateView( )
method in the new change handler function. For example:
function newOnChange(masterMenu) {
// You must include a call to the menu's updateView( ) method.
masterMenu.updateView( );
// Additional actions go here.
}
myComboBox1.setChangeHandler("newOnChange");
|