summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReed Loden <reed@reedloden.com>2010-07-05 09:42:01 +0200
committerReed Loden <reed@reedloden.com>2010-07-05 09:42:01 +0200
commitbf3e63a75b8fbc9d613ec3fd6289a178731692e4 (patch)
treee2e063f03682f85368cb462d525b35e3114053db
parente598bc84cff9a281d312651332465c3899e3f49d (diff)
downloadbugzilla-bf3e63a75b8fbc9d613ec3fd6289a178731692e4.tar.gz
bugzilla-bf3e63a75b8fbc9d613ec3fd6289a178731692e4.tar.xz
Bug 455810 - Add autocomplete support to the keywords field
* Special thanks to Guy Pyrzak for the original patch [r=mkanat a=mkanat]
-rw-r--r--Bugzilla/Constants.pm2
-rw-r--r--Bugzilla/Field.pm4
-rw-r--r--Bugzilla/Template.pm3
-rw-r--r--js/field.js34
-rw-r--r--skins/standard/IE-fixes.css10
-rw-r--r--skins/standard/global.css20
-rw-r--r--template/en/default/bug/create/create.html.tmpl11
-rw-r--r--template/en/default/bug/edit.html.tmpl9
-rw-r--r--template/en/default/bug/field.html.tmpl27
-rw-r--r--template/en/default/list/edit-multiple.html.tmpl25
-rw-r--r--template/en/default/search/field.html.tmpl35
-rw-r--r--template/en/default/search/search-advanced.html.tmpl2
12 files changed, 140 insertions, 42 deletions
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index d11736af1..a003ce739 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -128,6 +128,7 @@ use File::Basename;
FIELD_TYPE_DATETIME
FIELD_TYPE_BUG_ID
FIELD_TYPE_BUG_URLS
+ FIELD_TYPE_KEYWORDS
EMPTY_DATETIME_REGEX
@@ -395,6 +396,7 @@ use constant FIELD_TYPE_TEXTAREA => 4;
use constant FIELD_TYPE_DATETIME => 5;
use constant FIELD_TYPE_BUG_ID => 6;
use constant FIELD_TYPE_BUG_URLS => 7;
+use constant FIELD_TYPE_KEYWORDS => 8;
use constant EMPTY_DATETIME_REGEX => qr/^[0\-:\sA-Za-z]+$/;
diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm
index 9ab5c49b9..15b494762 100644
--- a/Bugzilla/Field.pm
+++ b/Bugzilla/Field.pm
@@ -182,7 +182,7 @@ use constant DEFAULT_FIELDS => (
{name => 'status_whiteboard', desc => 'Status Whiteboard',
in_new_bugmail => 1, buglist => 1},
{name => 'keywords', desc => 'Keywords', in_new_bugmail => 1,
- buglist => 1},
+ type => FIELD_TYPE_KEYWORDS, buglist => 1},
{name => 'resolution', desc => 'Resolution',
type => FIELD_TYPE_SINGLE_SELECT, buglist => 1},
{name => 'bug_severity', desc => 'Severity', in_new_bugmail => 1,
@@ -322,7 +322,7 @@ sub _check_type {
my $saved_type = $type;
# The constant here should be updated every time a new,
# higher field type is added.
- (detaint_natural($type) && $type <= FIELD_TYPE_BUG_URLS)
+ (detaint_natural($type) && $type <= FIELD_TYPE_KEYWORDS)
|| ThrowCodeError('invalid_customfield_type', { type => $saved_type });
my $custom = blessed($invocant) ? $invocant->custom : $params->{custom};
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index a317bb7c7..71ade2f01 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -765,6 +765,9 @@ sub create {
# Whether or not keywords are enabled, in this Bugzilla.
'use_keywords' => sub { return Bugzilla::Keyword->any_exist; },
+ # All the keywords.
+ 'all_keywords' => sub { return Bugzilla::Keyword->get_all(); },
+
'feature_enabled' => sub { return Bugzilla->feature(@_); },
# field_descs can be somewhat slow to generate, so we generate
diff --git a/js/field.js b/js/field.js
index 39b272f92..20485bcc8 100644
--- a/js/field.js
+++ b/js/field.js
@@ -16,6 +16,7 @@
*
* Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
* Guy Pyrzak <guy.pyrzak@gmail.com>
+ * Reed Loden <reed@reedloden.com>
*/
/* This library assumes that the needed YUI libraries have been loaded
@@ -621,8 +622,8 @@ YAHOO.bugzilla.userAutocomplete = {
userAutoComp.autoHighlight = false;
// this is a throttle to determine the delay of the query from typing
// set this higher to cause fewer calls to the server
- userAutoComp.queryDelay = 0.05
- userAutoComp.useIFrame = true
+ userAutoComp.queryDelay = 0.05;
+ userAutoComp.useIFrame = true;
userAutoComp.resultTypeList = false;
if( multiple == true ){
userAutoComp.delimChar = [","," "];
@@ -631,3 +632,32 @@ YAHOO.bugzilla.userAutocomplete = {
}
};
+YAHOO.bugzilla.keywordAutocomplete = {
+ dataSource : null,
+ init_ds : function(){
+ this.dataSource = new YAHOO.util.LocalDataSource( YAHOO.bugzilla.keyword_array );
+ },
+ init : function( field, container ) {
+ if( this.dataSource == null ){
+ this.init_ds();
+ }
+ var keywordAutoComp = new YAHOO.widget.AutoComplete(field, container, this.dataSource);
+ keywordAutoComp.maxResultsDisplayed = YAHOO.bugzilla.keyword_array.length;
+ keywordAutoComp.minQueryLength = 0;
+ keywordAutoComp.useIFrame = true;
+ keywordAutoComp.delimChar = [","," "];
+ keywordAutoComp.resultTypeList = false;
+ keywordAutoComp.queryDelay = 0;
+ /* Causes all the possibilities in the keyword to appear when a user
+ * focuses on the textbox
+ */
+ keywordAutoComp.textboxFocusEvent.subscribe( function(){
+ var sInputValue = YAHOO.util.Dom.get('keywords').value;
+ if( sInputValue.length === 0 ){
+ this.sendQuery(sInputValue);
+ this.collapseContainer();
+ this.expandContainer();
+ }
+ });
+ }
+};
diff --git a/skins/standard/IE-fixes.css b/skins/standard/IE-fixes.css
index 1b6b9929f..fc2225398 100644
--- a/skins/standard/IE-fixes.css
+++ b/skins/standard/IE-fixes.css
@@ -47,6 +47,10 @@ form#Create #comp_desc {
#bug_id_container, .search_field_grid,
.search_email_fields, ul.bug_changes li {
- zoom: 1;
- display: inline;
-} \ No newline at end of file
+ zoom: 1;
+ display: inline;
+}
+
+#keyword_container .yui-ac-content {
+ _height: 30em; /* ie6 */
+}
diff --git a/skins/standard/global.css b/skins/standard/global.css
index 5cc71ef53..f0809c33a 100644
--- a/skins/standard/global.css
+++ b/skins/standard/global.css
@@ -527,7 +527,21 @@ input.required, select.required, span.required_explanation {
background-image: url(global/down.png);
}
-/* custom styles for inline instances of autocomplete input fields*/
+/* custom styles for inline instances of autocomplete input fields */
.yui-skin-sam .yui-ac-input { position:static !important;
- vertical-align:middle !important;}
-.yui-skin-sam .yui-ac-container { left:0px !important;}
+ vertical-align:middle !important;
+ width:auto !important; }
+.yui-skin-sam .yui-ac-container { left:0px !important; }
+.yui-skin-sam .yui-ac { display: inline-block; }
+
+#keyword_container {
+ padding-bottom: 2em;
+ padding-top: .2em;
+}
+
+#keyword_container .yui-ac-content {
+ max-height: 19em;
+ overflow: auto;
+ overflow-x: hidden;
+ margin-left: -1px;
+}
diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl
index 0733de02a..fdac893c0 100644
--- a/template/en/default/bug/create/create.html.tmpl
+++ b/template/en/default/bug/create/create.html.tmpl
@@ -630,14 +630,11 @@ TUI_hide_default('expert_fields');
[% IF user.in_group('editbugs', product.id) %]
[% IF use_keywords %]
<tr>
- [% INCLUDE "bug/field-label.html.tmpl"
- field = bug_fields.keywords editable = 1
- desc_url = "describekeywords.cgi"
+ [% INCLUDE bug/field.html.tmpl
+ bug = default, field = bug_fields.keywords, editable = 1,
+ value = keywords, desc_url = "describekeywords.cgi",
+ value_span = 2
%]
- <td colspan="3">
- <input id="keywords" name="keywords" size="40"
- value="[% keywords FILTER html %]"> (optional)
- </td>
</tr>
[% END %]
diff --git a/template/en/default/bug/edit.html.tmpl b/template/en/default/bug/edit.html.tmpl
index 0ef3cba8f..5520e7699 100644
--- a/template/en/default/bug/edit.html.tmpl
+++ b/template/en/default/bug/edit.html.tmpl
@@ -591,8 +591,13 @@
<label for="keywords" accesskey="k">
<b><a href="describekeywords.cgi"><u>K</u>eywords</a></b></label>:
</td>
- [% PROCESS input inputname => "keywords" size => 40 colspan => 2
- value => bug.keywords.join(', ') %]
+ <td class="field_value" colspan="2">
+ [% INCLUDE bug/field.html.tmpl
+ bug = bug, field = bug_fields.keywords, value = bug.keywords
+ editable = bug.check_can_change_field("keywords", 0, 1),
+ no_tds = 1
+ %]
+ </td>
</tr>
[% END %]
[% END %]
diff --git a/template/en/default/bug/field.html.tmpl b/template/en/default/bug/field.html.tmpl
index 97d38661c..2417ce39b 100644
--- a/template/en/default/bug/field.html.tmpl
+++ b/template/en/default/bug/field.html.tmpl
@@ -18,6 +18,8 @@
# Contributor(s): Myk Melez <myk@mozilla.org>
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Elliotte Martin <elliotte_martin@yahoo.com>
+ # Guy Pyrzak <guy.pyrzak@gmail.com>
+ # Reed Loden <reed@reedloden.com>
#%]
[%# INTERFACE:
@@ -165,22 +167,35 @@
[% FOREACH url = value %]
<li>
<a href="[% url FILTER html %]">[% url FILTER html %]</a>
- [% IF editable %]
- <label><input type="checkbox" value="[% url FILTER html %]"
- name="remove_[% field.name FILTER html %]">
- Remove</label>
- [% END %]
+ <label><input type="checkbox" value="[% url FILTER html %]"
+ name="remove_[% field.name FILTER html %]">
+ Remove</label>
</li>
[% END %]
[% '</ul>' IF value.size %]
- [% IF editable && Param('use_see_also') %]
+ [% IF Param('use_see_also') %]
<label for="[% field.name FILTER html %]">
<strong>Add [% terms.Bug %] URLs:</strong>
</label><br>
<input type="text" id="[% field.name FILTER html %]" size="40"
class="text_input" name="[% field.name FILTER html %]">
[% END %]
+ [% CASE constants.FIELD_TYPE_KEYWORDS %]
+ <div id="keyword_container">
+ <input type="text" id="[% field.name FILTER html %]" size="40"
+ class="text_input" name="[% field.name FILTER html %]"
+ value="[% value FILTER html %]">
+ <div id="keyword_autocomplete"></div>
+ </div>
+ <script type="text/javascript" defer="defer">
+ YAHOO.bugzilla.keyword_array = [
+ [%- FOREACH keyword = all_keywords %]
+ [%-# %]"[% keyword.name FILTER js %]"
+ [%- "," IF NOT loop.last %][% END %]];
+ YAHOO.bugzilla.keywordAutocomplete.init('[% field.name FILTER js %]',
+ 'keyword_autocomplete');
+ </script>
[% END %]
[% ELSIF field.type == constants.FIELD_TYPE_TEXTAREA %]
<div class="uneditable_textarea">[% value FILTER wrap_comment(60)
diff --git a/template/en/default/list/edit-multiple.html.tmpl b/template/en/default/list/edit-multiple.html.tmpl
index 619afe8dd..87eb0c7d4 100644
--- a/template/en/default/list/edit-multiple.html.tmpl
+++ b/template/en/default/list/edit-multiple.html.tmpl
@@ -19,6 +19,7 @@
# Max Kanat-Alexander <mkanat@bugzilla.org>
# Frédéric Buclin <LpSolit@gmail.com>
# Guy Pyrzak <guy.pyrzak@gmail.com>
+ # Reed Loden <reed@reedloden.com>
#%]
[% PROCESS global/variables.none.tmpl %]
@@ -173,7 +174,7 @@
id => "assigned_to"
name => "assigned_to"
value => dontchange
- size => 32
+ size => 40
%]
<input type="checkbox" id="set_default_assignee" name="set_default_assignee" value="1">
<label for="set_default_assignee">Reset Assignee to default</label>
@@ -188,7 +189,7 @@
id => "qa_contact"
name => "qa_contact"
value => dontchange
- size => 32
+ size => 40
%]
<input type="checkbox" id="set_default_qa_contact" name="set_default_qa_contact" value="1">
<label for="set_default_qa_contact">Reset QA Contact to default</label>
@@ -200,7 +201,7 @@
<th><label for="masscc">CC List:</label></th>
<td colspan="3">
- <input id="masscc" name="masscc" size="32">
+ <input id="masscc" name="masscc" size="40">
<select name="ccaction">
<option value="add">Add these to the CC List</option>
<option value="remove">Remove these from the CC List</option>
@@ -212,13 +213,15 @@
[% IF use_keywords %]
<tr>
- <th>
- <label for="keywords">
- <a href="describekeywords.cgi">Keywords</a>:
- </label>
- </th>
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = bug_fields.keywords, editable = 1
+ desc_url = "describekeywords.cgi"
+ %]
<td colspan="3">
- <input id="keywords" name="keywords" size="32">
+ [% INCLUDE bug/field.html.tmpl
+ field = bug_fields.keywords, editable = 1, value = keywords
+ no_tds = 1
+ %]
<select name="keywordaction">
<option value="add">Add these keywords</option>
<option value="delete">Delete these keywords</option>
@@ -236,7 +239,7 @@
</label>
</th>
<td colspan="3">
- <input id="dependson" name="dependson" size="32">
+ <input id="dependson" name="dependson" size="40">
<select name="dependson_action">
<option value="add">Add these IDs</option>
<option value="remove">Delete these IDs</option>
@@ -251,7 +254,7 @@
</label>
</th>
<td colspan="3">
- <input id="blocked" name="blocked" size="32">
+ <input id="blocked" name="blocked" size="40">
<select name="blocked_action">
<option value="add">Add these IDs</option>
<option value="remove">Delete these IDs</option>
diff --git a/template/en/default/search/field.html.tmpl b/template/en/default/search/field.html.tmpl
index 50a2f0c06..d4a1a30b7 100644
--- a/template/en/default/search/field.html.tmpl
+++ b/template/en/default/search/field.html.tmpl
@@ -15,6 +15,7 @@
# Initial Developer. All Rights Reserved.
#
# Contributor(s): Guy Pyrzak <guy.pyrzak@gmail.com>
+ # Reed Loden <reed@reedloden.com>
#
#%]
[%# INTERFACE:
@@ -35,16 +36,41 @@
tag_name = "span"
editable = 1
%]
-
[% INCLUDE "search/type-select.html.tmpl"
name = field.name _ "_type",
types = types,
- selected = type_selected %]
-
+ selected = type_selected
+ %]
<input name="[% field.name FILTER html %]"
id="[% field.name FILTER html %]" size="40"
[% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
value="[% value FILTER html %]">
+ [% CASE constants.FIELD_TYPE_KEYWORDS %]
+ [% INCLUDE "bug/field-label.html.tmpl"
+ field = field
+ tag_name = "span"
+ editable = 1
+ %]
+ [% INCLUDE "search/type-select.html.tmpl"
+ name = field.name _ "_type",
+ types = types,
+ selected = type_selected
+ %]
+ <div id="keyword_container">
+ <input name="[% field.name FILTER html %]"
+ id="[% field.name FILTER html %]" size="40"
+ [% IF onchange %] onchange="[% onchange FILTER html %]"[% END %]
+ value="[% value FILTER html %]">
+ <div id="keyword_autocomplete"></div>
+ </div>
+ <script type="text/javascript" defer="defer">
+ YAHOO.bugzilla.keyword_array = [
+ [%- FOREACH keyword = all_keywords %]
+ [%-# %]"[% keyword.name FILTER js %]"
+ [%- "," IF NOT loop.last %][% END %]];
+ YAHOO.bugzilla.keywordAutocomplete.init('[% field.name FILTER js %]',
+ 'keyword_autocomplete');
+ </script>
[% CASE constants.FIELD_TYPE_DATETIME %]
[% INCLUDE "bug/field-label.html.tmpl"
field = field
@@ -113,5 +139,4 @@
[% END %]
</select>
</div>
- [% END %]
- \ No newline at end of file
+ [% END %]
diff --git a/template/en/default/search/search-advanced.html.tmpl b/template/en/default/search/search-advanced.html.tmpl
index 1e0cc9251..fa9819c35 100644
--- a/template/en/default/search/search-advanced.html.tmpl
+++ b/template/en/default/search/search-advanced.html.tmpl
@@ -38,7 +38,7 @@ var queryform = "queryform"
title = "Search for $terms.bugs"
onload = "doOnSelectProduct(0); enableHelp();"
javascript = js_data
- yui = [ 'calendar' ]
+ yui = [ 'autocomplete', 'calendar' ]
javascript_urls = [ "js/productform.js", "js/util.js",
"js/help.js" , "js/TUI.js", "js/field.js"]
style_urls = [ "skins/standard/help.css" , "skins/standard/search_form.css" ]