244 lines
7.9 KiB
JavaScript
244 lines
7.9 KiB
JavaScript
/* Functions used to show/hide dependent bug fields and change their select options
|
|
* License: Dual-license GPL 3.0+ or MPL 1.1+
|
|
* Author(s): Vitaliy Filippov <vitalif@mail.ru>
|
|
*/
|
|
|
|
onDomReady(initControlledFields);
|
|
|
|
function initControlledFields()
|
|
{
|
|
// Initialise fields in correct order (starting with top-most controller fields)
|
|
var initialised = {};
|
|
var doInit = function(f)
|
|
{
|
|
if (f && !initialised[f])
|
|
{
|
|
initialised[f] = true;
|
|
doInit(field_metadata[f].visibility_field);
|
|
doInit(field_metadata[f].value_field);
|
|
doInit(field_metadata[f].null_field);
|
|
doInit(field_metadata[f].default_field);
|
|
initControlledField(f);
|
|
}
|
|
};
|
|
for (var i in field_metadata)
|
|
{
|
|
doInit(i);
|
|
}
|
|
if (navigator.appName == 'Microsoft Internet Explorer')
|
|
{
|
|
// :-X reflow page to hide the gap between bugzilla-body and footer in IE8
|
|
document.body.className = document.body.className;
|
|
}
|
|
}
|
|
|
|
function initControlledField(id)
|
|
{
|
|
var f = document.getElementById(id);
|
|
if (!f || f.nodeName != 'INPUT' || f.type != 'hidden')
|
|
{
|
|
handleControlledField(id, !document.forms['Create']);
|
|
}
|
|
if (f)
|
|
{
|
|
addListener(f, 'change', handleControllerField_this);
|
|
}
|
|
}
|
|
|
|
function handleControllerField_this(e, nonfirst)
|
|
{
|
|
var m = field_metadata[this.id];
|
|
if (!m)
|
|
{
|
|
return;
|
|
}
|
|
var f = {};
|
|
for (var i in { 'fields': 1, 'values': 1, 'null': 1, 'defaults': 1 })
|
|
{
|
|
for (var j in m[i])
|
|
{
|
|
f[j] = true;
|
|
}
|
|
}
|
|
for (var i in f)
|
|
{
|
|
handleControlledField(i);
|
|
}
|
|
// Cascade events
|
|
for (var i in f)
|
|
{
|
|
handleControllerField_this.apply(document.getElementById(i), [ null, true ]);
|
|
}
|
|
if (!nonfirst && navigator.appName == 'Microsoft Internet Explorer')
|
|
{
|
|
// :-X reflow page to hide the gap between bugzilla-body and footer in IE8
|
|
document.body.className = document.body.className;
|
|
}
|
|
}
|
|
|
|
function setFieldValue(f, v)
|
|
{
|
|
if (f.nodeName == 'SELECT')
|
|
{
|
|
if (f.multiple)
|
|
{
|
|
f.selectedIndex = -1;
|
|
}
|
|
if (v)
|
|
{
|
|
v = v.split(',');
|
|
for (var i in v)
|
|
{
|
|
i = document.getElementById('v' + v[i] + '_' + f.id);
|
|
if (i)
|
|
{
|
|
i.selected = true;
|
|
}
|
|
}
|
|
}
|
|
else if (!f.multiple)
|
|
{
|
|
f.selectedIndex = 0;
|
|
}
|
|
}
|
|
else if (f.type != 'hidden')
|
|
{
|
|
f.value = v;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
function handleControlledField(controlled_id, is_initial_editform)
|
|
{
|
|
var m = field_metadata[controlled_id];
|
|
if (!m)
|
|
{
|
|
return;
|
|
}
|
|
var controlled = document.getElementById(controlled_id);
|
|
var vis;
|
|
// Show/hide the field
|
|
if (m.visibility_field && document.getElementById(m.visibility_field))
|
|
{
|
|
vis = checkValueVisibility(getSelectedIds(m.visibility_field), field_metadata[m.visibility_field]['fields'][controlled_id]);
|
|
for (var i in { row: 1, container: 1, label: 1 })
|
|
{
|
|
var field_container = document.getElementById('field_' + i + '_' + controlled_id);
|
|
(vis ? removeClass : addClass)(field_container, 'bz_hidden_field');
|
|
}
|
|
}
|
|
if (!controlled)
|
|
{
|
|
// Maybe the field is not editable.
|
|
return;
|
|
}
|
|
var df, diff;
|
|
if (m.default_value || (df = m.default_field && document.getElementById(m.default_field)))
|
|
{
|
|
// Check if the value is different from previous default or from empty value
|
|
// We must check it before re-filling field options because some values may disappear
|
|
if (controlled.nodeName == 'SELECT')
|
|
{
|
|
var copt = getSelectedIds(controlled);
|
|
delete copt[0]; // skip empty value
|
|
if (copt.UNKNOWN)
|
|
{
|
|
// We are on the bug entry form and some default value is selected,
|
|
// but its ID is still unknown (because entry form does not prefill select options)
|
|
diff = true;
|
|
}
|
|
if (controlled._oldDefault)
|
|
{
|
|
for (var i in controlled._oldDefault)
|
|
{
|
|
if (copt[controlled._oldDefault[i]])
|
|
delete copt[controlled._oldDefault[i]];
|
|
else
|
|
{
|
|
diff = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for (var i in copt)
|
|
{
|
|
diff = true;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
diff = controlled.value != (controlled._oldDefault || '');
|
|
}
|
|
if (is_initial_editform)
|
|
{
|
|
// Skip re-filling of fields on bug edit page load, because
|
|
// the bug may include incorrect values that must not be hidden initially.
|
|
// Also remember, but do not select the default value in this case.
|
|
}
|
|
else if (controlled.nodeName == 'SELECT')
|
|
{
|
|
// Change select options
|
|
if (m.value_field && document.getElementById(m.value_field))
|
|
{
|
|
// It is more correct to match selected values on name, because a
|
|
// target_milestone/version/component with the same name may exist for a different product
|
|
var copt = getSelectedValues(controlled);
|
|
bz_clearOptions(controlled);
|
|
var nullable = m.nullable && !controlled.multiple;
|
|
if (m.null_field && nullable && document.getElementById(m.null_field))
|
|
{
|
|
nullable = checkValueVisibility(getSelectedIds(m.null_field), field_metadata[m.null_field]['null'][controlled_id]);
|
|
}
|
|
nullable = nullable || controlled_id == 'component' && document.forms['Create'];
|
|
if (nullable)
|
|
{
|
|
bz_createOptionInSelect(controlled, '---', '');
|
|
}
|
|
var opt = getSelectedIds(m.value_field), controlled_value;
|
|
var vh = field_metadata[m.value_field]['values'][controlled_id];
|
|
for (var i in m.legal)
|
|
{
|
|
controlled_value = m.legal[i];
|
|
vis = checkValueVisibility(opt, vh && vh[controlled_value[0]]);
|
|
if (vis)
|
|
{
|
|
var item = bz_createOptionInSelect(controlled, controlled_value[1], controlled_value[1]);
|
|
item.id = 'v'+controlled_value[0]+'_'+controlled_id;
|
|
if (copt[controlled_value[1]])
|
|
{
|
|
item.selected = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (m.nullable && !controlled.multiple && m.null_field && document.getElementById(m.null_field))
|
|
{
|
|
// Just enable/disable empty value
|
|
var nullable = checkValueVisibility(getSelectedIds(m.null_field), field_metadata[m.null_field]['null'][controlled_id]);
|
|
var has_null = controlled.options[0].value == '';
|
|
if (nullable && !has_null)
|
|
{
|
|
controlled.insertBefore(new Option('---', ''), controlled.options[0]);
|
|
}
|
|
else if (!nullable && has_null)
|
|
{
|
|
controlled.removeChild(controlled.options[0]);
|
|
}
|
|
}
|
|
}
|
|
if (m.default_value || df)
|
|
{
|
|
// Remember default value for the new controller
|
|
var v = m.default_value;
|
|
if (df && field_metadata[m.default_field]['defaults'][controlled_id])
|
|
for (var i in getSelectedIds(m.default_field))
|
|
v = field_metadata[m.default_field]['defaults'][controlled_id][i];
|
|
controlled._oldDefault = v;
|
|
if (!diff && !is_initial_editform)
|
|
{
|
|
// If the field was empty or equal to the previous default, set it to the new default
|
|
setFieldValue(controlled, v);
|
|
}
|
|
}
|
|
}
|