commit da5e74a06a70fb21adde8d193e455cc168ab83e7
parent 70b27723819eff2a11ab1e3d0658dd376143b4f5
Author: Dan Stillman <dstillman@zotero.org>
Date: Mon, 25 Sep 2006 06:38:47 +0000
Autocomplete for creators in item pane
Differentiates between single and double fields for the search, but there's a problem in the current implementation in that only one field is editable at once, so displaying two-field names in a drop-down is a little problematic. While I could display the full names, comma-delimited, and get the discrete parts (which is what Scholar.Utilities.AutoComplete.getResultComment(), included in this commit, is for--the creatorID for the row would be hidden in the autocomplete drop-down comment field), it's a bit unclear what should happen when a user selects a comma-separated name from the drop-down of one of the fields. One option would be to have a row for the last name (in case that's all they want to complete) and other rows for "last, first" matches, and selecting one of the two-part names would replace whatever's in the opposite name field with the appropriate text (and save it to the DB, I'm afraid, unless I change how the creator fields work), keeping the focus in the current textbox for easy tabbing. Not great, but it might work.
Other ideas?
Diffstat:
3 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/chrome/chromeFiles/content/scholar/itemPane.js b/chrome/chromeFiles/content/scholar/itemPane.js
@@ -707,9 +707,10 @@ var ScholarItemPane = new function()
{
t.setAttribute('type', 'autocomplete');
t.setAttribute('autocompletesearch', 'zotero');
- t.setAttribute('autocompletesearchparam', fieldName + (itemID ? '/' + itemID : ''));
+ t.setAttribute('autocompletesearchparam', fieldName + '/' +
+ (elem.getAttribute('singleField')=='true' ? '1' : '0') +
+ '-' + (itemID ? itemID : ''));
}
-
var box = elem.parentNode;
box.replaceChild(t,elem);
@@ -722,7 +723,6 @@ var ScholarItemPane = new function()
_lastTabIndex = tabindex;
}
-
function handleKeyPress(event){
var target = document.commandDispatcher.focusedElement;
switch (event.keyCode)
diff --git a/chrome/chromeFiles/content/scholar/xpcom/utilities.js b/chrome/chromeFiles/content/scholar/xpcom/utilities.js
@@ -595,4 +595,25 @@ Scholar.Utilities.HTTP.processDocuments = function(firstDoc, urls, processor, do
}
init();
+}
+
+
+/*
+ * This would probably be better as a separate XPCOM service
+ */
+Scholar.Utilities.AutoComplete = new function(){
+ this.getResultComment = getResultComment;
+
+ function getResultComment(textbox){
+ var controller = textbox.controller;
+
+ for (var i=0; i<controller.matchCount; i++)
+ {
+ if (controller.getValueAt(i) == textbox.value)
+ {
+ return controller.getCommentAt(i);
+ }
+ }
+ return false;
+ }
}
\ No newline at end of file
diff --git a/components/chnmIZoteroAutoComplete.js b/components/chnmIZoteroAutoComplete.js
@@ -1,7 +1,7 @@
const ZOTERO_AC_CONTRACTID = '@mozilla.org/autocomplete/search;1?name=zotero';
const ZOTERO_AC_CLASSNAME = 'Zotero AutoComplete';
const ZOTERO_AC_CID = Components.ID('{06a2ed11-d0a4-4ff0-a56f-a44545eee6ea}');
-const ZOTERO_AC_IID = Components.interfaces.chnmIZoteroAutoComplete;
+//const ZOTERO_AC_IID = Components.interfaces.chnmIZoteroAutoComplete;
const Cc = Components.classes;
const Ci = Components.interfaces;
@@ -90,6 +90,9 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam,
+ searchParam + "'" + " with string '" + searchString + "'");
*/
+ var results = [];
+ var comments = [];
+
// Allow extra parameters to be passed in
var pos = searchParam.indexOf('/');
if (pos!=-1){
@@ -97,6 +100,9 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam,
var searchParam = searchParam.substr(0, pos);
}
+ var searchParts = searchParam.split('-');
+ searchParam = searchParts[0];
+
switch (searchParam){
case 'tag':
var sql = "SELECT tag FROM tags WHERE tag LIKE ?";
@@ -106,23 +112,50 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam,
+ "itemID = ?)";
sqlParams.push(extra);
}
+ sql += " ORDER BY tag";
var results = this._zotero.DB.columnQuery(sql, sqlParams);
var resultCode = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
break;
+
+ case 'creator':
+ var [singleField, itemID] = extra.split('-');
+ var sql = "SELECT "
+ // Full name not currently returned
+ //+ "lastName" + (!singleField ? '' : "|| ', ' || firstName")
+ + searchParts[2]
+ + " AS name, creatorID "
+ + "FROM creators WHERE " + searchParts[2] + " LIKE ? "
+ + "AND isInstitution=?";
+ var sqlParams = [searchString + '%', parseInt(singleField)];
+ if (itemID){
+ sql += " AND creatorID NOT IN (SELECT creatorID FROM "
+ + "itemCreators WHERE itemID = ?)";
+ sqlParams.push(itemID);
+ }
+ sql += " ORDER BY " + searchParts[2];
+ var rows = this._zotero.DB.query(sql, sqlParams);
+ for each(var row in rows){
+ results.push(row['name']);
+ // No currently used
+ //comments.push(row['creatorID'])
+ }
+ var resultCode = Ci.nsIAutoCompleteResult.RESULT_SUCCESS;
+ break;
+
default:
this._zotero.debug("'" + searchParam + "' is not a valid autocomplete scope", 1);
- var results = []
+ var results = [];
var resultCode = Ci.nsIAutoCompleteResult.RESULT_IGNORED;
}
- if (results===false){
+ if (!results || !results.length){
var results = [];
var resultCode = Ci.nsIAutoCompleteResult.RESULT_NOMATCH;
}
var result = new ZoteroAutoCompleteResult(searchString,
- resultCode, 0, "", results, []);
+ resultCode, 0, "", results, comments);
listener.onSearchResult(this, result);
}