diff --git a/chrome/content/zotero/itemPane.js b/chrome/content/zotero/itemPane.js index 25b0f6cb5..fe3d48e72 100644 --- a/chrome/content/zotero/itemPane.js +++ b/chrome/content/zotero/itemPane.js @@ -48,6 +48,7 @@ var ZoteroItemPane = new function() this.removeCreator = removeCreator; this.showEditor = showEditor; this.handleKeyPress = handleKeyPress; + this.handleCreatorAutoCompleteSelect = handleCreatorAutoCompleteSelect; this.hideEditor = hideEditor; this.getCreatorFields = getCreatorFields; this.modifyCreator = modifyCreator; @@ -440,8 +441,8 @@ var ZoteroItemPane = new function() label.setAttribute("fieldname",'creator-'+_creatorCount+'-typeID'); label.className = 'clicky'; - // getCreatorFields() and switchCreatorMode() may need need to be - // adjusted if this DOM structure changes + // getCreatorFields(), switchCreatorMode() and handleCreatorAutoCompleteSelect() + // may need need to be adjusted if this DOM structure changes var hbox = document.createElement("hbox"); // Name @@ -673,6 +674,7 @@ var ZoteroItemPane = new function() valueElement.appendChild(descriptionNode); } } + // 29 == arbitary length at which to chop uninterrupted text else if ((firstSpace == -1 && valueText.length > 29 ) || firstSpace > 29) { valueElement.setAttribute('crop', 'end'); @@ -771,6 +773,8 @@ var ZoteroItemPane = new function() } t.setAttribute('autocompletesearchparam', fieldName + '/' + suffix); + t.setAttribute('ontextentered', + 'ZoteroItemPane.handleCreatorAutoCompleteSelect(this)'); break; } } @@ -786,6 +790,41 @@ var ZoteroItemPane = new function() _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){ var target = document.commandDispatcher.focusedElement; switch (event.keyCode) diff --git a/components/chnmIZoteroAutoComplete.js b/components/chnmIZoteroAutoComplete.js index 323c4704b..759ec4fb3 100644 --- a/components/chnmIZoteroAutoComplete.js +++ b/components/chnmIZoteroAutoComplete.js @@ -138,27 +138,52 @@ ZoteroAutoComplete.prototype.startSearch = function(searchString, searchParam, } else { - 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 sql = "SELECT DISTINCT "; + if (fieldMode==1){ + sql += "lastName AS name, creatorID || '-1' AS creatorID"; + } + // Retrieve the matches in the specified field + // as well as any full names using the name + // + // 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)]; if (itemID){ - sql += " AND creatorID NOT IN (SELECT creatorID FROM " - + "itemCreators WHERE itemID = ?)"; + fromSQL += " AND creatorID NOT IN (SELECT creatorID FROM " + + "itemCreators WHERE itemID=?3)"; 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); for each(var row in rows){ results.push(row['name']); - // Not currently used - //comments.push(row['creatorID']) + comments.push(row['creatorID']) } break;