//Dependent ListBoxes @1-BD91091C
//Copyright 2007 CodeChargeTools.com

function CCT_BindDependentListBox(formType, formName, elementName, valuesHash, masterName, whenMasterIsEmpty, useAjax, disableEmptySlave, multipleLeave, includePageName) {
    var cctListBox = null;
    var formElement = document.forms[formName];
    var htmlElementName = elementName;
    var htmlMasterName = masterName;
    if (formElement == null) return;
    switch (formType) {
        case "EditableGrid":
            var idx = 0;
            var emptyRows = 0;
            while (true) {
                idx++;
                var row = String(idx);
                htmlElementName = "{elementName}_{row}";
                htmlMasterName = "{elementName}_{row}";
                htmlElementName = htmlElementName.replace(/\{formName\}/g, formName);
                htmlElementName = htmlElementName.replace(/\{elementName\}/g, elementName);
                htmlElementName = htmlElementName.replace(/\{row\}/g, row);
                htmlMasterName = htmlMasterName.replace(/\{formName\}/g, formName);
                htmlMasterName = htmlMasterName.replace(/\{elementName\}/g, masterName);
                htmlMasterName = htmlMasterName.replace(/\{row\}/g, row);
                cctListBox = formElement.elements[htmlElementName];
                if (null == cctListBox) {
                    emptyRows++; if (emptyRows < 10) continue; else break;
                }
                cctListBox.cctHash = valuesHash;
                cctListBox.cctSelected = cctListBox.value;
                cctListBox.cctMaster = htmlMasterName;
                cctListBox.cctMasterName = masterName;
                cctListBox.cctElementName = elementName;
                cctListBox.cctForm = formName;
                cctListBox.whenMasterIsEmpty = whenMasterIsEmpty;
                cctListBox.cctDisableEmptySlave = disableEmptySlave;
                cctListBox.cctMultipleLeave = multipleLeave;
                if (useAjax) {
                    CCT_InitAjaxDependentListBox(cctListBox);
                } else {
                    CCT_InitDependentListBox(cctListBox);
                }
            }
            break;
        case "Record":
            var idx = 0;
            cctListBox = formElement.elements[htmlElementName];
            if (cctListBox == null) cctListBox = formElement.elements[htmlElementName + "[]"];
            if (cctListBox == null) return;
            cctListBox.cctHash = valuesHash;
            cctListBox.cctSelected = cctListBox.value;
            cctListBox.cctMaster = htmlMasterName;
            cctListBox.cctMasterName = masterName;
            cctListBox.cctElementName = elementName;
            cctListBox.cctForm = formName;
            cctListBox.whenMasterIsEmpty = whenMasterIsEmpty;
            cctListBox.cctDisableEmptySlave = disableEmptySlave;
            cctListBox.cctMultipleLeave = multipleLeave;
            if (useAjax) {
                CCT_InitAjaxDependentListBox(cctListBox);
            } else {
                CCT_InitDependentListBox(cctListBox);
            }
            break;
    }
}

function CCT_InitDependentListBox(dependentListBox) {
    masterListBox = dependentListBox.form.elements[dependentListBox.cctMaster];
    var oldHandler = (masterListBox.onchange) ? masterListBox.onchange : function () {};
    masterListBox.onchange = function () {
        oldHandler.apply(masterListBox);
        CCT_LoadOptions(dependentListBox);
    };
    dependentListBox.cctBackup = CCT_GetOptionsHash(dependentListBox);
    CCT_LoadOptions(dependentListBox);
}

function CCT_InitAjaxDependentListBox(dependentListBox) {
    dependentListBox.cctMasterControl = dependentListBox.form.elements[dependentListBox.cctMaster];
    var oldHandler = (dependentListBox.cctMasterControl.onchange) ? dependentListBox.cctMasterControl.onchange : function () {};
    var newHandler = function() {
        var request = null;
        if (window.XMLHttpRequest) {
            request = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            request = new ActiveXObject("Microsoft.XMLHTTP");
        }
        CCT_ClearOptions(dependentListBox);
        request.onreadystatechange = function(e) {
            if (request.readyState == 4) {
                try {
                    dependentListBox = CCT_GetDepClone(dependentListBox);
                    var options = eval(request.responseText);
                    for (var i = 0; i < options.length; i++) {
                        dependentListBox.disabled = false;
                        var currentOption  = options[i];
                        var newOption = new Option(currentOption[1], currentOption[0]);
                        dependentListBox.options[dependentListBox.options.length] = newOption;
                        if (currentOption[0] == dependentListBox.cctSelected) {
                            dependentListBox.selectedIndex = dependentListBox.options.length - 1;
                            dependentListBox.cctSelected = "";
                        }
                    }
                    // Focusing on listbox partially fixes Safari rendering problem for updated listbox values
                    if (navigator.vendor && navigator.vendor.indexOf("Apple") != -1) {
                        dependentListBox.focus();
                    }
                    if (dependentListBox.onchange) {
                        dependentListBox.onchange.call();
                    }
                } catch(e) { alert("Wrong server response:\n\n " + request.responseText.substring(0, 400) + "\n..."); }
            }
        }
        request.open("GET", "?dl" + dependentListBox.cctForm + dependentListBox.cctElementName + "=" + escape(dependentListBox.cctMasterControl.value), true);
        request.send(null);
    };
    dependentListBox.cctMasterControl.onchange = function () {
        oldHandler.apply(dependentListBox.cctMasterControl);
        newHandler.apply(dependentListBox.cctMasterControl);
    };
    newHandler();
}
function CCT_GetDepClone(dependentListBox) {
    if (navigator.userAgent.toLowerCase().indexOf("safari") != -1) {
        var newDep = dependentListBox.cloneNode(true);
        dependentListBox.parentNode.insertBefore(newDep, dependentListBox);
        newDep.cctHash = dependentListBox.cctHash;
        newDep.cctBackup = dependentListBox.cctBackup;
        newDep.cctSelected = dependentListBox.cctSelected;
        newDep.cctMaster = dependentListBox.cctMaster;
        newDep.cctMasterName = dependentListBox.cctMasterName;
        newDep.cctMasterControl = dependentListBox.cctMasterControl;
        newDep.cctElementName = dependentListBox.cctElementName;
        newDep.cctForm = dependentListBox.cctForm;
        newDep.whenMasterIsEmpty = dependentListBox.whenMasterIsEmpty;
        newDep.cctDisableEmptySlave = dependentListBox.cctDisableEmptySlave;
        dependentListBox.parentNode.removeChild(dependentListBox);
        return newDep;
    }
    return dependentListBox;
}

function CCT_GetOptionsHash(listBox) {
    var resultingHash = new Array();
    for (var i = 0; i < listBox.options.length; i++) {
        var currentOption = listBox.options.item(i);
        if (currentOption.value != "") {
            resultingHash[currentOption.value] = currentOption.text;
        }
    }
    return resultingHash;
}

function CCT_ClearOptions(listBox) {
    if (listBox.multiple && listBox.cctMultipleLeave) {
        for (var i = 0; i < listBox.options.length; i++) {
            listBox.options[i].selected = false;
        }
        return;
    }
    var emptyText = null;
    if (listBox.options[0].value == "") {
        emptyText = listBox.options[0].text;
    }
    listBox.options.length = 0;
    if (emptyText != null) {
        listBox.options[0] = new Option(emptyText, "");
    }
    if (listBox.cctDisableEmptySlave == true) {
        listBox.disabled = true;
    }
}

function CCT_LoadOptions(listBox) {
    var depsHash = listBox.cctHash;
    var backupHash = listBox.cctBackup;
    var masterValue = listBox.form.elements[listBox.cctMaster].value;
    CCT_ClearOptions(listBox);
    var hasEmpty = (listBox.options.length > 0 && ""==listBox.options[0].value);
    var addedOptions = [];
    var mulSelectedOptions = new Object();
    listBox = CCT_GetDepClone(listBox);
    for (dep in depsHash) {
        var depKey = depsHash[dep][0];
        var masterKey = depsHash[dep][1];
        var addOption = !(""==depKey || addedOptions[depKey]) || (""==depKey && !hasEmpty);
        if ("" == depKey) hasEmpty = true;
        switch (listBox.whenMasterIsEmpty) {
            case 'emptyOnly':
                addOption = addOption && (masterKey == masterValue);
                break;
            case 'all':
                addOption = addOption && ((masterValue != "" && masterKey == masterValue) || !masterValue);
                break;
            case 'none':
            default:
                addOption = addOption && (masterValue != "" && masterKey == masterValue);
                break;
        }
        if (addOption && listBox.multiple && listBox.cctMultipleLeave) {
            mulSelectedOptions[depKey] = true;
        } else if (addOption) {
            listBox.disabled = false;
            addedOptions[backupHash[depKey]] = true;
            var newOption = new Option(backupHash[depKey], depKey);
            listBox.options[listBox.options.length] = newOption;
            if (depKey == listBox.cctSelected) {
                listBox.selectedIndex = listBox.options.length - 1;
                listBox.cctSelected = "";
            }
        }
    }
    if (listBox.multiple && listBox.cctMultipleLeave) {
        for (var i = 0; i < listBox.options.length; i++) {
            var currentOption = listBox.options[i];
            if (mulSelectedOptions[currentOption.value]) {
                currentOption.selected = true;
            }
        }
    }
    if (listBox.onchange) {
        listBox.onchange.call();
    }
}
//End Dependent ListBoxes


