Make "nullable" property dependent on visibility field value
parent
6167bfd72f
commit
9d71d573e4
16
Bugzilla.pm
16
Bugzilla.pm
|
@ -933,15 +933,16 @@ sub fieldvaluecontrol
|
|||
if (!$cache->{fieldvaluecontrol})
|
||||
{
|
||||
$cache->{fieldvaluecontrol} = $class->dbh->selectall_arrayref(
|
||||
'SELECT c.*, (CASE WHEN c.value_id=0 THEN f.visibility_field_id ELSE f.value_field_id END) visibility_field_id'.
|
||||
'SELECT c.*, (CASE WHEN c.value_id <= 0 THEN f.visibility_field_id ELSE f.value_field_id END) visibility_field_id'.
|
||||
' FROM fieldvaluecontrol c, fielddefs f WHERE f.id=c.field_id'.
|
||||
' ORDER BY c.field_id, c.value_id, (CASE WHEN c.value_id=0 THEN f.visibility_field_id ELSE f.value_field_id END), c.visibility_value_id', {Slice=>{}}
|
||||
);
|
||||
my $has = {};
|
||||
for (@{$cache->{fieldvaluecontrol}})
|
||||
{
|
||||
if ($_->{value_id})
|
||||
if ($_->{value_id} > 0)
|
||||
{
|
||||
# Show value_id if value_field==visibility_value_id
|
||||
$has->{$_->{visibility_field_id}}
|
||||
->{values}
|
||||
->{$_->{field_id}}
|
||||
|
@ -949,13 +950,22 @@ sub fieldvaluecontrol
|
|||
->{$_->{visibility_value_id}}
|
||||
->{is_default} = $_->{is_default};
|
||||
}
|
||||
else
|
||||
elsif (!$_->{value_id})
|
||||
{
|
||||
# Show field if visibility_field==visibility_value_id
|
||||
$has->{$_->{visibility_field_id}}
|
||||
->{fields}
|
||||
->{$_->{field_id}}
|
||||
->{$_->{visibility_value_id}} = 1;
|
||||
}
|
||||
elsif ($_->{value_id} == -1)
|
||||
{
|
||||
# Allow NULL if visibility_field==visibility_value_id
|
||||
$has->{$_->{visibility_field_id}}
|
||||
->{null}
|
||||
->{$_->{field_id}}
|
||||
->{$_->{visibility_value_id}} = 1;
|
||||
}
|
||||
}
|
||||
$cache->{fieldvaluecontrol_hash} = $has;
|
||||
}
|
||||
|
|
|
@ -748,7 +748,7 @@ sub check_dependent_fields
|
|||
if (!defined $value_objs)
|
||||
{
|
||||
# FIXME Implement default field values?
|
||||
next if $field_obj->nullable;
|
||||
next if $field_obj->check_is_nullable($self);
|
||||
ThrowUserError('object_not_specified', { class => $field_obj->value_type });
|
||||
}
|
||||
$value_objs = [ $value_objs ] if ref $value_objs ne 'ARRAY';
|
||||
|
@ -766,7 +766,7 @@ sub check_dependent_fields
|
|||
}
|
||||
}
|
||||
# Check other custom fields for empty values
|
||||
elsif (!$field_obj->nullable && $fn ne 'classification' &&
|
||||
elsif (!$field_obj->check_is_nullable($self) && $fn ne 'classification' &&
|
||||
(!$self->{$fn} || $field_obj->type == FIELD_TYPE_MULTI_SELECT && !@{$self->{$fn}}))
|
||||
{
|
||||
ThrowUserError('field_not_nullable', { field => $field_obj });
|
||||
|
|
|
@ -226,7 +226,6 @@ use constant FIELD_TABLE_SCHEMA => {
|
|||
],
|
||||
};
|
||||
|
||||
# FIXME make schema compatible with upstream 4.4
|
||||
use constant ABSTRACT_SCHEMA => {
|
||||
|
||||
# BUG-RELATED TABLES
|
||||
|
@ -580,6 +579,9 @@ use constant ABSTRACT_SCHEMA => {
|
|||
},
|
||||
|
||||
# All value/value and value/field dependencies are stored here
|
||||
# value_id > 0: value with this id is visible if value field has value visibility_value_id
|
||||
# value_id == 0: field is visible if visibility field has value visibility_value_id
|
||||
# value_id == -1: NULL is allowed if visibility field has value visibility_value_id
|
||||
# (originally CustIS Bugs 53617, 91153)
|
||||
fieldvaluecontrol => {
|
||||
FIELDS => [
|
||||
|
|
|
@ -636,21 +636,9 @@ sub visibility_values
|
|||
{
|
||||
my $self = shift;
|
||||
return undef if !$self->visibility_field_id;
|
||||
my $f;
|
||||
if ($self->visibility_field && !($f = $self->{visibility_values}))
|
||||
{
|
||||
$f = [ keys %{Bugzilla->fieldvaluecontrol_hash
|
||||
->{$self->visibility_field_id}
|
||||
->{fields}
|
||||
->{$self->id} || {} } ];
|
||||
if (@$f)
|
||||
{
|
||||
my $type = Bugzilla::Field::Choice->type($self->visibility_field);
|
||||
$f = $type->match({ id => $f });
|
||||
}
|
||||
$self->{visibility_values} = $f;
|
||||
}
|
||||
return $f;
|
||||
my $h = Bugzilla->fieldvaluecontrol_hash
|
||||
->{$self->visibility_field_id}->{fields}->{$self->id};
|
||||
return $h && %$h ? $h : undef;
|
||||
}
|
||||
|
||||
sub has_visibility_value
|
||||
|
@ -666,15 +654,13 @@ sub has_visibility_value
|
|||
return !$hash || !%$hash || $hash->{$value};
|
||||
}
|
||||
|
||||
sub has_all_visibility_values
|
||||
sub null_visibility_values
|
||||
{
|
||||
my $self = shift;
|
||||
return 1 if !$self->visibility_field_id;
|
||||
my $hash = Bugzilla->fieldvaluecontrol_hash
|
||||
->{$self->visibility_field_id}
|
||||
->{fields}
|
||||
->{$self->id};
|
||||
return !$hash || !%$hash;
|
||||
return undef if !$self->visibility_field_id;
|
||||
my $h = Bugzilla->fieldvaluecontrol_hash
|
||||
->{$self->value_field_id}->{null}->{$self->id};
|
||||
return $h && %$h ? $h : undef;
|
||||
}
|
||||
|
||||
# Check visibility of field for a bug or for a hashref with default value names
|
||||
|
@ -687,6 +673,15 @@ sub check_visibility
|
|||
return $value ? $self->has_visibility_value($value) : 1;
|
||||
}
|
||||
|
||||
sub check_is_nullable
|
||||
{
|
||||
my $self = shift;
|
||||
$self->nullable || return 0;
|
||||
my $vf = $self->visibility_field || return 1;
|
||||
my $value = bug_or_hash_value($bug, $vf);
|
||||
return $value ? $self->null_visibility_values->{$value->id} : 1;
|
||||
}
|
||||
|
||||
=pod
|
||||
|
||||
=over
|
||||
|
@ -804,7 +799,6 @@ sub set_visibility_field
|
|||
my ($self, $value) = @_;
|
||||
$self->set('visibility_field_id', $value);
|
||||
delete $self->{visibility_field};
|
||||
delete $self->{visibility_values};
|
||||
}
|
||||
|
||||
sub set_visibility_values
|
||||
|
@ -812,7 +806,14 @@ sub set_visibility_values
|
|||
my $self = shift;
|
||||
my ($value_ids) = @_;
|
||||
update_visibility_values($self, 0, $value_ids);
|
||||
delete $self->{visibility_values};
|
||||
return $value_ids && @$value_ids;
|
||||
}
|
||||
|
||||
sub set_null_visibility_values
|
||||
{
|
||||
my $self = shift;
|
||||
my ($value_ids) = @_;
|
||||
update_visibility_values($self, -1, $value_ids);
|
||||
return $value_ids && @$value_ids;
|
||||
}
|
||||
|
||||
|
@ -1244,7 +1245,7 @@ sub update_visibility_values
|
|||
{
|
||||
my ($controlled_field, $controlled_value_id, $visibility_value_ids) = @_;
|
||||
$visibility_value_ids ||= [];
|
||||
my $vis_field = $controlled_value_id
|
||||
my $vis_field = $controlled_value_id != 0
|
||||
? $controlled_field->value_field
|
||||
: $controlled_field->visibility_field;
|
||||
if (!$vis_field)
|
||||
|
|
|
@ -128,15 +128,15 @@ sub fields {
|
|||
}
|
||||
|
||||
my %field_data = (
|
||||
id => $self->type('int', $field->id),
|
||||
type => $self->type('int', $field->type),
|
||||
is_custom => $self->type('boolean', $field->custom),
|
||||
name => $self->type('string', $field->name),
|
||||
display_name => $self->type('string', $field->description),
|
||||
is_mandatory => $self->type('boolean', $field->is_mandatory),
|
||||
is_on_bug_entry => $self->type('boolean', 1),
|
||||
visibility_field => $self->type('string', $visibility_field),
|
||||
visibility_values => [ map { $self->type('string', $_->name) } @{ $vis_values || [] } ],
|
||||
id => $self->type('int', $field->id),
|
||||
type => $self->type('int', $field->type),
|
||||
is_custom => $self->type('boolean', $field->custom),
|
||||
name => $self->type('string', $field->name),
|
||||
display_name => $self->type('string', $field->description),
|
||||
is_mandatory => $self->type('boolean', $field->is_mandatory),
|
||||
is_on_bug_entry => $self->type('boolean', 1),
|
||||
visibility_field => $self->type('string', $visibility_field),
|
||||
visibility_values => [ map { $self->type('string', $_->name) } $field->visibility_field->value_type->new_from_list($vis_values) ],
|
||||
);
|
||||
if ($has_values) {
|
||||
$field_data{value_field} = $self->type('string', $value_field);
|
||||
|
|
|
@ -75,6 +75,7 @@ elsif ($action eq 'new')
|
|||
add_to_deps => scalar $cgi->param('add_to_deps'),
|
||||
});
|
||||
$field->set_visibility_values([ $cgi->param('visibility_value_id') ]);
|
||||
$field->set_null_visibility_values([ $cgi->param('null_visibility_values') ]);
|
||||
|
||||
delete_token($token);
|
||||
|
||||
|
@ -115,19 +116,20 @@ elsif ($action eq 'update')
|
|||
{
|
||||
# TODO enter_bug could be edited for non-custom fields, too.
|
||||
# At the moment, though, it has no effect for non-custom fields.
|
||||
$field->set_enter_bug($cgi->param('enter_bug'));
|
||||
$field->set_clone_bug($cgi->param('clone_bug'));
|
||||
$field->set_value_field($cgi->param('value_field_id'));
|
||||
$field->set_add_to_deps($cgi->param('add_to_deps'));
|
||||
my $vf = $cgi->param('visibility_field_id');
|
||||
if ($field->visibility_field_id != $vf)
|
||||
if ($vf != $field->visibility_field_id)
|
||||
{
|
||||
$field->set_visibility_field($vf);
|
||||
$field->set_visibility_values([]);
|
||||
$field->set_null_visibility_values([]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$field->set_visibility_values([ $cgi->param('visibility_value_id') ]);
|
||||
$field->set_null_visibility_values([ $cgi->param('null_visibility_values') ]) if $field->is_select && $field->nullable;
|
||||
}
|
||||
}
|
||||
$field->update();
|
||||
|
|
|
@ -68,9 +68,7 @@ if ($action eq 'update' && $token)
|
|||
for my $cfield (@{$field->controls_visibility_of})
|
||||
{
|
||||
# check if it is 'visible for all'
|
||||
next if $cfield->has_all_visibility_values;
|
||||
my $visibility_values = Bugzilla->fieldvaluecontrol_hash
|
||||
->{$field->id}->{fields}->{$cfield->id};
|
||||
my $visibility_values = $cfield->visibility_values || next;
|
||||
# check if changed
|
||||
next unless ($ARGS->{'visible_'.$cfield->id} xor $visibility_values->{$value->id});
|
||||
if ($ARGS->{'visible_'.$cfield->id})
|
||||
|
|
|
@ -40,4 +40,12 @@ function onChangeType()
|
|||
u = type_field.value == constants.FIELD_TYPE_EXTURL;
|
||||
document.getElementById('url_row').style.display
|
||||
= u ? '' : 'none';
|
||||
onChangeNullable();
|
||||
}
|
||||
|
||||
function onChangeNullable()
|
||||
{
|
||||
var u = document.getElementById('nullable');
|
||||
var n = document.getElementById('allow_null_in_row');
|
||||
n.style.display = u.checked ? '' : 'none';
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ var constants = {
|
|||
[% IF !field.id || field.type && field.type != constants.FIELD_TYPE_BUG_ID_REV %]
|
||||
<th align="left"><label for="nullable">Allow empty value:</label></th>
|
||||
<td>
|
||||
<input type="checkbox" id="nullable" name="nullable"
|
||||
<input type="checkbox" id="nullable" name="nullable" onclick="onChangeNullable()"
|
||||
value="1" [%- " checked" IF field.nullable %] />
|
||||
</td>
|
||||
[% END %]
|
||||
|
@ -219,16 +219,38 @@ var constants = {
|
|||
</tr>
|
||||
[% END %]
|
||||
[% IF field.visibility_field %]
|
||||
<tr valign="top" id="visibility_value_row">
|
||||
<th colspan="2" align="left"><label for="visibility_value_id">
|
||||
Show the field only if <span id="visibility_value_name_span">[% field.visibility_field.description | html %]</span> is set to:
|
||||
</label></th>
|
||||
<tr valign="top">
|
||||
<th colspan="2" align="left">
|
||||
<label for="visibility_value_id">Show the field only if [% field.visibility_field.description | html %] is set to:</label><br />
|
||||
<span style="font-weight: normal">(<a href="javascript:void(0)"
|
||||
onclick="document.getElementById('visibility_value_id').selectedIndex=-1">clear options</a>
|
||||
to make this field always appear)</span>
|
||||
</th>
|
||||
<td colspan="2">
|
||||
[% SET all = field.has_all_visibility_values %]
|
||||
[% SET all = field.visibility_values %]
|
||||
<select style="width: 400px" id="visibility_value_id"
|
||||
name="visibility_value_id" size="7" multiple="multiple">
|
||||
[% FOREACH value = field.visibility_field.legal_values %]
|
||||
<option value="[% value.id | html %]"[% ' selected="selected"' IF !all && field.has_visibility_value(value.id) %]>
|
||||
<option value="[% value.id | html %]"[% ' selected="selected"' IF all && all.${value.id} %]>
|
||||
[% value.name | html %]
|
||||
</option>
|
||||
[% END %]
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top" id="allow_null_in_row">
|
||||
<th colspan="2" align="left">
|
||||
<label for="null_visibility_values">Allow empty value only if [% field.visibility_field.description | html %] is set to:</label><br />
|
||||
<span style="font-weight: normal">(<a href="javascript:void(0)"
|
||||
onclick="document.getElementById('null_visibility_values').selectedIndex=-1">clear options</a>
|
||||
to always allow empty value)</span>
|
||||
</th>
|
||||
<td colspan="2">
|
||||
[% SET all = field.null_visibility_values %]
|
||||
<select style="width: 400px" id="null_visibility_values"
|
||||
name="null_visibility_values" size="7" multiple="multiple">
|
||||
[% FOREACH value = field.visibility_field.legal_values %]
|
||||
<option value="[% value.id | html %]"[% ' selected="selected"' IF field.nullable && all && all.${value.id} %]>
|
||||
[% value.name | html %]
|
||||
</option>
|
||||
[% END %]
|
||||
|
@ -255,7 +277,7 @@ var constants = {
|
|||
</p>
|
||||
|
||||
<script>
|
||||
onChangeEnterBug();
|
||||
onChangeNullable();
|
||||
[% IF !field.id %]
|
||||
onChangeType();
|
||||
[% END %]
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
<td>[% cfield.description | html %]</td>
|
||||
<td align="center">
|
||||
<input type="checkbox" name="visible_[% cfield.id %]" value="1"
|
||||
[% "checked=\"checked\"" IF cfield.has_visibility_value(value) %]
|
||||
[% "disabled=\"disabled\"" IF cfield.has_all_visibility_values %] />
|
||||
[% "checked=\"checked\"" IF !cfield.visibility_values || cfield.visibility_values.${value.id} %]
|
||||
[% "disabled=\"disabled\"" IF !cfield.visibility_values %] />
|
||||
</td>
|
||||
<td>
|
||||
[% IF cfield.has_all_visibility_values %]
|
||||
[% IF !cfield.visibility_values %]
|
||||
Поле видимо для всех значений поля <strong>[% field.description | html %]</strong><br/>
|
||||
<a href="editfields.cgi?action=edit&name=[% cfield.name | url_quote %]">Редактировать</a>
|
||||
[% END %]
|
||||
|
|
Loading…
Reference in New Issue