Display and save multiple-field selections in the creator autocomplete

In other words, show both "Shakespeare" and "Shakespeare, William" in the drop-down, and if the latter is chosen, save both fields

One issue is that since the autocomplete is by default limited to the width of the textbox, longer entries get truncated (though you can see them with a mouseover), and that may not be easy to fix.
This commit is contained in:
Dan Stillman 2006-10-03 08:38:49 +00:00
parent 044aea0fad
commit 9f959bf3e0
2 changed files with 78 additions and 14 deletions

View File

@ -48,6 +48,7 @@ var ZoteroItemPane = new function()
this.removeCreator = removeCreator; this.removeCreator = removeCreator;
this.showEditor = showEditor; this.showEditor = showEditor;
this.handleKeyPress = handleKeyPress; this.handleKeyPress = handleKeyPress;
this.handleCreatorAutoCompleteSelect = handleCreatorAutoCompleteSelect;
this.hideEditor = hideEditor; this.hideEditor = hideEditor;
this.getCreatorFields = getCreatorFields; this.getCreatorFields = getCreatorFields;
this.modifyCreator = modifyCreator; this.modifyCreator = modifyCreator;
@ -440,8 +441,8 @@ var ZoteroItemPane = new function()
label.setAttribute("fieldname",'creator-'+_creatorCount+'-typeID'); label.setAttribute("fieldname",'creator-'+_creatorCount+'-typeID');
label.className = 'clicky'; label.className = 'clicky';
// getCreatorFields() and switchCreatorMode() may need need to be // getCreatorFields(), switchCreatorMode() and handleCreatorAutoCompleteSelect()
// adjusted if this DOM structure changes // may need need to be adjusted if this DOM structure changes
var hbox = document.createElement("hbox"); var hbox = document.createElement("hbox");
// Name // Name
@ -673,6 +674,7 @@ var ZoteroItemPane = new function()
valueElement.appendChild(descriptionNode); valueElement.appendChild(descriptionNode);
} }
} }
// 29 == arbitary length at which to chop uninterrupted text
else if ((firstSpace == -1 && valueText.length > 29 ) || firstSpace > 29) else if ((firstSpace == -1 && valueText.length > 29 ) || firstSpace > 29)
{ {
valueElement.setAttribute('crop', 'end'); valueElement.setAttribute('crop', 'end');
@ -771,6 +773,8 @@ var ZoteroItemPane = new function()
} }
t.setAttribute('autocompletesearchparam', t.setAttribute('autocompletesearchparam',
fieldName + '/' + suffix); fieldName + '/' + suffix);
t.setAttribute('ontextentered',
'ZoteroItemPane.handleCreatorAutoCompleteSelect(this)');
break; break;
} }
} }
@ -786,6 +790,41 @@ var ZoteroItemPane = new function()
_lastTabIndex = tabindex; _lastTabIndex = tabindex;
} }
/*
* Save a multiple-field selection for the creator autocomplete
* (e.g. "Shakespeare, William")
*/
function handleCreatorAutoCompleteSelect(textbox, creatorField)
{
var comment = Zotero.Utilities.AutoComplete.getResultComment(textbox);
if (!comment)
{
return false;
}
var [creatorID, numFields] = comment.split('-');
// If result uses two fields, save both
if (numFields==2)
{
var [field, creatorIndex, creatorField] =
textbox.getAttribute('fieldname').split('-');
var creator = Zotero.Creators.get(creatorID);
var row = textbox.parentNode.parentNode.parentNode;
var otherFields = ZoteroItemPane.getCreatorFields(row);
var otherField = creatorField=='lastName' ? 'firstName' : 'lastName';
otherFields[otherField] = creator[otherField];
ZoteroItemPane.modifyCreator(creatorIndex, creatorField,
creator[creatorField], otherFields);
}
// Otherwise let the autocomplete popup handle matters
}
function handleKeyPress(event){ function handleKeyPress(event){
var target = document.commandDispatcher.focusedElement; var target = document.commandDispatcher.focusedElement;
switch (event.keyCode) switch (event.keyCode)

View File

@ -138,27 +138,52 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam,
} }
else else
{ {
var sql = "SELECT " var sql = "SELECT DISTINCT ";
// Full name not currently returned if (fieldMode==1){
//+ "lastName" + (!singleField ? '' : "|| ', ' || firstName") sql += "lastName AS name, creatorID || '-1' AS creatorID";
+ searchParts[2] }
+ " AS name, creatorID " // Retrieve the matches in the specified field
+ "FROM creators WHERE " + searchParts[2] + " LIKE ? " // as well as any full names using the name
+ "AND isInstitution=?"; //
// e.g. "Shakespeare" and "Shakespeare, William"
//
// creatorID is in the format "12345-1" or "12345-2",
// - 1 means the row uses only the specified field
// - 2 means it uses both
else {
sql += "CASE WHEN firstName='' OR firstName IS NULL THEN lastName "
+ "ELSE lastName || ', ' || firstName END AS name, "
+ "creatorID || '-' || CASE "
+ "WHEN (firstName = '' OR firstName IS NULL) THEN 1 "
+ "ELSE 2 END AS creatorID";
}
var fromSQL = " FROM creators WHERE " + searchParts[2]
+ " LIKE ?1 " + "AND isInstitution=?2";
var sqlParams = [searchString + '%', parseInt(fieldMode)]; var sqlParams = [searchString + '%', parseInt(fieldMode)];
if (itemID){ if (itemID){
sql += " AND creatorID NOT IN (SELECT creatorID FROM " fromSQL += " AND creatorID NOT IN (SELECT creatorID FROM "
+ "itemCreators WHERE itemID = ?)"; + "itemCreators WHERE itemID=?3)";
sqlParams.push(itemID); sqlParams.push(itemID);
} }
sql += " ORDER BY " + searchParts[2];
sql += fromSQL;
// If double-field mode, include matches for just this field
// as well (i.e. "Shakespeare"), and group to collapse repeats
if (fieldMode!=1){
sql = "SELECT * FROM (" + sql + " UNION SELECT DISTINCT "
+ searchParts[2] + " AS name, creatorID || '-1' AS creatorID"
+ fromSQL + ") GROUP BY name";
}
sql += " ORDER BY name";
} }
var rows = this._zotero.DB.query(sql, sqlParams); var rows = this._zotero.DB.query(sql, sqlParams);
for each(var row in rows){ for each(var row in rows){
results.push(row['name']); results.push(row['name']);
// Not currently used comments.push(row['creatorID'])
//comments.push(row['creatorID'])
} }
break; break;