lot of things, including:
authorsenator <lebbeous@esilibrary.com>
Thu, 24 Feb 2011 23:11:04 +0000 (18:11 -0500)
committersenator <lebbeous@esilibrary.com>
Thu, 24 Feb 2011 23:11:04 +0000 (18:11 -0500)
- crib subjects support from regular opac poc
- get rid of adv search form inclusion on results page, but keep the link to
    it. Show a special version of just the "compiled" QP query
- better and more generic handling of search terms (compiling CGI params
    to QP string)
- make limit to avail and sort work from basic search results page
- genericize search cgi params -> qp. filter:foo, s/class/qtype/, etc
- more!

12 files changed:
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm
Open-ILS/web/css/skin/default/opac/style.css
Open-ILS/web/templates/default/opac/parts/advanced/global_row.tt2
Open-ILS/web/templates/default/opac/parts/advanced/search.tt2
Open-ILS/web/templates/default/opac/parts/audience_options.tt2 [deleted file]
Open-ILS/web/templates/default/opac/parts/audience_selector.tt2 [new file with mode: 0644]
Open-ILS/web/templates/default/opac/parts/format_selector.tt2
Open-ILS/web/templates/default/opac/parts/language_selector.tt2 [moved from Open-ILS/web/templates/default/opac/parts/item_lang_options.tt2 with 83% similarity]
Open-ILS/web/templates/default/opac/parts/record/summary.tt2
Open-ILS/web/templates/default/opac/parts/searchbar.tt2
Open-ILS/web/templates/default/opac/parts/stypes_selector.tt2
Open-ILS/web/templates/default/opac/results.tt2

index 199ef1e..025f9d6 100644 (file)
@@ -11,15 +11,17 @@ my $U = 'OpenILS::Application::AppUtils';
 sub _prepare_biblio_search_basics {
     my ($cgi) = @_;
 
+    return $cgi->param('query') unless $cgi->param('qtype');
+
     my %parts;
-    my @part_names = qw/class contains query/;
+    my @part_names = qw/qtype contains query/;
     $parts{$_} = [ $cgi->param($_) ] for (@part_names);
 
     my @chunks = ();
-    for (my $i = 0; $i < scalar @{$parts{'class'}}; $i++) {
-        my ($class, $contains, $query) = map { $parts{$_}->[$i] } @part_names;
+    for (my $i = 0; $i < scalar @{$parts{'qtype'}}; $i++) {
+        my ($qtype, $contains, $query) = map { $parts{$_}->[$i] } @part_names;
 
-        push(@chunks, $class . ':') unless $class eq 'keyword' and $i == 0;
+        push(@chunks, $qtype . ':') unless $qtype eq 'keyword' and $i == 0;
 
         # This stuff probably will need refined or rethought to better handle
         # the weird things Real Users will surely type in.
@@ -41,32 +43,16 @@ sub _prepare_biblio_search {
     my ($cgi, $ctx) = @_;
 
     my $query = _prepare_biblio_search_basics($cgi);
-    my $args = {};
-
-    $args->{'org_unit'} = $cgi->param('loc') || $ctx->{aou_tree}->()->id;
-    $args->{'depth'} = defined $cgi->param('depth') ?
-        $cgi->param('depth') :
-        $ctx->{find_aou}->($args->{'org_unit'})->ou_type->depth;
-
-    if (grep /available/, $cgi->param('modifier')) {
-        $query = '#available ' . $query;
-    }
 
-    if ($cgi->param('format')) {
-        $query .= ' format(' . join('', $cgi->param('format')) . ')';
-    }
+    $query = ('#' . $_ . ' ' . $query) foreach ($cgi->param('modifier'));
 
-    if ($cgi->param('lang')) {
-        # XXX TODO find out how to build query with multiple langs, if that
-        # even needs to be a feature of adv search.
-        $query .= ' lang:' . $cgi->param('lang');
+    foreach (grep /^fi:/, $cgi->param) {
+        /:(\w+)$/ or next;
+        my $term = join(",", $cgi->param($_));
+        $query .= " $1($term)" if length $term;
     }
 
-    if ($cgi->param('audience')) {
-        $query .= ' audience(' . join(',', $cgi->param('audience')) . ')';
-    }
-
-    if (defined $cgi->param('sort')) {
+    if ($cgi->param('sort')) {
         my ($axis, $desc) = split /\./, $cgi->param('sort');
         $query .= " sort($axis)";
         $query .= '#descending' if $desc;
@@ -86,7 +72,17 @@ sub _prepare_biblio_search {
         }
     }
 
-    return ($args, $query);
+    my $site = $cgi->param('loc') || $ctx->{aou_tree}->()->id;
+    if (defined($cgi->param('loc')) or not $query =~ /site\(\d+\)/) {
+        $query .= " site($site)";
+    }
+    if (defined($cgi->param('depth')) or not $query =~ /depth\(\d+\)/) {
+        my $depth = defined $cgi->param('depth') ?
+            $cgi->param('depth') : $ctx->{find_aou}->($site)->ou_type->depth;
+        $query .= " depth($depth)";
+    }
+
+    return $query;
 }
 
 # context additions: 
@@ -103,20 +99,35 @@ sub load_rresults {
     my $page = $cgi->param('page') || 0;
     my $facet = $cgi->param('facet');
     my $limit = $cgi->param('limit') || 10; # TODO user settings
+    my $offset = $page * $limit;
+
+    my $query = _prepare_biblio_search($cgi, $ctx);
+# XXX for now, we still put limit and offset into a hash rather than
+# right into the query string, because use of the limit() and offset() filters
+# in the query string doesn't actually work as advertised.
+#
+# When you do, with offsets > 0, you get wrong results in the 'count'
+# part of the result hash from open-ils.search.biblio.multiclass.query.
+#
+#    if (defined $cgi->param('limit') or not $query =~ /limit\(\d+\)/) {
+#        $query =~ s/ limit\(\d+\)//;
+#        $query .= " limit($limit)";
+#    }
+#    if (defined $cgi->param('page') or not $query =~ /offset\(\d+\)/) {
+#        $query =~ s/ offset\(\d+\)//;
+#        $query .= " offset($offset)";
+#    }
+    my $args = {'limit' => $limit, 'offset' => $offset};
 
-    my ($args, $query) = _prepare_biblio_search($cgi, $ctx);
 
     # Stuff these into the TT context so that templates can use them in redrawing forms
     $ctx->{processed_search_query} = $query;
-    $ctx->{processed_search_args} = $args;
-
-    $args->{'limit'} = $limit;
-    $args->{'offset'} = $page * $limit;
 
     $query = "$query $facet" if $facet; # TODO
 
     my $results;
 
+    $logger->info("LFW XXX: compiled query: q{$query}");
     try {
 
         my $method = 'open-ils.search.biblio.multiclass.query';
index 8577afd..0366017 100644 (file)
@@ -228,7 +228,7 @@ div.select-wrapper:hover {
 #search_box_wrapper {
        border:1px solid #e9ebf3;
        padding: 1px;
-       padding-left:3px;
+    padding-left: 3px;
 }
 
 #search-wrapper #breadcrumb {
@@ -656,7 +656,7 @@ div.select-wrapper:hover {
 }
 
 .results_header_sel {
-    width: 88px;
+    /* width: 88px; */
        float:left;
        position: relative;
        top: 2px;
index 6d65c68..f553218 100644 (file)
@@ -11,7 +11,7 @@
             <option value='exact'>[% l("Matches Exactly") %]</option>
         </select>
         <!-- search term -->
-        <input type='text' size='18' name='query' style='margin-right: 3px;' />
+        <input type='text' size='18' name='query' />
         <!-- Remove this row -->
         <a href="javascript:;"
             style="position:relative;top:1px; vertical-align: middle;"
index 72ca027..433b438 100644 (file)
             <td valign='top'>
                 <strong>[% l("Item Type") %]</strong><br />
                 [%  INCLUDE "default/opac/parts/format_selector.tt2"
-                        values=CGI.param("format")
                         multiple="multiple" size="4"
                         id="adv_global_item_type_basic" %]
             </td>
             <td valign='top'>
                 <strong>[% l("Language") %]</strong><br />
-                <select multiple='multiple' size='4' name="lang" id='adv_global_lang'>
-                    [% INCLUDE "default/opac/parts/item_lang_options.tt2"
-                        values=CGI.param("lang") %]
-                </select>
+                [%  INCLUDE "default/opac/parts/language_selector.tt2"
+                        multiple="multiple" size="4" %]
             </td>
             <td valign='top'>
                 <strong>[% l("Audience") %]</strong><br />
-                <select size='3' name="audience" multiple="multiple"
-                    id='adv_global_audience_basic'>
-                    [% INCLUDE "default/opac/parts/audience_options.tt2"
-                        values=CGI.param("audience") %]
+                    [% INCLUDE "default/opac/parts/audience_selector.tt2"
+                        id="adv_global_audience_basic"
+                        multiple="multiple" size="4" %]
                 </select>
                     <!--<a id='adv_global_audience_link_adv' class='classic_link adv_adv_link'
                         href='javascript:void(0);' onclick='
                                     [%  END; END %]
                             </select>    
                             <div style='margin-top:5px;'>
-                                <input id='adv_global_pub_date_1' name='date1' type='text' size='4' maxlength='4' />
+                                <input id='adv_global_pub_date_1' name='date1' type='text' size='4' maxlength='4' value="[% CGI.param('date1') | html %]" />
                                 <span id='adv_global_pub_date_2_span' class='[% CGI.param("pubdate") == "between" ? "" : "hide_me" %]'>
-                                   [% l("and") %] <input name='date2' id='adv_global_pub_date_2' type='text' size='4' maxlength='4'/>
+                                   [% l("and") %] <input name='date2' id='adv_global_pub_date_2' type='text' size='4' maxlength='4' value="[% CGI.param('date2') | html %]" />
                                 </span>
                             </div>
                         </td>
diff --git a/Open-ILS/web/templates/default/opac/parts/audience_options.tt2 b/Open-ILS/web/templates/default/opac/parts/audience_options.tt2
deleted file mode 100644 (file)
index 00e7790..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-[%
-FOR opt IN [
-    {'code' => 'a,b,c,j', 'label' => l("Juvenile")},
-    {'code' => 'd', 'label' => l("General")},
-    {'code' => 'e', 'label' => l("Adult")}
-];
-    |l(opt.code, opt.label) %]
-<option value='[_1]'[% values.grep('^' _ opt.code _ '$').size ? ' selected="selected"' : '' %]>[_2]</option>
-[% END; END %]
diff --git a/Open-ILS/web/templates/default/opac/parts/audience_selector.tt2 b/Open-ILS/web/templates/default/opac/parts/audience_selector.tt2
new file mode 100644 (file)
index 0000000..b3e86bf
--- /dev/null
@@ -0,0 +1,16 @@
+[%  name = name || "fi:audience";
+    id = id || "audience_selector";
+    values = values || CGI.param(name) %]
+<select id='[% id %]' name='[% name %]'[%
+    multiple ? ' multiple="multiple"' : '';
+    size ? (' size="' _ size _ '"') : ''; %]>
+[%
+FOR opt IN [
+    {'code' => 'a,b,c,j', 'label' => l("Juvenile")},
+    {'code' => 'd', 'label' => l("General")},
+    {'code' => 'e', 'label' => l("Adult")}
+];
+    |l(opt.code, opt.label) %]
+<option value='[_1]'[% values.grep('^' _ opt.code _ '$').size ? ' selected="selected"' : '' %]>[_2]</option>
+[% END; END %]
+</select>
index d9fcddd..2ca397b 100644 (file)
@@ -1,5 +1,6 @@
-[%  name = name || "format";
-    id = id || "format_selector" %]
+[%-  name = name || "fi:format";
+    id = id || "format_selector";
+    values = values || CGI.param(name) -%]
 <select id='[% id %]' name='[% name %]'[%
     multiple ? ' multiple="multiple"' : '';
     size ? (' size="' _ size _ '"') : ''; %]>
@@ -1,4 +1,10 @@
-[%
+[%- name = name || "fi:language";
+    id = id || "language_selector";
+    values = values || CGI.param(name); -%]
+<select id='[% id %]' name='[% name %]'[%
+    multiple ? ' multiple="multiple"' : '';
+    size ? (' size="' _ size _ '"') : ''; %]>
+[%-
 # Language otions for languages that exist in the catalog.
 # This file should be updated on occasion.
 #
@@ -30,4 +36,5 @@ FOR lang IN [
 ];
     |l(lang.code, lang.label) %]
 <option value='[_1]'[% values.grep('^' _ lang.code _ '$').size ? ' selected="selected"' : '' %]>[_2]</option>
-[%  END; END %]
+[%  END; END -%]
+</select>
index 761ae9a..63c1daf 100644 (file)
                                 <strong id="rdetail_pub_lbl">[% IF attrs.publisher; l("Publisher"); END %]</strong>
                             </td>
                             <td valign="top" id='rdetail_publisher'>[% attrs.publisher %]</td>
+                            [% BLOCK render_subject;
+                            FOR node IN ctx.marc_xml.findnodes('//*[@tag="650"]');
+                                s0 = node.childNodes.0.textContent;
+                                s1 = node.childNodes.1.textContent;
+                                IF s0;
+                                    IF s0.match('\S') %]
+                                    <a href="[% ctx.opac_root %]/results?query=su:[% s0 | url %]">[% s0 %]</a>
+                                    &mdash;
+                                    [% END; IF s1 %]
+                                    <a href="[% ctx.opac_root %]/results?query=su:[% s1 | url %]">[% s1 %]</a>
+                                    <br/>
+                                    [% END %]
+                                [% END %]
+                            [% END %]
+                            [% END %]
+                            [% s = PROCESS render_subject; IF s.match('\S') %]
                             <td nowrap='nowrap' valign="top">
-                                [%# XXX TODO see kcls' drawMarcSubjects() in rdetail.js %]
                                 <strong id="rdetail_sub_lbl">[% l("Subjects") %]</strong>
                             </td>
-                            <td valign="top"></td>
+                            <td valign="top">[% s %]</td>
+                            [% END %]
                         </tr>
                     </table>
                 </div>
index 3636eb0..7a83aea 100644 (file)
@@ -1,23 +1,8 @@
 [% PROCESS "default/opac/parts/org_selector.tt2" %]
 <div id="search-box">    
-    [% IF CGI.param('_adv') # this means adv search got us here %]
-    <div class="refine-controls">
-        <span id="refine_control_reveal">[
-            <a href="[% ctx.opac_root %]/advanced?[% query_string %]"
-                onclick="unHideMe($('adv_search_refine')); unHideMe($('refine_control_hide')); hideMe($('refine_control_reveal')); return false;">[%
-            l('Click to Refine Your Search')
-        %]</a> ]</span>
-        <span id="refine_control_hide" class="hide_me">[
-            <a href="javascript:void(0);"
-                onclick="hideMe($('adv_search_refine')); hideMe($('refine_control_hide')); unHideMe($('refine_control_reveal')); return false;">[%
-            l('Click to Hide Search Form')
-        %]</a> ]</span>
-    </div>
-    <div id="adv_search_refine" class="hide_me">
-        [% INCLUDE "default/opac/parts/advanced/search.tt2" %]
-    </div>
-    [% ELSE %]
+    [% UNLESS took_care_of_form -%]
     <form action="[% ctx.opac_root %]/results" method="GET">
+    [%- END %]
     <table cellpadding="0" cellspacing="10" border="0">
         <tr>
             <td colspan="3">
             </td>
         </tr>
         <tr>
+            [% IF is_advanced %]
+            <td colspan="2">
+                <input type="hidden" name="_adv" value="1" />
+            [% ELSE %]
             <td>
-                [% INCLUDE "default/opac/parts/stypes_selector.tt2" %]
+            [% INCLUDE "default/opac/parts/stypes_selector.tt2" %]
             </td>
             <td>
+            [% END %]
                 <div id="search_box_wrapper">
                     <!-- Note: when common browsers support HTML5 placeholder text, we can remove the JS -->
-                    <input type="text" id="search_box" name="query" value="[% ctx.processed_search_query || l("Search Keyword") | html %]"
+                    <input type="text" id="search_box" name="query" value="[% is_advanced ? ctx.processed_search_query : CGI.param('query') || l("Search Keyword") | html %]"
+                        [% IF is_advanced %]style="width: 450px"[% END %]
                         onfocus="if (this.value=='[% l("Search Keyword") %]'){this.value='';this.style.color='#000';}"
                         onblur="if (this.value==''){this.value='[% l("Search Keyword") %]';this.style.color='#999';}" />
-                    <input name='page' type='hidden' value="0" />
                 </div>
+                <input name='page' type='hidden' value="0" />
             </td>
             <td valign="top">
                 <div class="pos-abs">
@@ -50,6 +41,7 @@
                 </div>
             </td>
         </tr>
+        [% UNLESS is_advanced %]
         <tr>
             <td>
                 [% INCLUDE "default/opac/parts/format_selector.tt2" value=CGI.param("format") %]
                 </span>
             </td>
         </tr>
+        [% END %]
     </table>
-    </form>
+    [% UNLESS took_care_of_form %]</form>[% END %]
+    [% IF is_advanced %]
+    <div class="opac-auto-102">
+        [ <a href="[% ctx.opac_root %]/advanced?[% query_string %]">[%
+            l('Click to Refine Your Search')
+        %]</a> ]
+    </div>
     [% END %]
     <div id="breadcrumb">
         <a href="[% ctx.opac_root %]/home">[% l('Catalog Home') %]</a> &gt;
index 69389e9..b139791 100644 (file)
@@ -6,8 +6,8 @@
     {value => "series", label => l("Series")},
     {value => "id|bibcn", label => l("Call Number")}
 ] %]
-<select name="class">
-    [%  search_class = CGI.param('class');
+<select name="qtype">
+    [%  search_class = CGI.param('qtype');
         FOR sc IN search_classes -%]
     <option value='[% sc.value %]'[%
         search_class == sc.value ? ' selected="selected"' : ''
index f4f0f71..682ef91 100644 (file)
@@ -4,6 +4,7 @@
     WRAPPER "default/opac/parts/base.tt2";
     INCLUDE "default/opac/parts/topnav.tt2";
     ctx.page_title = l("Search Results");
+    is_advanced = CGI.param("_adv").size;
 
     query_string = CGI.query_string |
         replace(';x=\d+','') | replace(';y=\d+','') | replace(';page=\d*', '') |
     loc = CGI.param('loc');
     page_count = POSIX.ceil(ctx.hit_count / ctx.page_size);
 %]
+    <form action="[% ctx.opac_root %]/results" method="GET">
     <div id="search-wrapper">
         [% INCLUDE "default/opac/parts/utils.tt2" %]
-        [% INCLUDE "default/opac/parts/searchbar.tt2" %]
+        [% INCLUDE "default/opac/parts/searchbar.tt2" took_care_of_form=1 %]
     </div>
     <div id="content-wrapper">
         <div id="results_header_bar">
@@ -41,7 +43,7 @@
                 <div class="results_header_div"></div>
                 [% UNLESS CGI.param('_adv') %]
                     <div class="results_header_lbl">Sort by</div>
-                    [% INCLUDE "default/opac/parts/filtersort.tt2" %]
+                    [% INCLUDE "default/opac/parts/filtersort.tt2" value=CGI.param('sort') %]
                     <div class="results_header_div"></div>
                     <!-- XXX still needed?<div class="results_header_lbl">View</div>
                     <select class="results_header_sel">
                         <option>Detailed</option>
                     </select>
                     <div class="results_header_div"></div> -->
-                    <input type="checkbox" id="limit_to_available" />
+                    <input type="checkbox" id="limit_to_available"
+                        name="modifier" value="available"
+                        [% CGI.param('modifier').grep('available').size
+                            ? ' checked="checked"' : '' %] />
                     <label for="limit_to_available" class="results_header_lbl">
                         [% l('Limit to available items') %]
                     </label>
@@ -66,4 +71,5 @@
             <div class="common-full-pad"></div>    
         </div>
     </div>
+    </form>
 [% END %]