Bug 66910 - Complete keywords and autocomplete

git-svn-id: svn://svn.office.custis.ru/3rdparty/bugzilla.org/trunk@1674 6955db30-a419-402b-8a0d-67ecbb4d7f56
master
akrasilnikov 2013-06-05 10:45:06 +00:00
parent 0b231ede44
commit 1aeb072046
6 changed files with 178 additions and 10 deletions

View File

@ -631,7 +631,7 @@ sub run_create_validators
$params->{version} = $class->_check_version($params->{version}, $product);
$params->{keywords} = $class->_check_keywords($params->{keywords}, $product);
$params->{keywords} = $class->_check_keywords($params->{keywords}, $params->{keywords_description}, $product);
$params->{groups} = $class->_check_groups($product,
$params->{groups});
@ -679,6 +679,9 @@ sub run_create_validators
# These are converted into IDs
delete $params->{product};
delete $params->{component};
# used for keywords only
delete $params->{keywords_description};
Bugzilla::Hook::process('bug_end_of_create_validators',
{ params => $params });
@ -1722,7 +1725,7 @@ sub _check_groups {
}
sub _check_keywords {
my ($invocant, $keyword_string, $product) = @_;
my ($invocant, $keyword_string, $keyword_description_string, $product) = @_;
$keyword_string = trim($keyword_string);
return [] if !$keyword_string;
@ -1730,13 +1733,43 @@ sub _check_keywords {
if (!ref $invocant) {
return [] if !Bugzilla->user->in_group('editbugs', $product->id);
}
# CustIS Bug 66910 - Adding new keyword to DB
my @keyword_descriptions;
foreach my $kd (split(/[@]+/, trim($keyword_description_string))) {
my @this_kd = split(/[=]+/, $kd);
push @keyword_descriptions, { $this_kd[0] => $this_kd[1]};
}
my %keywords;
foreach my $keyword (split(/[\s,]+/, $keyword_string)) {
next unless $keyword;
my $obj = new Bugzilla::Keyword({ name => $keyword });
ThrowUserError("unknown_keyword", { keyword => $keyword }) if !$obj;
$keywords{$obj->id} = $obj;
# CustIS Bug 66910 - Adding new keyword to DB
if (!$obj)
{
my $this_kd = "";
foreach (@keyword_descriptions)
{
if (exists($_->{$keyword}))
{
$this_kd = $_->{$keyword};
}
}
my $obj = Bugzilla::Keyword->create({
name => $keyword,
description => $this_kd
});
$keywords{$obj->id} = $obj;
}
else
{
$keywords{$obj->id} = $obj;
}
#ThrowUserError("unknown_keyword", { keyword => $keyword }) if !$obj;
#$keywords{$obj->id} = $obj;
}
return [values %keywords];
}
@ -2552,14 +2585,14 @@ sub add_comment {
# functions, so I just combined them all into one. This is also easier for
# process_bug to use.
sub modify_keywords {
my ($self, $keywords, $action) = @_;
my ($self, $keywords, $keywords_description, $action) = @_;
$action ||= "makeexact";
if (!grep($action eq $_, qw(add delete makeexact))) {
$action = "makeexact";
}
$keywords = $self->_check_keywords($keywords);
$keywords = $self->_check_keywords($keywords, $keywords_description);
my (@result, $any_changes);
if ($action eq 'makeexact') {

View File

@ -229,6 +229,8 @@ function updateRemainingTime()
function changeform_onsubmit()
{
if (check_new_keywords() == false) return false;
var wtInput = document.changeform.work_time;
if (!wtInput)
return true;
@ -247,6 +249,7 @@ function changeform_onsubmit()
return false;
}
}
wtInput.value = awt;
adjustRemainingTime();
return true;
@ -314,3 +317,64 @@ function att_file_onchange(e)
}
}
}
// CustIS bug 66910 - check new keywords and requery description for its
function check_new_keywords()
{
var non_exist_keywords = [];
var cnt_exist_keywords = 0;
var input_keywords = document.changeform.keywords.value.split(",");
var exist_keywords = [];
for(var i = 0; i < emptyKeywordsOptions.length; i++)
{
exist_keywords[i] = emptyKeywordsOptions[i].name.trim();
}
for(var i = 0; i < input_keywords.length; i++)
{
if (input_keywords[i].trim() != "" && exist_keywords.indexOf(input_keywords[i].trim()) == -1)
{
non_exist_keywords[cnt_exist_keywords] = input_keywords[i].trim();
cnt_exist_keywords++;
}
}
if (non_exist_keywords.length > 0)
{
var keywords_submit = true;
var kd_container = document.getElementById("keywords_description_container");
if (kd_container.children[0] == undefined)
{
var desc_html = "";
for(var i = 0; i < non_exist_keywords.length; i++)
{
desc_html += "<br /><label>Description for new item of keywords - <b>" + non_exist_keywords[i].trim() + "</b></label><br /><input type=\"text\" value=\"\" class=\"text_input\" name=\"kd\" id=\"keyword_description_" + i + "\" style=\"border: solid 1px red;\" /> <br/>";
}
kd_container.innerHTML = desc_html;
keywords_submit = false;
}
else
{
var kd_descriptions_val = "";
var kd_descriptions = kd_container.getElementsByTagName("INPUT");
for (var i = 0; i < kd_descriptions.length; i++)
{
if (kd_descriptions[i].value == "")
{
keywords_submit = false;
}
if (kd_descriptions_val != "")
{
kd_descriptions_val += "@";
}
var this_id = kd_descriptions[i].getAttribute('id').replace("keyword_description_", "");
kd_descriptions_val += non_exist_keywords[this_id].trim() + "=" + kd_descriptions[i].value;
}
kd_container.innerHTML = kd_container.innerHTML + "<input type=\"hidden\" value=\"" + kd_descriptions_val + "\" name=\"keywords_description\" />"
}
return keywords_submit;
}
}

View File

@ -133,6 +133,7 @@ push(@bug_fields, qw(
resolution
dependson
keywords
keywords_description
short_desc
priority
version

View File

@ -334,9 +334,11 @@ elsif (should_set('dependson') || should_set('blocked')) {
my $any_keyword_changes;
if (defined $cgi->param('keywords')) {
foreach my $b (@bug_objects) {
my $return =
$b->modify_keywords(scalar $cgi->param('keywords'),
scalar $cgi->param('keywords_description'),
scalar $cgi->param('keywordaction'));
$any_keyword_changes ||= $return;
}

View File

@ -92,6 +92,8 @@ var noTimeTracking = [% product.notimetracking ? 'true' : 'false' %];
function validateEntryForm(theform)
{
if (check_new_keywords() == false) return false;
if (theform.short_desc.value == '')
{
alert('Please enter a summary sentence for this [% terms.bug %].');
@ -127,6 +129,68 @@ function validateEntryForm(theform)
return true;
}
// CustIS bug 66910 - check new keywords and requery description for its
function check_new_keywords()
{
var non_exist_keywords = [];
var cnt_exist_keywords = 0;
var input_keywords = document.Create.keywords.value.split(",");
var exist_keywords = [];
for(var i = 0; i < emptyKeywordsOptions.length; i++)
{
exist_keywords[i] = emptyKeywordsOptions[i].name.trim();
}
for(var i = 0; i < input_keywords.length; i++)
{
if (input_keywords[i].trim() != "" && exist_keywords.indexOf(input_keywords[i].trim()) == -1)
{
non_exist_keywords[cnt_exist_keywords] = input_keywords[i].trim();
cnt_exist_keywords++;
}
}
if (non_exist_keywords.length > 0)
{
var keywords_submit = true;
var kd_container = document.getElementById("keywords_description_container");
if (kd_container.children[0] == undefined)
{
var desc_html = "";
for(var i = 0; i < non_exist_keywords.length; i++)
{
desc_html += "<br /><label>Description for - <b>" + non_exist_keywords[i].trim() + "</b></label><br /><input type=\"text\" value=\"\" name=\"kd\" id=\"keyword_description_" + i + "\" style=\"border: solid 1px red; width: 296px;\" /> <br/>";
}
kd_container.innerHTML = desc_html;
keywords_submit = false;
}
else
{
var kd_descriptions_val = "";
var kd_descriptions = kd_container.getElementsByTagName("INPUT");
for (var i = 0; i < kd_descriptions.length; i++)
{
if (kd_descriptions[i].value == "")
{
keywords_submit = false;
}
if (kd_descriptions_val != "")
{
kd_descriptions_val += "@";
}
var this_id = kd_descriptions[i].getAttribute('id').replace("keyword_description_", "");
kd_descriptions_val += non_exist_keywords[this_id].trim() + "=" + kd_descriptions[i].value;
kd_descriptions[i].value = kd_descriptions[i].value;
}
kd_container.innerHTML = kd_container.innerHTML + "<input type=\"hidden\" value=\"" + kd_descriptions_val + "\" name=\"keywords_description\" />"
}
return keywords_submit;
}
}
function set_assign_to() {
// Based on the selected component, fill the "Assign To:" field
// with the default component owner, and the "QA Contact:" field
@ -682,14 +746,15 @@ function checkWorktime(inp)
[% END %]
<input id="keywords" name="keywords" size="40" value="[% keywords FILTER html %]">
<script type="text/javascript">
var emptyKeywordsOptions = [% keyword_list ? json(keyword_list) : "null" %];
addListener(window, 'load', function() {
var emptyOptions = [% keyword_list ? json(keyword_list) : "null" %];
new SimpleAutocomplete("keywords",
function(h) { keywordAutocomplete(h, emptyOptions); },
function(h) { keywordAutocomplete(h, emptyKeywordsOptions); },
{ emptyText: 'No keywords found', multipleDelimiter: "," }
);
});
</script>
<div id="keywords_description_container"></div>
</td>
[% IF Param("usebugaliases") %]
<th>Alias:</th>

View File

@ -533,10 +533,10 @@ document.changeform = document.[% cfname %];
<tr>
<td class="field_label">
<script type="text/javascript">
var emptyKeywordsOptions = [% keyword_list ? json(keyword_list) : "null" %];
addListener(window, 'load', function() {
var emptyOptions = [% keyword_list ? json(keyword_list) : "null" %];
new SimpleAutocomplete("keywords",
function(h) { keywordAutocomplete(h, emptyOptions); },
function(h) { keywordAutocomplete(h, emptyKeywordsOptions); },
{ emptyText: 'No keywords found', multipleDelimiter: "," }
);
});
@ -1061,6 +1061,9 @@ document.changeform = document.[% cfname %];
value="[% val FILTER html %]"[% " size=\"$size\"" IF size %]
[% " maxlength=\"$maxlength\"" IF maxlength %]
[% " spellcheck=\"$spellcheck\"" IF spellcheck %]>
[% IF inputname == "keywords" %]
<div id="keywords_description_container"></div>
[% END %]
[% ELSE %]
[% IF size && val.length > size %]
<span title="[% val FILTER html %]">