www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 3ac311e85aaa8af7f126d74d422ec7159cc20654
parent b79937d13428c9d092ce96377d33230345ae893b
Author: Dan Stillman <dstillman@zotero.org>
Date:   Mon, 21 Aug 2006 05:08:11 +0000

Search improvements:

Conditions can now offer drop-down menus rather than freeform text fields -- implemented for collections/saved searches and item types

Special handling to combine collections and saved searches into a single "Collection" menu (can we get away with calling them "Smart Collections"?) -- internally, values are stored as C1234 or S5678 in the interface and converted to/from regular collectionID and savedSearchID conditions for search.js

Use localized strings for conditions (tries searchConditions.* first, then itemFields.*)

Alphabetize condition list

Operator menu now fixed length for all conditions


Diffstat:
Mchrome/chromeFiles/content/scholar/bindings/scholarsearch.xml | 142+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mchrome/chromeFiles/content/scholar/xpcom/search.js | 33+++++++++++++++++++++++++++------
Mchrome/chromeFiles/locale/en-US/scholar/scholar.properties | 7+++++++
Mchrome/chromeFiles/skin/default/scholar/scholar.css | 6++++++
4 files changed, 175 insertions(+), 13 deletions(-)

diff --git a/chrome/chromeFiles/content/scholar/bindings/scholarsearch.xml b/chrome/chromeFiles/content/scholar/bindings/scholarsearch.xml @@ -110,7 +110,9 @@ if(conditionsBox.hasChildNodes()) for(var i = 0, len=conditionsBox.childNodes.length; i < len; i++) + { conditionsBox.childNodes[i].updateSearch(); + } return this.search.save(); ]]> @@ -133,8 +135,8 @@ <xul:label value="Match"/> <xul:menulist id="joinModeMenu" oncommand="this.parentNode.parentNode.parentNode.updateJoinMode();"> <xul:menupopup> - <xul:menuitem label="Any" value="any"/> - <xul:menuitem label="All" value="all" selected="true"/> + <xul:menuitem label="any" value="any"/> + <xul:menuitem label="all" value="all" selected="true"/> </xul:menupopup> </xul:menulist> <xul:label value="of the following:"/> @@ -160,18 +162,28 @@ var conditions = Scholar.SearchConditions.getStandardConditions(); for(var i=0, len=conditions.length; i<len; i++) - conditionsList.appendItem(conditions[i]['name'], conditions[i]['name']); + { + conditionsList.appendItem(conditions[i]['localized'], conditions[i]['name']); + } conditionsList.selectedIndex = 0; ]]> </constructor> + <field name="selectedCondition"/> <method name="onConditionSelected"> <body> <![CDATA[ + // Skip if already selected + if (this.id('conditionsmenu').value==this.selectedCondition){ + return; + } + this.selectedCondition = this.id('conditionsmenu').value; + var operatorsList = this.id('operatorsmenu'); var condition = Scholar.SearchConditions.get(this.id('conditionsmenu').value); var operators = condition['operators']; + // Display appropriate operators for condition var selectThis; for(var i = 0, len = operatorsList.firstChild.childNodes.length; i < len; i++) { @@ -182,12 +194,79 @@ } operatorsList.selectedIndex = selectThis; + + // Generate drop-down menus for certain conditions + switch (this.id('conditionsmenu').value){ + case 'collectionID': + var merged = []; + var searches = Scholar.Searches.getAll(); + var cols = Scholar.getCollections(); + for (var i in cols) + { + merged.push([cols[i].getName(), 'C' + cols[i].getID()]); + } + for (var i in searches) + { + merged.push([searches[i]['name'], 'S' + searches[i]['id']]); + } + + this.createValueMenu(merged); + break; + + case 'itemTypeID': + var types = Scholar.ItemTypes.getTypes(); + for (var i in types) + { + types[i][0] = Scholar.getString('itemTypes.' + types[i]['name']); + types[i][1] = types[i]['id']; + delete types[i]['name']; + delete types[i]['id']; + } + this.createValueMenu(types); + break; + + default: + // If switching between menu and textbox, clear value + if (this.id('valuefield').hidden){ + this.value = ''; + this.id('valuefield').value = ''; + } + else { + this.id('valuefield').value = this.value; + } + + this.id('valuefield').hidden = false; + this.id('valuemenu').hidden = true; + break; + } + ]]> + </body> + </method> + <method name="createValueMenu"> + <parameter name="values"/> + <body> + <![CDATA[ + while (this.id('valuemenu').hasChildNodes()){ + this.id('valuemenu').removeChild(this.id('valuemenu').firstChild); + } + + if (values.length){ + for (var i in values){ + this.id('valuemenu').appendItem(values[i][0], values[i][1]); + } + this.id('valuemenu').selectedIndex = 0; + } + + this.id('valuemenu').value = this.value; + this.id('valuefield').hidden = true; + this.id('valuemenu').hidden = false; ]]> </body> </method> <field name="dontupdate"/> <field name="parent"/> <field name="conditionID"/> + <field name="value"/> <method name="initWithParentAndCondition"> <parameter name="parent"/> <parameter name="condition"/> @@ -200,10 +279,28 @@ { this.dontupdate = true; //so that the search doesn't get updated while we are creating controls. - this.id('conditionsmenu').value = condition['condition']; + // Handle collectionID/savedSearchID + switch (condition['condition']) + { + case 'savedSearchID': + this.id('conditionsmenu').value = 'collectionID'; + var prefix = 'S'; + break; + + case 'collectionID': + this.id('conditionsmenu').value = 'collectionID'; + var prefix = 'C'; + + // fall through + + default: + this.id('conditionsmenu').value = condition['condition']; + var prefix = ''; + } + this.id('operatorsmenu').value = condition['operator']; - this.id('valuefield').value = condition['value']; - + this.value = prefix + condition['value']; + this.dontupdate = false; } @@ -218,7 +315,35 @@ { var condition = this.id('conditionsmenu').value; var operator = this.id('operatorsmenu').value; - var value = this.id('valuefield').value; + + // Regular text field + if (!this.id('valuefield').hidden) + { + var value = this.id('valuefield').value; + } + + // Handle special C1234 and S5678 form for + // collections and searches + else if (this.id('conditionsmenu').value=='collectionID') + { + var letter = this.id('valuemenu').value.substr(0,1); + if (letter=='C') + { + condition = 'collectionID'; + } + else if (letter=='S') + { + condition = 'savedSearchID'; + } + var value = this.id('valuemenu').value.substr(1); + } + + // Regular drop-down menu + else + { + var value = this.id('valuemenu').value; + } + this.parent.search.updateCondition(this.conditionID, condition, operator, value); } ]]> @@ -258,6 +383,9 @@ <xul:menupopup/> </xul:menulist> <xul:textbox id="valuefield" flex="1"/> + <xul:menulist id="valuemenu" flex="1" hidden="true"> + <xul:menupopup/> + </xul:menulist> <xul:toolbarbutton id="remove" class="clicky" label="-" oncommand="this.parentNode.parentNode.onRemoveClicked();"/> <xul:toolbarbutton id="add" class="clicky" label="+" oncommand="this.parentNode.parentNode.onAddClicked();"/> </xul:hbox> diff --git a/chrome/chromeFiles/content/scholar/xpcom/search.js b/chrome/chromeFiles/content/scholar/xpcom/search.js @@ -563,7 +563,8 @@ Scholar.SearchConditions = new function(){ isNot: true }, table: 'savedSearches', - field: 'savedSearchID' + field: 'savedSearchID', + special: true }, { @@ -577,7 +578,7 @@ Scholar.SearchConditions = new function(){ }, { - name: 'itemType', + name: 'itemTypeID', operators: { is: true, isNot: true @@ -593,7 +594,8 @@ Scholar.SearchConditions = new function(){ isNot: true }, table: 'itemTags', - field: 'tagID' + field: 'tagID', + special: true }, { @@ -657,19 +659,38 @@ Scholar.SearchConditions = new function(){ delete _conditions[i]; } + var sortKeys = []; + var sortValues = []; + // Separate standard conditions for menu display for (var i in _conditions){ // Standard conditions a have associated tables - if (_conditions[i]['table'] && + if (_conditions[i]['table'] && !_conditions[i]['special'] && // If a template condition, not the original (e.g. 'field') (!_conditions[i]['template'] || i!=_conditions[i]['name'])){ - _standardConditions.push({ + + try { + var localized = Scholar.getString('searchConditions.' + i) + } + catch (e){ + var localized = Scholar.getString('itemFields.' + i); + } + + sortKeys.push(localized); + sortValues[localized] = { name: i, + localized: localized, operators: _conditions[i]['operators'] - }); + }; } } + // Alphabetize by localized name + sortKeys = sortKeys.sort(); + for each(var i in sortKeys){ + _standardConditions.push(sortValues[i]); + } + _initialized = true; } diff --git a/chrome/chromeFiles/locale/en-US/scholar/scholar.properties b/chrome/chromeFiles/locale/en-US/scholar/scholar.properties @@ -106,5 +106,12 @@ searchOperator.greaterThan = is greater than searchOperator.isBefore = is before searchOperator.isAfter = is after +searchConditions.collectionID = Collection +searchConditions.itemTypeID = Item Type +searchConditions.tag = Tag +searchConditions.note = Note +searchConditions.creator = Creator +searchConditions.thesisType = Thesis Type + exportOptions.exportNotes = Export Notes exportOptions.exportFileData = Export Files \ No newline at end of file diff --git a/chrome/chromeFiles/skin/default/scholar/scholar.css b/chrome/chromeFiles/skin/default/scholar/scholar.css @@ -66,6 +66,7 @@ seealsobox scholarsearch { -moz-binding: url('chrome://scholar/content/bindings/scholarsearch.xml#search-box'); + width:60em; } searchcondition @@ -73,6 +74,11 @@ searchcondition -moz-binding: url('chrome://scholar/content/bindings/scholarsearch.xml#search-condition'); } +searchcondition menulist[id="operatorsmenu"] +{ + width:15em; +} + .clicky, .unclicky { -moz-border-radius: 6px;