diff --git a/lib/RT/CustomField.pm b/lib/RT/CustomField.pm index 79c1f1f5a5d..76bf5c4c0a2 100644 --- a/lib/RT/CustomField.pm +++ b/lib/RT/CustomField.pm @@ -646,6 +646,10 @@ sub Values { my $self = shift; my $class = $self->ValuesClass; + + # For back compatibility, autocomplete user/group cfs are not supposed to use Values + $class = 'RT::CustomFieldValues' if $class =~ /^RT::(?:Users|Groups)::/; + if ( $class ne 'RT::CustomFieldValues') { RT::StaticUtil::RequireModule($class) or die "Can't load $class: $@"; } @@ -870,6 +874,7 @@ sub ValidateValuesClass { return 1 if !$class || $class eq 'RT::CustomFieldValues'; return 1 if grep $class eq $_, RT->Config->Get('CustomFieldValuesSources'); + return 1 if $self->Type eq 'Autocomplete' && $class =~ /^RT::(?:Users|Groups)::/; return undef; } diff --git a/share/html/Admin/CustomFields/Modify.html b/share/html/Admin/CustomFields/Modify.html index beee4675a0c..88d6923424f 100644 --- a/share/html/Admin/CustomFields/Modify.html +++ b/share/html/Admin/CustomFields/Modify.html @@ -82,7 +82,7 @@ % } -% if ( $CustomFieldObj->Id and $CustomFieldObj->IsSelectionType and RT->Config->Get('CustomFieldValuesSources') and ( scalar(@{RT->Config->Get('CustomFieldValuesSources')}) > 0 ) ) { +% if ( $CustomFieldObj->Id and $CustomFieldObj->IsSelectionType and ( $CustomFieldObj->Type eq 'Autocomplete' or ( RT->Config->Get('CustomFieldValuesSources') and ( scalar(@{RT->Config->Get('CustomFieldValuesSources')}) > 0 ) ) ) ) { <&| /Elements/LabeledValue, Label => loc("Field values source") &> <& /Admin/Elements/EditCustomFieldValuesSource, CustomField => $CustomFieldObj &> diff --git a/share/html/Admin/Elements/EditCustomFieldValuesSource b/share/html/Admin/Elements/EditCustomFieldValuesSource index b84b77aef12..aff94671c9f 100644 --- a/share/html/Admin/Elements/EditCustomFieldValuesSource +++ b/share/html/Admin/Elements/EditCustomFieldValuesSource @@ -72,6 +72,11 @@ foreach my $class( 'RT::CustomFieldValues', RT->Config->Get('CustomFieldValuesSo push @sources, \%res; } +if ( $CustomField->Type eq 'Autocomplete' ) { + push @sources, { Class => "RT::Users::$_", Description => loc('RT user [_1]', $_) } for qw/id Name EmailAddress/; + push @sources, { Class => "RT::Groups::$_", Description => loc('RT group [_1]', $_) } for qw/id Name/; +} + return unless grep $_->{'Class'} ne 'RT::CustomFieldValues', @sources; diff --git a/share/html/Elements/EditCustomFieldAutocomplete b/share/html/Elements/EditCustomFieldAutocomplete index 40104555ae7..9a393d08203 100644 --- a/share/html/Elements/EditCustomFieldAutocomplete +++ b/share/html/Elements/EditCustomFieldAutocomplete @@ -53,8 +53,14 @@ cols="<% $Cols %>" \ % if ( defined $Rows ) { rows="<% $Rows %>" \ % } -name="<% $name %>" id="<% $name %>" class="CF-<%$CustomField->id%>-Edit form-control"><% $Default || '' %> +name="<% $name %>" id="<% $name %>" class="CF-<%$CustomField->id%>-Edit form-control no-selectize" +% if ( $CustomField->ValuesClass =~ /^RT::(Users|Groups)::(\w+)/ ) { +data-autocomplete="<% $1 %>" data-autocomplete-return="<% $2 %>" data-autocomplete-multiple="1" +% } + +><% $Default || '' %> +% if ( $CustomField->ValuesClass !~ /^RT::(?:Users|Groups)::/ ) { <%INIT> diff --git a/share/static/js/autocomplete.js b/share/static/js/autocomplete.js index c967050ddfe..0fdaad86315 100644 --- a/share/static/js/autocomplete.js +++ b/share/static/js/autocomplete.js @@ -43,7 +43,7 @@ Selectize.define('rt_drag_drop', function(options) { window.RT.Autocomplete.bind = function(from) { - jQuery("input[data-autocomplete]", from).each(function(){ + jQuery(":input[data-autocomplete]", from).each(function(){ var input = jQuery(this); var what = input.attr("data-autocomplete"); var wants = input.attr("data-autocomplete-return"); @@ -51,7 +51,7 @@ window.RT.Autocomplete.bind = function(from) { if (!what || !window.RT.Autocomplete.Classes[what]) return; - if ( (what === 'Users' || what === 'Principals') && input.is('[data-autocomplete-multiple]')) { + if ( (what === 'Users' || what === 'Principals') && input.is('[data-autocomplete-multiple]') && !input.hasClass('no-selectize') ) { var options = input.attr('data-options'); var items = input.attr('data-items'); input.selectize({ @@ -151,7 +151,12 @@ window.RT.Autocomplete.bind = function(from) { if (input.is('[data-autocomplete-multiple]')) { if ( what != 'Tickets' ) { - queryargs.push("delim=,"); + if ( input.is('textarea') ) { + queryargs.push("delim=%0A"); + } + else { + queryargs.push("delim=,"); + } } options.focus = function () { @@ -160,7 +165,7 @@ window.RT.Autocomplete.bind = function(from) { } options.select = function(event, ui) { - var terms = this.value.split(what == 'Tickets' ? /\s+/ : /,\s*/); + var terms = this.value.split(what == 'Tickets' ? /\s+/ : input.is('textarea') ? /\n+/ : /,\s*/); terms.pop(); // remove current input if ( what == 'Tickets' ) { // remove non-integers in case subject search with spaces in (like "foo bar") @@ -175,7 +180,7 @@ window.RT.Autocomplete.bind = function(from) { } terms.push( ui.item.value ); // add selected item terms.push(''); // add trailing delimeter so user can input another value directly - this.value = terms.join(what == 'Tickets' ? ' ' : ", "); + this.value = terms.join(what == 'Tickets' ? ' ' : input.is('textarea') ? "\n" : ','); jQuery(this).change(); return false;