A Dynamic Select Component for Javascript
by Steve Johnson

Listing One
// Copyright 1999, Stephen C. Johnson
function ds_onChange()
{
    var ga;
    var flag;

    // Cycle through action lists for the select
    this.actionManager.executeActions(this.currentList, 
        this.options[this.selectedIndex].text);
    // loop through all groups
    for(var g in dsm.groups)
    {
        ga = dsm.groups[g].split(",");
        flag = false                
        for(var i=0; i < ga.length; i++)
        {
            if(ga[i] == this.alias) 
                flag = true;
            else if(flag)
            {
                var s = dsm.dynamicSelects[ga[i]];
                s.actionManager.executeActions(s.currentList, 
                    s.options[s.selectedIndex].text);
            }
        }
    }
}
function ds_changeList(_listName, _itemName)
{                               
    var o = olm.optionLists[_listName];
    var p = this.options;
    
    p.length = 0;
    for(var i=0; i < o.optionArray.length; i++)
    {
        p[p.length] = new Option(o.optionArray[i].text, 
            o.optionArray[i].value);
    }
    if (_itemName == null)
        o.defaultItem
    else
    {
        for(var j=0; j < p.length; j++)
            if(p[j].text == _itemName) break;
    }
    this.currentList = _listName;
    this.selectedIndex = j;
}
function dynamicSelect(_htmlSelect)
{                           
    _htmlSelect.alias   = _htmlSelect.form.name +"."+ _htmlSelect.name;
    _htmlSelect.actionManager   = new ActionManager();
    _htmlSelect.currentList     = null;

    // if size is > 1, use the click method instead
    // of the change method
    if(_htmlSelect.size > 1)
        _htmlSelect.onclick = ds_onChange;
    else
        _htmlSelect.onchange = ds_onChange;
    _htmlSelect.changeList  = ds_changeList;
}
// Definition of the OptionList Object
function OptionList(_optionArray, _alias, _defaultItem)
{
    this.optionArray = _optionArray;
    this.alias       = _alias;
    this.defaultItem = 
   (_defaultItem == null)? (this.optionArray[0].text): _defaultItem;
}
// Definition of the OLManager
function olm_addOptionList(_optionList)
{
    this.optionLists[_optionList.alias] = _optionList;
}
function olm_getOptionList(_optionListName)
{
    return this.optionLists[_optionListName];
}
function OLManager()
{
    this.optionLists = new Array();
    this.addOptionList = olm_addOptionList;
    this.getOptionList = olm_getOptionList;
}
// Definition of the DSManager 
function dsm_addDynamicSelect(_dynamicSelect)
{   
    this.dynamicSelects[_dynamicSelect.alias] = _dynamicSelect;
}
function dsm_addGroup(_groupID, _dsString)
{
    this.groups[_groupID] = _dsString; 
}
function dsm_getDynamicSelect(_dynamicSelectName)
{
    return this.dynamicSelects[_dynamicSelectName]; 
}
function DSManager()
{
    this.dynamicSelects = new Array();
    this.groups         = new Array();
    this.addDynamicSelect   = dsm_addDynamicSelect;
    this.getDynamicSelect   = dsm_getDynamicSelect;
    this.addGroup           = dsm_addGroup;
}
// Definition of the ActionManager
function am_addAction(_list, _item, _action)
{
    var r = this.getActionsFor(_list, _item);
    this.actions[_list +"."+ _item +"."+ r.length] = _action;
}
function am_executeActions(_list, _item)
{
    var a = this.getActionsFor(_list, _item);
    for(var i=0; i <  a.length; i++)
    {
        var b = a[i].split(",");
        dsm.dynamicSelects[b[0]].changeList(b[1], b[2]);
    }
}
function am_getActionsFor(_list, _item)
{        
    var r = new Array();
    var startIndex = _list +"."+ _item;

    for(var i in this.actions)
    {
        if( (i.substring(0, startIndex.length) == startIndex) ||
             (i.substring(0, (_list.length+2)) == _list+".*"))
        {
            r[r.length] = this.actions[i];
        }
    }
    return r;
}
function ActionManager()
{
    this.actions = new Array();
    this.addAction      = am_addAction;
    this.executeActions = am_executeActions;
    this.getActionsFor  = am_getActionsFor;
}
// Initialize the objects
function dSelectInit()
{
    dsm = new DSManager();
    olm = new OLManager();

    var n,v,d,l,a;
    var e = document.dynamicSelectConfig.elements;
    
    for(var i = 0; i < e.length; i++)
    {
        var n = e[i].name.split(":");
        var v = e[i].value.split(",");
        var g = null;
        if(n[0] == "D")
        {               
            for(var j=0; j < v.length; j++)
            {                       
                d = v[j].split("|");
                if(dsm.dynamicSelects[d[0]] == null)
                {
                    var s = eval("document."+d[0]); 
                    if (s == null) {
                        return;
                    }
                    dynamicSelect(s);
                    dsm.addDynamicSelect(s);
                }
                dsm.dynamicSelects[d[0]].currentList = d[1];

                g = (g == null)? d[0]: (g+','+d[0]);
            }
            dsm.addGroup(n[1], g);
        }
        else if(n[0] == "L")
        {
            var o = new Array();
            var def = null;
            var x;

            for(var j=0; j < v.length; j++)
            {
                x = v[j].split("|");
                x[1] = (x[1] == null)? x[0]: x[1];

                if(x[1].substring(x[1].length-1, x[1].length) == "*")
                {
                    def = x[1] = x[1].substring(0, x[1].length-1);
                }
                o[j] = new Option(x[1], x[0]);
            }
            olm.addOptionList(new OptionList(o, n[1], def));
        }
        else if(n[0] == "A")
        {
            if(dsm.dynamicSelects[n[1]] != null)
            dsm.dynamicSelects[n[1]].actionManager.addAction(n[2],
                    n[3], e[i].value);
        }
    }
    // now initialize the lists
    for(var k in dsm.dynamicSelects)
    {
        var x = dsm.dynamicSelects[k];
        x.changeList(x.currentList, 
            olm.optionLists[x.currentList].defaultItem);    
    }
}


4


