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
This commit is contained in:
parent
b79937d134
commit
3ac311e85a
|
@ -110,7 +110,9 @@
|
||||||
|
|
||||||
if(conditionsBox.hasChildNodes())
|
if(conditionsBox.hasChildNodes())
|
||||||
for(var i = 0, len=conditionsBox.childNodes.length; i < len; i++)
|
for(var i = 0, len=conditionsBox.childNodes.length; i < len; i++)
|
||||||
|
{
|
||||||
conditionsBox.childNodes[i].updateSearch();
|
conditionsBox.childNodes[i].updateSearch();
|
||||||
|
}
|
||||||
|
|
||||||
return this.search.save();
|
return this.search.save();
|
||||||
]]>
|
]]>
|
||||||
|
@ -133,8 +135,8 @@
|
||||||
<xul:label value="Match"/>
|
<xul:label value="Match"/>
|
||||||
<xul:menulist id="joinModeMenu" oncommand="this.parentNode.parentNode.parentNode.updateJoinMode();">
|
<xul:menulist id="joinModeMenu" oncommand="this.parentNode.parentNode.parentNode.updateJoinMode();">
|
||||||
<xul:menupopup>
|
<xul:menupopup>
|
||||||
<xul:menuitem label="Any" value="any"/>
|
<xul:menuitem label="any" value="any"/>
|
||||||
<xul:menuitem label="All" value="all" selected="true"/>
|
<xul:menuitem label="all" value="all" selected="true"/>
|
||||||
</xul:menupopup>
|
</xul:menupopup>
|
||||||
</xul:menulist>
|
</xul:menulist>
|
||||||
<xul:label value="of the following:"/>
|
<xul:label value="of the following:"/>
|
||||||
|
@ -160,18 +162,28 @@
|
||||||
var conditions = Scholar.SearchConditions.getStandardConditions();
|
var conditions = Scholar.SearchConditions.getStandardConditions();
|
||||||
|
|
||||||
for(var i=0, len=conditions.length; i<len; i++)
|
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;
|
conditionsList.selectedIndex = 0;
|
||||||
]]>
|
]]>
|
||||||
</constructor>
|
</constructor>
|
||||||
|
<field name="selectedCondition"/>
|
||||||
<method name="onConditionSelected">
|
<method name="onConditionSelected">
|
||||||
<body>
|
<body>
|
||||||
<![CDATA[
|
<![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 operatorsList = this.id('operatorsmenu');
|
||||||
|
|
||||||
var condition = Scholar.SearchConditions.get(this.id('conditionsmenu').value);
|
var condition = Scholar.SearchConditions.get(this.id('conditionsmenu').value);
|
||||||
var operators = condition['operators'];
|
var operators = condition['operators'];
|
||||||
|
|
||||||
|
// Display appropriate operators for condition
|
||||||
var selectThis;
|
var selectThis;
|
||||||
for(var i = 0, len = operatorsList.firstChild.childNodes.length; i < len; i++)
|
for(var i = 0, len = operatorsList.firstChild.childNodes.length; i < len; i++)
|
||||||
{
|
{
|
||||||
|
@ -182,12 +194,79 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
operatorsList.selectedIndex = selectThis;
|
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>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
<field name="dontupdate"/>
|
<field name="dontupdate"/>
|
||||||
<field name="parent"/>
|
<field name="parent"/>
|
||||||
<field name="conditionID"/>
|
<field name="conditionID"/>
|
||||||
|
<field name="value"/>
|
||||||
<method name="initWithParentAndCondition">
|
<method name="initWithParentAndCondition">
|
||||||
<parameter name="parent"/>
|
<parameter name="parent"/>
|
||||||
<parameter name="condition"/>
|
<parameter name="condition"/>
|
||||||
|
@ -200,9 +279,27 @@
|
||||||
{
|
{
|
||||||
this.dontupdate = true; //so that the search doesn't get updated while we are creating controls.
|
this.dontupdate = true; //so that the search doesn't get updated while we are creating controls.
|
||||||
|
|
||||||
|
// 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'];
|
this.id('conditionsmenu').value = condition['condition'];
|
||||||
|
var prefix = '';
|
||||||
|
}
|
||||||
|
|
||||||
this.id('operatorsmenu').value = condition['operator'];
|
this.id('operatorsmenu').value = condition['operator'];
|
||||||
this.id('valuefield').value = condition['value'];
|
this.value = prefix + condition['value'];
|
||||||
|
|
||||||
this.dontupdate = false;
|
this.dontupdate = false;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +315,35 @@
|
||||||
{
|
{
|
||||||
var condition = this.id('conditionsmenu').value;
|
var condition = this.id('conditionsmenu').value;
|
||||||
var operator = this.id('operatorsmenu').value;
|
var operator = this.id('operatorsmenu').value;
|
||||||
|
|
||||||
|
// Regular text field
|
||||||
|
if (!this.id('valuefield').hidden)
|
||||||
|
{
|
||||||
var value = this.id('valuefield').value;
|
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);
|
this.parent.search.updateCondition(this.conditionID, condition, operator, value);
|
||||||
}
|
}
|
||||||
]]>
|
]]>
|
||||||
|
@ -258,6 +383,9 @@
|
||||||
<xul:menupopup/>
|
<xul:menupopup/>
|
||||||
</xul:menulist>
|
</xul:menulist>
|
||||||
<xul:textbox id="valuefield" flex="1"/>
|
<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="remove" class="clicky" label="-" oncommand="this.parentNode.parentNode.onRemoveClicked();"/>
|
||||||
<xul:toolbarbutton id="add" class="clicky" label="+" oncommand="this.parentNode.parentNode.onAddClicked();"/>
|
<xul:toolbarbutton id="add" class="clicky" label="+" oncommand="this.parentNode.parentNode.onAddClicked();"/>
|
||||||
</xul:hbox>
|
</xul:hbox>
|
||||||
|
|
|
@ -563,7 +563,8 @@ Scholar.SearchConditions = new function(){
|
||||||
isNot: true
|
isNot: true
|
||||||
},
|
},
|
||||||
table: 'savedSearches',
|
table: 'savedSearches',
|
||||||
field: 'savedSearchID'
|
field: 'savedSearchID',
|
||||||
|
special: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -577,7 +578,7 @@ Scholar.SearchConditions = new function(){
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
name: 'itemType',
|
name: 'itemTypeID',
|
||||||
operators: {
|
operators: {
|
||||||
is: true,
|
is: true,
|
||||||
isNot: true
|
isNot: true
|
||||||
|
@ -593,7 +594,8 @@ Scholar.SearchConditions = new function(){
|
||||||
isNot: true
|
isNot: true
|
||||||
},
|
},
|
||||||
table: 'itemTags',
|
table: 'itemTags',
|
||||||
field: 'tagID'
|
field: 'tagID',
|
||||||
|
special: true
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -657,17 +659,36 @@ Scholar.SearchConditions = new function(){
|
||||||
delete _conditions[i];
|
delete _conditions[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sortKeys = [];
|
||||||
|
var sortValues = [];
|
||||||
|
|
||||||
// Separate standard conditions for menu display
|
// Separate standard conditions for menu display
|
||||||
for (var i in _conditions){
|
for (var i in _conditions){
|
||||||
// Standard conditions a have associated tables
|
// 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')
|
// If a template condition, not the original (e.g. 'field')
|
||||||
(!_conditions[i]['template'] || i!=_conditions[i]['name'])){
|
(!_conditions[i]['template'] || i!=_conditions[i]['name'])){
|
||||||
_standardConditions.push({
|
|
||||||
name: i,
|
try {
|
||||||
operators: _conditions[i]['operators']
|
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;
|
_initialized = true;
|
||||||
|
|
|
@ -106,5 +106,12 @@ searchOperator.greaterThan = is greater than
|
||||||
searchOperator.isBefore = is before
|
searchOperator.isBefore = is before
|
||||||
searchOperator.isAfter = is after
|
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.exportNotes = Export Notes
|
||||||
exportOptions.exportFileData = Export Files
|
exportOptions.exportFileData = Export Files
|
|
@ -66,6 +66,7 @@ seealsobox
|
||||||
scholarsearch
|
scholarsearch
|
||||||
{
|
{
|
||||||
-moz-binding: url('chrome://scholar/content/bindings/scholarsearch.xml#search-box');
|
-moz-binding: url('chrome://scholar/content/bindings/scholarsearch.xml#search-box');
|
||||||
|
width:60em;
|
||||||
}
|
}
|
||||||
|
|
||||||
searchcondition
|
searchcondition
|
||||||
|
@ -73,6 +74,11 @@ searchcondition
|
||||||
-moz-binding: url('chrome://scholar/content/bindings/scholarsearch.xml#search-condition');
|
-moz-binding: url('chrome://scholar/content/bindings/scholarsearch.xml#search-condition');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchcondition menulist[id="operatorsmenu"]
|
||||||
|
{
|
||||||
|
width:15em;
|
||||||
|
}
|
||||||
|
|
||||||
.clicky, .unclicky
|
.clicky, .unclicky
|
||||||
{
|
{
|
||||||
-moz-border-radius: 6px;
|
-moz-border-radius: 6px;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user