This repository has been archived on 2024-11-28. You can view files and clone it, but cannot push or open issues or pull requests.
Incam_SGD/resources/js/conditional_selection.js

173 lines
4.5 KiB
JavaScript
Raw Normal View History

// 'lookups' and 'connections' are produced by the master conditional widget
var NOSELECTION = 'No selection.';
function ConditionalSelection() {
}
function in_array(a, val) {
if(!a.length) {
return;
}
for(var i=0;i<a.length;i++) {
if(a[i] == val) {
return true;
}
}
return false;
}
function getId(elm) {
if(elm.id.search('field_') != -1) {
return elm.id.substring('field_'.length);
} else if(elm.id.search('lookup_') != -1) {
return elm.id.substring('lookup_'.length);
}
return false;
}
ConditionalSelection.prototype = {
'initialize' : function(masterId) {
// make clones of the original nodes to keep the options in
var fieldLookups = {};
var current = {};
var lookups = eval('lookups_' + masterId);
var connections = eval('connections_' + masterId);
// initialize - build various tables
forEach(getElementsByTagAndClassName(null, 'is_conditional_' + masterId),
function(elm) {
var fieldId = getId(elm);
for(var i=0; i<elm.options.length; i++) {
var oElm = elm.options[i];
var lookupId = oElm.id.substring('lookup_'.length);
fieldLookups[lookupId] = {'parent':fieldId, 'value':oElm.innerHTML};
if(oElm.selected && oElm.value) {
current[fieldId] = oElm.value;
}
}
});
// the following function are defined inline, as they depend on the
// 'lookups' and 'connections' being specified above
function clearConnected(fieldId) {
if(!fieldId in connections || !connections[fieldId].length) {
return;
}
for(var i=0; i<connections[fieldId].length; i++) {
var field = $('field_'+connections[fieldId][i]);
replaceChildNodes(field, OPTION(null, NOSELECTION));
field.disabled = true;
clearConnected(connections[fieldId][i]);
}
}
function clearInvalid(fieldId) {
if(!fieldId in connections || !connections[fieldId].length) {
return;
}
var parentField = $('field_'+fieldId);
var selectedId = getId(parentField.options[parentField.selectedIndex]);
var options = lookups[selectedId];
if(parentField.options[parentField.selectedIndex].innerHTML == NOSELECTION) {
clearConnected(fieldId);
} else {
for(var i=0; i<connections[fieldId].length; i++) {
var field = $('field_'+connections[fieldId][i]);
var newOptions = [];
var selected = null;
for(var j=0; j<field.options.length; j++) {
var opt = field.options[j];
if(!(opt.innerHTML != NOSELECTION && !in_array(options, getId(opt)))) {
newOptions.push(opt);
}
if(j == field.selectedIndex && opt.id && in_array(options, getId(opt))) {
selected = opt.id;
}
}
field.selectedIndex = 0;
replaceChildNodes(field, null);
for(var j=0; j<newOptions.length; j++) {
var opt = newOptions[j];
appendChildNodes(field, opt);
if(selected != null) {
if(opt.id && opt.id == selected) { // || j == 0 && field.selectedIndex == 0) {
field.selectedIndex = j;
}
}
}
if(selected == null) {
field.selectedIndex = 0;
field.options[0].selected = 'selected';
}
clearInvalid(connections[fieldId][i]);
}
}
}
// instead of clearing here, we remove the non-applicable options
// this should handle the case with existing selections
clearInvalid(masterId);
function populateForSelection(selectedId) {
if(selectedId in lookups) {
for(var i=0; i<lookups[selectedId].length; i++) {
var lookupId = lookups[selectedId][i];
var lookupInfo = fieldLookups[lookupId];
var parent = $('field_' + lookupInfo['parent']);
appendChildNodes(parent,
OPTION({'value':lookupInfo['value'], 'id':'lookup_' + lookupId},
lookupInfo['value']));
parent.disabled = false;
}
}
}
forEach(getElementsByTagAndClassName(null, 'is_conditional_' + masterId), function(elm) {
// check if this field connects to anything else
var fieldId = elm.id.substring('field_'.length);
if(fieldId in connections && connections[fieldId].length) {
var controller = true;
}
if(controller) {
connect(elm, 'onchange',
function() {
var selectedId = elm.options[elm.selectedIndex].id.substring('lookup_'.length);
var touched = [];
clearConnected(fieldId);
populateForSelection(selectedId);
});
}
});
}
}
addLoadEvent(function() {
var masters = getElementsByTagAndClassName('select', 'is_master');
for(var i=0; i<masters.length; i++) {
var elm = masters[i];
var masterId = getId(elm);
var d = new ConditionalSelection();
d.initialize(masterId);
}
});