</permacrud>
</class>
- <class id="cmsa" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::metabib_search_alias" oils_persist:tablename="config.metabib_search_alias" reporter:label="Metabib Search Alias">
+ <class id="cmsa" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::metabib_search_alias" oils_persist:tablename="config.metabib_search_alias" reporter:label="Metabib Search Alias" oils_persist:field_safe="true">
<fields oils_persist:primary="alias">
<field reporter:label="Alias (RegExp)" name="alias" reporter:datatype="text"/>
<field reporter:label="Class" name="field_class" reporter:datatype="link"/>
</permacrud>
</class>
- <class id="cmc" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::metabib_class" oils_persist:tablename="config.metabib_class" reporter:label="Metabib Class">
+ <class id="cmc" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::metabib_class" oils_persist:tablename="config.metabib_class" reporter:label="Metabib Class" oils_persist:field_safe="true">
<fields oils_persist:primary="name">
<field reporter:label="Name" name="name" reporter:datatype="text"/>
<field reporter:label="Label" name="label" reporter:datatype="text"/>
</permacrud>
</class>
- <class id="cmf" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::metabib_field" oils_persist:tablename="config.metabib_field" reporter:label="Metabib Field">
+ <class id="cmf" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="config::metabib_field" oils_persist:tablename="config.metabib_field" reporter:label="Metabib Field" oils_persist:field_safe="true">
<fields oils_persist:primary="id" oils_persist:sequence="config.metabib_field_id_seq">
<field reporter:label="Class" name="field_class" reporter:datatype="link"/>
<field reporter:label="ID" name="id" reporter:datatype="id" />
my $query = $base_query;
$log->debug("Full base query: $base_query", DEBUG);
+ $query = "$args{facets} $query" if ($args{facets});
+
if (!$locale_map{COMPLETE}) {
my @locales = config::i18n_locale->search_where({ code => { '<>' => '' } });
{ name => 'orgUnit',
desc => 'An OpenILS actor::org_unit short name that limits the scope of returned holdings',
type => 'text' },
+ { name => 'depth',
+ desc => 'An OpenILS actor::org_unit_type depththat limits the scope of returned holdings',
+ type => 'number' },
{ name => 'hideCopies',
desc => 'Flag that prevents the inclusion of copies in the returned holdings',
type => 'boolean' },
if ($uri =~ m{^tag:[^:]+:([^\/]+)/([^\/[]+)(?:\[([0-9,]+)\])?(?:/(.+))?}o) {
$id = $2;
$paging = $3;
- $lib = uc($4);
+ ($lib,$depth) = split('/', $4);
$type = 'record';
$type = 'metarecord' if ($1 =~ /^m/o);
$type = 'authority' if ($1 =~ /^authority/o);
if (dojo.isObject(params)) {
args = params;
} else {
- args.params = [].splice.call(arguments, 1, arguments.length - 1);
+ args.params = [].splice.call(arguments, 2, arguments.length - 2);
}
}
--- /dev/null
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2010 Equinox Software, Inc
+ * Mike Rylander <miker@esilibrary.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * ---------------------------------------------------------------------------
+ */
+
+if(!dojo._hasResource["openils.widget.FacetSidebar"]) {
+
+ dojo._hasResource["openils.widget.FacetSidebar"] = true;
+ dojo.provide("openils.widget.FacetSidebar");
+ dojo.require("openils.widget.Searcher");
+
+ dojo.declare(
+ 'openils.widget.FacetSidebar',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString : '<div dojoAttachPoint="myTop"><div dojoAttachPoint="containerNode"></div><div class="facetClassContainer" dojoAttachPoint="facetClasses"></div></div>',
+ widgetsInTemplate: false,
+
+ facetData : {},
+ facetCacheKey : '',
+ searchBox : '',
+ classOrder : null,
+ searchSubmit : '',
+ facetLimit : 10,
+
+ startup : function () {
+ this.populate();
+ this.inherited(arguments)
+ },
+
+ populate : function () {},
+
+ render : function () {
+ if (!this.facetCacheKey) return;
+
+ if (openils.widget.Searcher._cache.facetData) {
+ this.facetData = openils.widget.Searcher._cache.facetData;
+ } else {
+ var facetData = fieldmapper.standardRequest( [ 'open-ils.search', 'open-ils.search.facet_cache.retrieve'], this.facetCacheKey );
+ if (!facetData) return;
+ this.facetData = openils.widget.Searcher._cache.facetData = facetData;
+ }
+
+ var classes = openils.widget.Searcher._cache.arr.cmc;
+ if (this.classOrder && this.classOrder.length > 0) {
+ classes = [];
+ dojo.forEach(
+ this.classOrder,
+ function(x) { classes.push({name:x}); }
+ );
+ }
+
+ var me = this;
+ dojo.forEach(
+ classes,
+ function (x) {
+ var possible_facets = dojo.filter(
+ openils.widget.Searcher._cache.arr.cmf,
+ function (y) {
+ if (y.field_class == x.name && facetData[y.id]) return 1;
+ return 0;
+ }
+ );
+ if (possible_facets.length > 0) me.addClass( x.name, possible_facets );
+ }
+ );
+ },
+
+ addClass : function (thisclass, facets) {
+ return new openils.widget.FacetSidebar.facetClass(
+ { facetLimit: this.facetLimit, searchBox : this.searchBox, searchSubmit : this.searchSubmit, facetClass : thisclass, facetData : this.facetData, facetList : facets }
+ ).placeAt(this.facetClasses, 'last');
+ }
+ }
+ );
+
+ dojo._hasResource["openils.widget.FacetSidebar.facetClass"] = true;
+ dojo.provide("openils.widget.FacetSidebar.facetClass");
+
+ dojo.declare(
+ 'openils.widget.FacetSidebar.facetClass',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString :
+'<div class="facetClassLabelContainer">' +
+' <div class="facetClassLabel" dojoAttachPoint="facetClassLabel"></div>' +
+' <div class="facetFieldContainer" dojoAttachPoint="facetFields"></div>' +
+'</div>',
+ widgetsInTemplate: false,
+
+ facetLimit : 10,
+ facetClass : '',
+ facetData : null,
+ facetList : null,
+ searchBox : '',
+ searchSubmit : '',
+
+ postCreate : function () {
+ if (!this.facetClass) return;
+ if (!this.facetData) return;
+
+ var myclass = this.facetClass;
+
+ var fclass = dojo.filter(openils.widget.Searcher._cache.arr.cmc, function (x) { if (x.name == myclass) return 1; return 0; })[0];
+ this.facetClassLabel.innerHTML = fclass.label;
+
+ var me = this;
+ dojo.forEach(
+ this.facetList,
+ function (f) { me.addFacets(f); }
+ );
+ },
+
+ addFacets : function (f) {
+ return new openils.widget.FacetSidebar.facetField(
+ { facetLimit: this.facetLimit, searchBox : this.searchBox, searchSubmit : this.searchSubmit, facet : f, facetData : this.facetData[f.id] }
+ ).placeAt( this.facetFields, 'last' );
+ }
+ }
+ );
+
+ dojo._hasResource["openils.widget.FacetSidebar.facetField"] = true;
+ dojo.provide("openils.widget.FacetSidebar.facetField");
+
+ dojo.declare(
+ 'openils.widget.FacetSidebar.facetField',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString :
+'<div class="facetField" dojoAttachPoint="myTop">' +
+' <div class="extraFacetFieldsWrapper" dojoAttachPoint="toggleExtraFacetFieldsWrapper"><button class="toggleExtraFacetFieldsButton" dojoType="dijit.form.Button" dojoAttachPoint="toggleExtraFacetFields" dojoAttachEvent="onClick:toggleExtraFacets"></button></div>' +
+' <div class="facetFieldLabel" dojoAttachPoint="facetLabel"></div>' +
+' <div class="facetFields" dojoAttachPoint="facetFields"></div>' +
+' <div class="facetFields hide_me" dojoAttachPoint="extraFacetFields"></div>' +
+'</div>',
+
+ widgetsInTemplate: true,
+ facet : null,
+ facetData : null,
+ facetLimit : 10,
+ searchBox : '',
+ searchSubmit : '',
+ extraHidden : true,
+
+ postCreate : function () {
+ this.nls = dojo.i18n.getLocalization("openils.widget", "Searcher");
+ var me = this;
+ var keylist = []; for (var i in this.facetData) { keylist.push(i); }
+
+ keylist = keylist.sort(function(a,b){
+ if (me.facetData[a] < me.facetData[b]) return 1;
+ if (me.facetData[a] > me.facetData[b]) return -1;
+ if (a < b) return -1;
+ if (a > b) return 1;
+ return 0;
+ });
+
+ this.facetLabel.innerHTML = this.facet.label;
+ this.toggleExtraFacetFields.setLabel(this.nls.more);
+
+ var pos = 0;
+ dojo.forEach(
+ keylist,
+ function(value){
+
+ var have_it = dojo.byId(me.searchBox).value.indexOf(me.facet.field_class + '|' + me.facet.name + '[' + value + ']') > -1;
+
+ var container = dojo.create('div',{'class':'facetFieldLine'});
+ dojo.create('span',{'class':'facetFieldLineCount', innerHTML: me.facetData[value]},container);
+
+ if (have_it) {
+ dojo.create('a',{href : '#', 'class':'facetFieldLineValue', onclick : function(){ me.undoSearch(value); return false;}, innerHTML: '<b>(' + value + ')</b>'},container);
+ } else {
+ dojo.create('a',{href : '#', 'class':'facetFieldLineValue', onclick : function(){ me.doSearch(value); return false;}, innerHTML: value},container);
+ }
+
+ if (pos >= me.facetLimit) dojo.place(container,me.extraFacetFields,'last');
+ else dojo.place(container,me.facetFields,'last');
+
+ pos++;
+ }
+ );
+
+ if (pos < me.facetLimit + 1) dojo.query(this.toggleExtraFacetFieldsWrapper).toggleClass('hide_me');
+
+ },
+
+ toggleExtraFacets : function () {
+ dojo.query(this.extraFacetFields).toggleClass('hide_me');
+ this.extraHidden = !this.extraHidden;
+ this.extraHidden ? this.toggleExtraFacetFields.setLabel(this.nls.more) : this.toggleExtraFacetFields.setLabel(this.nls.less);
+ },
+
+ undoSearch : function (value) {
+ var sb = dojo.byId(this.searchBox);
+ sb.value = sb.value.replace(this.facet.field_class + '|' + this.facet.name + '[' + value + ']','');
+ dojo.byId(this.searchSubmit).click();
+ },
+
+ doSearch : function (value) {
+ dojo.byId(this.searchBox).value += ' ' + this.facet.field_class + '|' + this.facet.name + '[' + value + ']';
+ dojo.byId(this.searchSubmit).click();
+ }
+ }
+ );
+
+
+}
+
--- /dev/null
+/* ---------------------------------------------------------------------------
+ * Copyright (C) 2010 Equinox Software, Inc
+ * Mike Rylander <miker@esilibrary.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ * ---------------------------------------------------------------------------
+ */
+
+if(!dojo._hasResource["openils.widget.Searcher"]) {
+
+ dojo._hasResource["openils.widget.Searcher"] = true;
+ dojo.provide("openils.widget.Searcher");
+
+ dojo.require("fieldmapper.AutoIDL");
+ dojo.require("openils.I18N");
+ dojo.require("fieldmapper.dojoData");
+ dojo.require("DojoSRF");
+ dojo.require("dojo.data.ItemFileReadStore");
+ dojo.require("dijit._Widget");
+ dojo.require("dijit._Templated");
+ dojo.require("dijit.form.Button");
+ dojo.require("dijit.form.TextBox");
+ dojo.require("dijit.form.FilteringSelect");
+ dojo.requireLocalization("openils.widget", "Searcher");
+
+ fieldmapper.IDL.load(['cmf','cmc','cmsa']);
+
+//------ searching wrapper, uses dijits below -----------------------------------------------
+
+ dojo.declare(
+ 'openils.widget.Searcher',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString :
+"<div dojoAttachPoint='searcherTopNode'>" +
+
+" <div dojoAttachPoint='deck'>" +
+" <div dojoAttachPoint='basicSearch'>" +
+" <span dojoAttachPoint='containerNode' class='searcherSimpleSearchWrapper'></span>" +
+" </div>" +
+
+" <div dojoAttachPoint='advSearch' class='hide_me searcherAdvancedSearchWrapper'>" +
+" <div dojoAttachPoint='searcherClassedSearchesContainer' class='searcherClassedSearchesContainer hide_me'>" +
+" <div dojoAttachPoint='classedSearches' class='searcherClassedSearches'>" +
+" <span dojoAttachPoint='searcherClassedSearchesLabel' class='searcherClassedSearchesLabel'></span>" +
+" </div>" +
+" <div class='searcherClassedSearchesAddContainer'>" +
+" <button dojoType='dijit.form.Button' dojoAttachPoint='andClassedSearch' dojoAttachEvent='onClick:addClassAnd'></button>" +
+" <button dojoType='dijit.form.Button' dojoAttachPoint='orClassedSearch' dojoAttachEvent='onClick:addClassOr'></button>" +
+" </div>" +
+" </div>" +
+
+" <div dojoAttachPoint='searcherFacetedSearchesContainer' class='searcherFacetedSearchesContainer hide_me'>" +
+" <div class='searcherFacetedSearches' dojoAttachPoint='facetedSearches'>" +
+" <span dojoAttachPoint='searcherFacetedSearchesLabel' class='searcherFacetedSearchesLabel'></span>" +
+" </div>" +
+" <span>" +
+" <button dojoType='dijit.form.Button' dojoAttachPoint='addFacetedSearch' dojoAttachEvent='onClick:addFacet'></button>" +
+" </span>" +
+" </div>" +
+
+" <div dojoAttachPoint='searcherFilterModifierContainer' class='searcherFilterModifierContainer hide_me'>" +
+" <table width='100%'><tbody><tr>" +
+" <td dojoAttachPoint='searcherFilterContainer' class='searcherFilterContainer hide_me' valign='top' width='50%'>" +
+" <div dojoAttachPoint='filters'>" +
+" <span dojoAttachPoint='searcherFiltersLabel' class='searcherFiltersLabel'></span>" +
+" </div>" +
+" <button dojoType='dijit.form.Button' dojoAttachPoint='addFilterButton' dojoAttachEvent='onClick:addFilter'></button>" +
+" </td>" +
+" <td dojoAttachPoint='searcherModifierContainer' class='searcherModifierContainer hide_me' valign='top' width='50%'>" +
+" <div dojoAttachPoint='modifiers'>" +
+" <span dojoAttachPoint='searcherModifiersLabel' class='searcherModifiersLabel'></span>" +
+" </div>" +
+" <button dojoType='dijit.form.Button' dojoAttachPoint='addModifierButton' dojoAttachEvent='onClick:addModifier'></button>" +
+" </td>" +
+" </tr></tbody></table>" +
+" </div>" +
+
+" <div class='searcherGoContainer'>" +
+" <span dojoType='dijit.form.Button' dojoAttachPoint='goButton' dojoAttachEvent='onClick:performSearch'></span>" +
+" </div>" +
+" </div>" +
+" </div>" +
+
+" <div class='searcherDeckSwapContainer'>" +
+" <span dojoType='dijit.form.Button' dojoAttachPoint='advToggle' dojoAttachEvent='onClick:swapDeck'></span>" +
+" </div>" +
+"</div>",
+ widgetsInTemplate: true,
+ advanced : false,
+ basicTextBox : '',
+ facetTextBox : '',
+ withClassedSearches : true,
+ withFacetedSearches : false,
+ withFiltersModifiers : false,
+ withFilters : false,
+ withModifiers : false,
+ basic_query : '',
+ facet_query : '',
+
+ compileFullSearch : function () {
+ if (!this.advanced) return dojo.byId( this.basicTextBox ).attr('value');
+
+ var query = '';
+
+ var first_cs = true;
+
+ // First, classed searches
+ dojo.query( '.classedSearch', this.classedSearches ).forEach(
+ function (csearch) {
+ csearch = dijit.byNode(csearch);
+ var part = csearch.searchValue.attr('value');
+ if (!part || part.match(/^\s+$/)) return;
+
+ if (first_cs) first_cs = false;
+ else query += csearch.anded ? '' : ' ||';
+
+ query += ' ' + csearch.matchIndex.attr('value') + ':';
+ if (csearch.matchType.attr('value') == 'exact') {
+ query += '"';
+ } else if (csearch.matchType.attr('value') == 'notcontains') {
+ part = '-' + part.replace(/\s+/g, ' -');
+ }
+
+ query += part;
+
+ if (csearch.matchType.attr('value') == 'exact') query += '"';
+ }
+ );
+
+ var fquery = '';
+ // Now facets
+ dojo.query( '.facetedSearch', this.facetedSearches ).forEach(
+ function (facet) {
+ facet = dijit.byNode(facet);
+ var part = facet.searchValue.attr('value');
+ if (!part || part.match(/^\s+$/)) return;
+ fquery += ' ' + facet.matchIndex.attr('value') + '[' + part + ']';
+ }
+ );
+
+ // and filters...
+ dojo.query( '.filter', this.filters ).forEach(
+ function (filt) {
+ filt = dijit.byNode(filt);
+ var part = filt.valueList.attr('value');
+ if (!part || part.match(/^\s+$/) || filt.filterSelect.attr('value') == '-') return;
+ query += ' ' + filt.filterSelect.attr('value') + '(' + part + ')';
+ }
+ );
+
+ // finally, modifiers
+ dojo.query( '.modifier', this.modifiers ).forEach(
+ function (modifier) {
+ modifier = dijit.byNode(modifier);
+ var part = modifier.modifierSelect.attr('value')
+ if (!part || part == '-') return;
+ query += ' #' + part;
+ }
+ );
+
+
+ this.basic_query = query;
+ this.facet_query = fquery;
+
+ return query;
+ },
+
+ addFilter : function () {
+ return new openils.widget.Searcher.filter({}, dojo.create('div',null,this.filters));
+ },
+
+ addModifier : function () {
+ return new openils.widget.Searcher.modifier({}, dojo.create('div',null,this.modifiers));
+ },
+
+ addClassAnd : function () {
+ return new openils.widget.Searcher.classedSearch({}, dojo.create('div',null,this.classedSearches));
+ },
+
+ addClassOr : function () {
+ return new openils.widget.Searcher.classedSearch({anded:false}, dojo.create('div',null,this.classedSearches));
+ },
+
+ addFacet : function () {
+ return new openils.widget.Searcher.facetedSearch({}, dojo.create('div',null,this.facetedSearches));
+ },
+
+ performSearch : function () {},
+ populate : function () {},
+
+ startup : function () {
+ if (this.advanced) {
+ dojo.query(this.basicSearch).toggleClass('hide_me');
+ dojo.query(this.advSearch).toggleClass('hide_me');
+ }
+
+ if (!this.facetTextBox) this.facetTextBox = this.basicTextBox;
+
+ if (this.withFiltersModifiers) {
+ this.withFilters = true;
+ this.withModifiers = true;
+ } else if (this.withFilters || this.withModifiers) {
+ this.withFiltersModifiers = true;
+ }
+
+ if (this.withFiltersModifiers) dojo.query(this.searcherFilterModifierContainer).toggleClass('hide_me');
+ if (this.withFilters) dojo.query(this.searcherFilterContainer).toggleClass('hide_me');
+ if (this.withModifiers) dojo.query(this.searcherModifierContainer).toggleClass('hide_me');
+ if (this.withFacetedSearches) dojo.query(this.searcherFacetedSearchesContainer).toggleClass('hide_me');
+ if (this.withClassedSearches) dojo.query(this.searcherClassedSearchesContainer).toggleClass('hide_me');
+
+ this.populate();
+ this.inherited(arguments)
+ },
+
+ swapDeck : function () {
+ if (this.advanced) this.advanced = false;
+ else this.advanced = true;
+
+ dojo.query(this.basicSearch).toggleClass('hide_me');
+ dojo.query(this.advSearch).toggleClass('hide_me');
+
+ if (this.advanced) this.advToggle.setLabel(this.nls.basic);
+ else this.advToggle.setLabel(this.nls.advanced);
+ },
+
+ postCreate : function () {
+ this.nls = dojo.i18n.getLocalization("openils.widget", "Searcher");
+
+ this.searcherClassedSearchesLabel.innerHTML = this.nls.classed_searches;
+ this.searcherFacetedSearchesLabel.innerHTML = this.nls.faceted_searches;
+ this.searcherFiltersLabel.innerHTML = this.nls.filters;
+ this.searcherModifiersLabel.innerHTML = this.nls.modifiers;
+ this.addFacetedSearch.setLabel(this.nls.new_facet);
+
+ this.andClassedSearch.setLabel(this.nls.and);
+ this.orClassedSearch.setLabel(this.nls.or);
+
+ this.addFilterButton.setLabel(this.nls.new_filter);
+ this.addModifierButton.setLabel(this.nls.new_modifier);
+
+ this.goButton.setLabel(this.nls.perform_search);
+
+ if (this.advanced) this.advToggle.setLabel(this.nls.basic);
+ else this.advToggle.setLabel(this.nls.advanced);
+
+ new openils.widget.Searcher.classedSearch(
+ { noRemove : true },
+ dojo.create('div',null,this.classedSearches)
+ );
+ }
+
+ }
+ );
+
+ openils.widget.Searcher._cache = {arr : {}, obj : {}, store : {}};
+
+ dojo.forEach(
+ [ {ident:'name',classname:'cmc',label:'label'}, {ident:'id',classname:'cmf',label:'label'}, {ident:'alias',classname:'cmsa',label:'alias'} ],
+ function (c) {
+
+ var q = {};
+ q[c.ident] = { '!=' : null };
+
+ var fielder_result = fieldmapper.standardRequest(
+ [ 'open-ils.fielder', 'open-ils.fielder.'+c.classname+'.atomic'],
+ [ { query : q } ]
+ );
+
+ var sorted_fielder_result = fielder_result.sort( function(a,b) {
+ if(a[c.label] > b[c.label]) return 1;
+ if(a[c.label] < b[c.label]) return -1;
+ return 0;
+ });
+
+ openils.widget.Searcher._cache.arr[c.classname] = sorted_fielder_result;
+
+ var list = [];
+ openils.widget.Searcher._cache.obj[c.classname] = {};
+
+ dojo.forEach(
+ openils.widget.Searcher._cache.arr[c.classname],
+ function (x) {
+ openils.widget.Searcher._cache.obj[c.classname][x[c.ident]] = x;
+ list.push(x);
+ }
+ );
+
+ openils.widget.Searcher._cache.store[c.classname] = new dojo.data.ItemFileReadStore( { data : {identifier : c.ident, label : c.label, items : list } } );
+ }
+ );
+
+ var facet_list = [];
+ var search_list = [];
+
+ dojo.forEach(
+ openils.widget.Searcher._cache.arr.cmc,
+ function (cmc_obj) {
+ search_list.push({
+ name : cmc_obj.name,
+ label : cmc_obj.label
+ });
+ dojo.forEach(
+ dojo.filter(
+ openils.widget.Searcher._cache.arr.cmf,
+ function (x) {
+ if (x.field_class == cmc_obj.name) return 1;
+ return 0;
+ }
+ ),
+ function (cmf_obj) {
+ if (cmf_obj.search_field == 't') {
+ search_list.push({
+ name : cmc_obj.name + '|' + cmf_obj.name,
+ label : ' -- ' + cmf_obj.label
+ });
+ }
+ if (cmf_obj.facet_field == 't') {
+ facet_list.push({
+ name : cmc_obj.name + '|' + cmf_obj.name,
+ label : cmc_obj.label + ' : ' + cmf_obj.label
+ });
+ }
+ }
+ )
+ }
+ );
+
+ openils.widget.Searcher.facetStore = new dojo.data.ItemFileReadStore( { data : {identifier : 'name', label : 'label', items : facet_list} } );
+ openils.widget.Searcher.searchStore = new dojo.data.ItemFileReadStore( { data : {identifier : 'name', label : 'label', items : search_list} } );
+
+//------ modifiers template -----------------------------------------------
+
+ dojo._hasResource["openils.widget.Searcher.modifier"] = true;
+ dojo.provide("openils.widget.Searcher.modifier");
+
+ dojo.declare(
+ 'openils.widget.Searcher.modifier',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString :
+'<table dojoAttachPoint="myTop" class="modifier"><tbody><tr>' +
+' <td>' +
+' <select value="-" name="modifierSelect" dojoAttachPoint="modifierSelect" dojoType="dijit.form.FilteringSelect" >' +
+' <option dojoAttachPoint="modifierDefault" value="-">-- Select a Modifier --</option>' +
+' <option dojoAttachPoint="modifierAvailable" value="available"></option>' +
+' <option dojoAttachPoint="modifierDescending" value="descending"></option>' +
+' <option dojoAttachPoint="modifierAscending" value="ascending"></option>' +
+' <option dojoAttachPoint="modifierMetabib" value="metabib"></option>' +
+' <option dojoAttachPoint="modifierStaff" value="staff"></option>' +
+' </select>' +
+' </td> ' +
+' <td dojoAttachPoint="removeWrapper"><span dojoType="dijit.form.Button" dojoAttachPoint="removeButton" dojoAttachEvent="onClick:killMe"></span></td> ' +
+'</tr></tbody></table>',
+ widgetsInTemplate: true,
+
+ postCreate : function () {
+ this.nls = dojo.i18n.getLocalization("openils.widget", "Searcher");
+
+ this.modifierDefault.innerHTML = this.nls.modifier_default;
+ this.modifierAvailable.innerHTML = this.nls.available;
+ this.modifierDescending.innerHTML = this.nls.descending;
+ this.modifierAscending.innerHTML = this.nls.ascending;
+ this.modifierMetabib.innerHTML = this.nls.metabib;
+ this.modifierStaff.innerHTML = this.nls.staff;
+
+ this.removeButton.setLabel(this.nls.remove);
+ },
+
+ killMe : function () {
+ dijit.byNode(this.myTop).destroyRecursive();
+ this.destroy();
+ }
+ }
+ );
+
+//------ filters template -----------------------------------------------
+
+ dojo._hasResource["openils.widget.Searcher.filter"] = true;
+ dojo.provide("openils.widget.Searcher.filter");
+
+ dojo.declare(
+ 'openils.widget.Searcher.filter',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString :
+'<table dojoAttachPoint="myTop" class="filter"><tbody><tr>' +
+' <td>' +
+' <select value="-" name="filterSelect" dojoAttachPoint="filterSelect" dojoType="dijit.form.FilteringSelect">' +
+' <option dojoAttachPoint="filterDefault" value="-">-- Select a Filter --</option>' +
+' <option dojoAttachPoint="filterSite" value="site">Site</option>' +
+' <option dojoAttachPoint="filterDepth" value="depth">Search Depth</option>' +
+' <option dojoAttachPoint="filterSort" value="sort">Sort Axis</option>' +
+' <option dojoAttachPoint="filterStatuses" value="statuses">Statuses</option>' +
+' <option dojoAttachPoint="filterAudience" value="audience">Audience</option>' +
+' <option dojoAttachPoint="filterBefore" value="before">Published Before</option>' +
+' <option dojoAttachPoint="filterAfter" value="after">Published After</option>' +
+' <option dojoAttachPoint="filterBetween" value="between">Published Between</option>' +
+' <option dojoAttachPoint="filterDuring" value="during">In Publication</option>' +
+' <option dojoAttachPoint="filterForm" value="item_form">Form</option>' +
+' <option dojoAttachPoint="filterType" value="item_type">Type</option>' +
+' <option dojoAttachPoint="filterTypeForm" value="format">Type and Form</option>' +
+' <option dojoAttachPoint="filterVRFormat" value="vr_format">Videorecording Format</option>' +
+' <option dojoAttachPoint="filterLitForm" value="lit_form">Literary Form</option>' +
+' <option dojoAttachPoint="filterBibLevel" value="bib_level">Bibliographic Level</option>' +
+' </select>' +
+' </td> ' +
+' <td><div dojoAttachPoint="valueList" dojoType="dijit.form.TextBox"></div></td> ' +
+' <td dojoAttachPoint="removeWrapper"><span dojoType="dijit.form.Button" dojoAttachPoint="removeButton" dojoAttachEvent="onClick:killMe"></span></td> ' +
+'</tr></tbody></table>',
+ widgetsInTemplate: true,
+
+ postCreate : function () {
+ this.nls = dojo.i18n.getLocalization("openils.widget", "Searcher");
+
+ this.filterDefault.innerHTML = this.nls.filter_default;
+ this.filterSite.innerHTML = this.nls.site;
+ this.filterDepth.innerHTML = this.nls.depth;
+ this.filterSort.innerHTML = this.nls.sort;
+ this.filterStatuses.innerHTML = this.nls.statuses;
+ this.filterAudience.innerHTML = this.nls.audience;
+ this.filterBefore.innerHTML = this.nls.before;
+ this.filterAfter.innerHTML = this.nls.after;
+ this.filterBetween.innerHTML = this.nls.between;
+ this.filterDuring.innerHTML = this.nls.during;
+ this.filterForm.innerHTML = this.nls.item_form;
+ this.filterType.innerHTML = this.nls.item_type;
+ this.filterTypeForm.innerHTML = this.nls.format;
+ this.filterVRFormat.innerHTML = this.nls.vr_format;
+ this.filterLitForm.innerHTML = this.nls.lit_form;
+ this.filterBibLevel.innerHTML = this.nls.bib_level;
+
+ this.removeButton.setLabel(this.nls.remove);
+ },
+
+ killMe : function () {
+ dijit.byNode(this.myTop).destroyRecursive();
+ this.destroy();
+ }
+ }
+ );
+
+//------ facet search template -----------------------------------------------
+
+ dojo._hasResource["openils.widget.Searcher.facetedSearch"] = true;
+ dojo.provide("openils.widget.Searcher.facetedSearch");
+
+ dojo.declare(
+ 'openils.widget.Searcher.facetedSearch',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString :
+'<table dojoAttachPoint="myTop" class="facetedSearch"><tbody><tr>' +
+' <td><div dojoAttachPoint="matchIndex" searchAttr="label" dojoType="dijit.form.FilteringSelect" store="openils.widget.Searcher.facetStore"></div></td> ' +
+' <td><span style="margin-left:10px; margin-right:10px;" dojoAttachPoint="exactOption"></span></td> ' +
+' <td><div dojoAttachPoint="searchValue" dojoType="dijit.form.TextBox"></div></td> ' +
+' <td dojoAttachPoint="removeWrapper"><span dojoType="dijit.form.Button" dojoAttachPoint="removeButton" dojoAttachEvent="onClick:killMe"></span></td> ' +
+'</tr></tbody></table>',
+ widgetsInTemplate: true,
+
+ noRemove : false,
+
+ postCreate : function () {
+ this.nls = dojo.i18n.getLocalization("openils.widget", "Searcher");
+
+ this.exactOption.innerHTML = this.nls.exact;
+ this.removeButton.setLabel(this.nls.remove);
+
+ if (this.noRemove) dojo.destroy(this.removeWrapper);
+ },
+
+ killMe : function () {
+ dijit.byNode(this.myTop).destroyRecursive();
+ this.destroy();
+ }
+ }
+ );
+
+//------ classed search template -----------------------------------------------
+
+ dojo._hasResource["openils.widget.Searcher.classedSearch"] = true;
+ dojo.provide("openils.widget.Searcher.classedSearch");
+
+ dojo.declare(
+ 'openils.widget.Searcher.classedSearch',
+ [dijit._Widget, dijit._Templated],
+ {
+
+ templateString :
+'<table dojoAttachPoint="myTop" class="classedSearch"><tbody><tr>' +
+' <td colspan="4" align="center"><span dojoAttachPoint="joinerSpan"></span></td></tr><tr> ' +
+' <td><div dojoAttachPoint="matchIndex" value="keyword" searchAttr="label" dojoType="dijit.form.FilteringSelect" store="openils.widget.Searcher.searchStore"></div></td> ' +
+' <td>' +
+' <select dojoAttachPoint="matchType" dojoType="dijit.form.FilteringSelect" name="matchType">' +
+' <option dojoAttachPoint="containsOption" value="contains">Contains</option>' +
+' <option dojoAttachPoint="notContainsOption" value="notcontains">Does Not Contain</option>' +
+' <option dojoAttachPoint="exactOption" value="exact"> Matches Exactly</option>' +
+' </select>' +
+' </td> ' +
+' <td><div dojoAttachPoint="searchValue" dojoType="dijit.form.TextBox"></div></td> ' +
+' <td dojoAttachPoint="removeWrapper"><span dojoType="dijit.form.Button" dojoAttachPoint="removeButton" dojoAttachEvent="onClick:killMe"></span></td> ' +
+'</tr></tbody></table>',
+ widgetsInTemplate: true,
+
+ anded : true,
+ noRemove : false,
+
+ postCreate : function () {
+ this.nls = dojo.i18n.getLocalization("openils.widget", "Searcher");
+
+ this.containsOption.innerHTML = this.nls.contains;
+ this.notContainsOption.innerHTML = this.nls.notcontains;
+ this.exactOption.innerHTML = this.nls.exact;
+
+ this.removeButton.setLabel(this.nls.remove);
+
+ if (this.noRemove) dojo.destroy(this.removeWrapper);
+ if (!this.noRemove && this.anded) this.joinerSpan.innerHTML = this.nls.and;
+ if (!this.noRemove && !this.anded) this.joinerSpan.innerHTML = this.nls.or;
+ },
+
+ killMe : function () {
+ dojo.destroy(this.myTop);
+ this.destroy();
+ }
+ }
+ );
+
+
+}
--- /dev/null
+{
+ and : '&&',
+ or : '||',
+ more : 'More...',
+ less : '...Less',
+ classed_searches : 'Classed Searches',
+ faceted_searches : 'Facets',
+ filters : 'Filters',
+ modifiers : 'Modifiers',
+ new_facet : 'New Facet',
+ new_filter : 'New Filter',
+ new_modifier : 'New Modifier',
+ remove : 'Remove',
+ advanced : 'Advanced',
+ basic : 'Basic',
+ perform_search : 'Go!',
+ contains : 'Contains',
+ notcontains : 'Does Not Contain',
+ exact : 'Exactly Matches',
+ modifier_default : '-- Select a Modifier --',
+ available : 'Available',
+ descending : 'Sort Descending',
+ ascending : 'Sort Ascending',
+ metabib : 'Metarecord Search',
+ staff : 'Staff Search',
+ filter_default : '-- Select a Filter --',
+ site : 'Site',
+ depth : 'Search Depth',
+ sort : 'Sort Axis',
+ statuses : 'Statuses',
+ audience : 'Audience',
+ before : 'Published Before',
+ after : 'Published After',
+ between : 'Published Between',
+ during : 'In Publication',
+ item_form : 'Form',
+ item_type : 'Type',
+ format : 'Type and Form',
+ vr_format : 'Videorecording Format',
+ lit_form : 'Literary Form',
+ bib_level : 'Bibliographic Level'
+}
/* URL param names */
var PARAM_TERM = "t"; /* search term */
+var PARAM_FACET = "ft"; /* facet term */
var PARAM_STYPE = "tp"; /* search type */
var PARAM_LOCATION = "l"; /* current location */
var PARAM_LASSO = "sg"; /* current location */
/* URL param values (see comments above) */
var TERM;
+var FACET;
var STYPE;
var LOCATION;
var LASSO;
if(isNaN(DEPTH)) DEPTH = null;
+ FACET = cgi.param(PARAM_FACET);
TERM = cgi.param(PARAM_TERM);
STYPE = cgi.param(PARAM_STYPE);
FORM = cgi.param(PARAM_FORM);
/* URL param accessors */
function getTerm(){return TERM;}
+function getFacet(){return FACET;}
function getStype(){return STYPE;}
function getLocation(){return LOCATION;}
function getLasso(){return LASSO;}
string += _appendParam(ORIGLOC, PARAM_ORIGLOC, args, getOrigLocation, string);
if(getTerm())
string += _appendParam(TERM, PARAM_TERM, args, getTerm, string);
+ if(getFacet())
+ string += _appendParam(FACET, PARAM_FACET, args, getFacet, string);
if(getStype())
string += _appendParam(STYPE, PARAM_STYPE, args, getStype, string);
if(getLocation() != 1)
function buildSearchLink(type, string, linknode, trunc) {
if(!trunc) trunc = 65;
var args = {};
- if( SHOW_MR_DEFAULT) {
+ if( SHOW_MR_DEFAULT || findCurrentPage() == MRESULT ) {
args.page = MRESULT;
} else {
args.page = RRESULT;
<!ENTITY navigate.loggedinas.title "Logged in as...">
<!ENTITY navigate.titleGroupResults "My Search Results">
<!ENTITY navigate.titleResults "My Title Results">
+<!ENTITY navigate.facetRefine "Refine your search">
<!ENTITY navigate.title.details "My Title Details">
<!ENTITY navigate.record.details "Record Details">
breq.callback( rdetailCheckDeleted );
breq.send();
- resultBuildCaches( [ record ] );
- resultDrawSubjects();
- resultDrawSeries();
+ //resultBuildCaches( [ record ] );
+ //resultDrawSubjects();
+ //resultDrawSeries();
// grab added content
G.evt.result.hitCountReceived.push(resultSetHitInfo);
G.evt.result.recordReceived.push(resultDisplayRecord, resultAddCopyCounts);
G.evt.result.copyCountsReceived.push(resultDisplayCopyCounts);
- G.evt.result.allRecordsReceived.push(resultBuildCaches, resultDrawSubjects,
- resultDrawAuthors, resultDrawSeries, function(){unHideMe($('result_info_2'))},
- fetchGoogleBooksLink,fetchChiliFreshReviews);
+ G.evt.result.allRecordsReceived.push( function(){unHideMe($('result_info_2'))}, fetchGoogleBooksLink, fetchChiliFreshReviews);
attachEvt('result','lowHits',resultLowHits);
attachEvt('result','zeroHits',resultZeroHits);
if(getAvail()) args.available = 1;
+ if(getFacet()) args.facets = getFacet();
+
if(getAudience()) args.audience = getAudience().split(/,/);
if(getLitForm()) args.lit_form = getLitForm().split(/,/);
if(getLanguage()) args.language = getLanguage().split(/,/);
/* set up the selector objects, etc */
G.ui.searchbar.text.value = (getTerm() != null) ? getTerm() : "";
+ if (!isFrontPage) G.ui.searchbar.facets.value = (getFacet() != null) ? getFacet() : "";
setSelector(_ts, getStype());
setSelector(_fs, getForm());
function searchBarSubmit(isFilterSort) {
var text = G.ui.searchbar.text.value;
+ var facet_text = isFrontPage ? '' : G.ui.searchbar.facets.value;
clearSearchParams();
var args = {};
- if(SHOW_MR_DEFAULT || (isFilterSort && findCurrentPage() == MRESULT)) {
+ if(SHOW_MR_DEFAULT || findCurrentPage() == MRESULT) {
args.page = MRESULT;
} else {
args.page = RRESULT;
args[PARAM_STYPE] = _ts.options[_ts.selectedIndex].value;
args[PARAM_TERM] = text;
+ args[PARAM_FACET] = facet_text;
args[PARAM_LOCATION] = depthSelGetNewLoc();
args[PARAM_DEPTH] = d;
args[PARAM_FORM] = _fs.options[_fs.selectedIndex].value;
}
function sidebarTreesFree() {
+/*
removeChildren($(subjectSidebarTree.rootid));
removeChildren($(authorSidebarTree.rootid));
removeChildren($(seriesSidebarTree.rootid));
subjectSidebarTree = null;
authorSidebarTree = null;
seriesSidebarTree = null;
+*/
}
dojo.require("dojo.date.locale");
dojo.require("dojo.date.stamp");
dojo.require("dojo.parser");
- dojo.require("openils.I18N");
+ dojo.require("openils.widget.FacetSidebar"); // pulls in Searcher and I18N
</script>
<!-- Searchbar for doing metarecord searches -->
-<div id='searchbar'>
+<div id='searchbar' dojoType="openils.widget.Searcher" basicTextBox='search_box'>
+ <script type='dojo/method' event='performSearch'>
+ this.compileFullSearch();
+ dojo.byId(this.basicTextBox).value = this.basic_query;
+ dojo.byId(this.facetTextBox).value += this.facet_query;
+ dojo.byId('search_submit').click();
+ </script>
+ <script type='dojo/method' event='populate'><![CDATA[
+ var searcher = this;
+ attachEvt("result", "allRecordsReceived", function () {
+ if(!resultCompiledSearch) {
+ return;
+ }
+
+ var all_search = dojo.query( '.classedSearch', searcher.classedSearches );
+ if (all_search.length > 1) {
+ for (var i = 1; i < all_search.length; i++) {
+ dojo.destroy(all_search[i]);
+ }
+ }
+
+ var csearch = dijit.byNode(dojo.query( '.classedSearch', searcher.classedSearches )[0]);
+
+ for (var type in resultCompiledSearch.searches) {
+ csearch.matchIndex.attr('value',type);
+ csearch.searchValue.attr('value',resultCompiledSearch.searches[type].term);
+ csearch = searcher.addClassAnd();
+ }
+ });
+ ]]></script>
+
<!-- load my js -->
<script language='javascript' type='text/javascript'>
config.ids.searchbar = {};
config.css.searchbar = {};
config.ids.searchbar.text = 'search_box';
+ config.ids.searchbar.facets = 'facet_box';
config.ids.searchbar.submit = 'search_submit';
config.ids.searchbar.type_selector = 'search_type_selector';
config.ids.searchbar.depth_selector = 'depth_selector';
<td nowrap='nowrap' align='center' class='search_box_container color_2'>
- <input id='search_box' type='text' />
+ <input id='search_box' type='text' onkeyup='dojo.byId("facet_box").value = "";'/>
+ <input id='facet_box' type='hidden' />
<span style='padding-left: 6px;'>
<input type='button' style='width: 40px;' id='search_submit' value='&button.go;' />
</span>
</div>
</div>
- <div id='subject_tree_sidebar' class='sidebar_chunk hide_me' style='margin-top: 12px;'>
- <div id='subject_sidebar_tree_div'> </div>
- <script language='javascript' type='text/javascript'>
- removeChildren($('subject_sidebar_tree_div'));
- var subjectSidebarTree = new SlimTree(
- document.getElementById('subject_sidebar_tree_div'),
- 'subjectSidebarTree', '../../../../images/slimtree/related.jpg');
- subjectSidebarTree.addNode( 'subjectSidebarTreeRoot', -1,
- "&sidebar.relevantSubjects.headerLabel;",
- 'javascript:subjectSidebarTree.toggle(' +
- '"subjectSidebarTreeRoot");');
- </script>
- </div>
+ <div id='facetSidebarContainer' class='hide_me'>
- <div id='author_tree_sidebar' class='sidebar_chunk hide_me'>
- <hr/>
- <div id='author_sidebar_tree_div'> </div>
- <script language='javascript' type='text/javascript'>
- removeChildren($('author_sidebar_tree_div'));
- var authorSidebarTree = new SlimTree(
- document.getElementById('author_sidebar_tree_div'),
- 'authorSidebarTree','../../../../images/slimtree/people.jpg');
- authorSidebarTree.addNode( 'authorSidebarTreeRoot', -1,
- "&sidebar.relevantAuthors.headerLabel;",
- 'javascript:authorSidebarTree.toggle(' +
- '"authorSidebarTreeRoot");');
- </script>
+ <div class="side_bar_item" style="margin-top: 10px; font-weight: bold;">
+ <span>&navigate.facetRefine;</span>
</div>
- <div id='series_tree_sidebar' class='sidebar_chunk hide_me'>
- <hr/>
- <div id='series_sidebar_tree_div'> </div>
- <script language='javascript' type='text/javascript'>
- removeChildren($('series_sidebar_tree_div'));
- var seriesSidebarTree = new SlimTree(
- document.getElementById('series_sidebar_tree_div'),
- 'seriesSidebarTree',
- '../../../../images/slimtree/houses.jpg');
- seriesSidebarTree.addNode( 'seriesSidebarTreeRoot', -1,
- "&sidebar.relevantSeries.headerLabel;",
- 'javascript:seriesSidebarTree.toggle(' +
- '"seriesSidebarTreeRoot");');
- </script>
+ <div dojoType='openils.widget.FacetSidebar' searchBox='facet_box' searchSubmit='search_submit' facetLimit='5' classOrder='["author","subject","series","title","keyword"]'>
+ <script type='dojo/method' event='populate'><![CDATA[
+ var fblob = this;
+ attachEvt("result", "allRecordsReceived", function () {
+ if(!resultFacetKey) return;
+ if (fblob.facetCacheKey) return; // already rendered it
+
+ dojo.removeClass('facetSidebarContainer','hide_me');
+
+ fblob.facetCacheKey = resultFacetKey;
+ fblob.render();
+ });
+ ]]></script>
+ </div>
</div>
<div id='adv_quick_search_sidebar' class='sidebar_chunk hide_me'
config.ids.sidebar.loginbox = 'login_link_div';
config.ids.sidebar.logged_in_as = 'logged_in_as_div';
config.ids.sidebar.username_dest = 'username_dest';
- config.ids.sidebar.subject = 'subject_sidebar';
- config.ids.sidebar.subject_item = 'subject_item';
- config.ids.sidebar.author = 'author_sidebar';
- config.ids.sidebar.author_item = 'author_item';
- config.ids.sidebar.series = 'series_sidebar';
- config.ids.sidebar.series_item = 'series_item';
config.ids.sidebar.home_link = 'home_link'
config.ids.sidebar.advanced_link = 'advanced_link'
config.ids.sidebar.myopac_link = 'myopac_link'
- config.names.sidebar.subject_item = 'subject_item';
- config.names.sidebar.author_item = 'author_item';
- config.names.sidebar.series_item = 'series_item';
-
config.css.encircled = 'encircled';
</script>
var out = '';
var list = dojo.query( 'subfield', item );
for (var i = 0; i < list.length; i++) {
- out += dojox.data.dom.textContent(list[i]) + ' ';
+ out += BT.textContent(list[i]) + ' ';
}
return out;
]]></script>
var output = [];
var list = dojo.query( 'subfield', item );
for (var i =0; i < list.length; i++) {
- total += dojox.data.dom.textContent(list[i]) + ' ';
+ total += BT.textContent(list[i]) + ' ';
var current = '<a href="rresult.xml?rt=subject&tp=subject&t=' + total;
for (var p in other_params) {
if (cgi.param(other_params[p]))
current += '&' + other_params[p] + '=' + cgi.param(other_params[p]);
}
- current += '">' + dojox.data.dom.textContent(list[i]) + '</a>'
+ current += '">' + BT.textContent(list[i]) + '</a>'
output.push(current);
}
return '<span>' + output.join(' -- ') + '</span><br/>';
.border_3_3 { border: 3px solid #E0F6E0; }
.border_4_3 { border: 3px solid #E0F0E0; }
-
-
+/* some facet styling */
+.facetClassContainer { margin: 2px; border: 1px solid #64EA4F; }
+.facetClassLabelContainer { background: #A7EA9D; border: 1px solid #A7EA9D; }
+.facetClassLabel { font-weight: bold; text-align: center; }
+.facetFieldContainer { background: #E0F6E0; }
+.facetFieldLabel { padding-left: 2px; margin-top: 5px; margin-bottom: 5px; font-weight: bold; text-align: left; }
+.extraFacetFieldsWrapper { }
+.toggleExtraFacetFieldsButton { float: right; margin: 0px; padding: 0px; }
+.facetFieldLineCount { display: inline-block; border-right: 1px solid #A7EA9D; color: gray; width: 3em; margin-right: 3px }
+.facetField { border-top: 1px solid #A7EA9D; }
+.facetFields { padding-left: 5px; }
+.facetFieldLineValue { overflow: hidden; text-overflow: ellipsis; }
+
+.searcherSimpleSearchWrapper {}
+.searcherAdvancedSearchWrapper { margin: 2px; border: 1px solid #64EA4F; }
+
+.searcherClassedSearchesContainer { margin: 5px; }
+.searcherClassedSearches {}
+.searcherClassedSearchesLabel { font-weight: bold; }
+
+.searcherClassedSearchesAddContainer { width: 50%; text-align: center; }
+
+.searcherFacetedSearchesContainer { margin: 5px; border-top: 1px solid black; }
+.searcherFacetedSearches {}
+.searcherFacetedSearchesLabel { font-weight: bold; }
+
+.searcherFilterModifierContainer { margin: 5px; border-top: 1px solid black; }
+
+.searcherFiltersLabel { font-weight: bold; }
+.searcherFilterContainer {}
+
+.searcherModifiersLabel { font-weight: bold; }
+.searcherModifierContainer {}
+
+.searcherGoContainer { width: 50%; text-align: right; }
+.searcherDeckSwapContainer {}
/* general purpose light borders */
.border_5 { border: 1px solid #D0D0D0; }