TPac: Facets on results page
authorBill Erickson <berick@esilibrary.com>
Fri, 30 Sep 2011 20:01:22 +0000 (16:01 -0400)
committerDan Scott <dscott@laurentian.ca>
Tue, 4 Oct 2011 01:06:35 +0000 (21:06 -0400)
Show search facets along the left side of the results page.  Clicking on
a facet re-runs the current search with the  new facet appeneded.
Selected facets are styled to indicate they are selected.  Clicking on a
selected facet removes that facet from the set of selected facets (i.e.
it backs out the facet).

TODO: update CSS to match default Evergreen skin

Signed-off-by: Bill Erickson <berick@esilibrary.com>
Signed-off-by: Dan Scott <dscott@laurentian.ca>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Util.pm
Open-ILS/src/templates/opac/parts/result/facets.tt2 [new file with mode: 0644]
Open-ILS/src/templates/opac/parts/result/table.tt2
Open-ILS/web/css/skin/default/opac/style.css
Open-ILS/web/images/adv_search_minus_btn.png [new file with mode: 0644]
Open-ILS/web/images/adv_search_plus_btn.png [new file with mode: 0644]
Open-ILS/web/images/facet_box_bg.png [new file with mode: 0644]
Open-ILS/web/images/facet_box_bg_bottom.png [new file with mode: 0644]

index 635678b..37fa582 100644 (file)
@@ -168,7 +168,7 @@ sub load_rresults {
     }
 
     my $page = $cgi->param('page') || 0;
-    my $facet = $cgi->param('facet');
+    my @facets = $cgi->param('facet');
     my $limit = $self->_get_search_limit;
     my $loc = $cgi->param('loc') || $ctx->{aou_tree}->()->id;
     my $offset = $page * $limit;
@@ -229,7 +229,7 @@ sub load_rresults {
         # Stuff these into the TT context so that templates can use them in redrawing forms
         $ctx->{processed_search_query} = $query;
 
-        $query = "$query $facet" if $facet; # TODO
+        $query .= " $_" for @facets;
 
         $logger->activity("EGWeb: [search] $query");
 
index 6af3a7a..3b72dbc 100644 (file)
@@ -201,13 +201,23 @@ sub get_records_and_facets {
     # gather up the unapi recs
     $ses->session_wait(1);
 
-    my $facets;
+    my $facets = {};
     if ($facet_key) {
-        $facets = $facet_req->gather(1);
-        $facets->{$_} = {
-            cmf => $self->ctx->{get_cmf}->($_),
-            data => $facets->{$_}
-        } for keys %$facets;    # quick-n-dirty
+        my $tmp_facets = $facet_req->gather(1);
+        for my $cmf_id (keys %$tmp_facets) {
+
+            # sort highest to lowest match count
+            my @entries;
+            my $entries = $tmp_facets->{$cmf_id};
+            for my $ent (keys %$entries) {
+                push(@entries, {value => $ent, count => $$entries{$ent}});
+            };
+            @entries = sort { $b->{count} <=> $a->{count} } @entries;
+            $facets->{$cmf_id} = {
+                cmf => $self->ctx->{get_cmf}->($cmf_id),
+                data => \@entries
+            }
+        }
     } else {
         $facets = undef;
     }
diff --git a/Open-ILS/src/templates/opac/parts/result/facets.tt2 b/Open-ILS/src/templates/opac/parts/result/facets.tt2
new file mode 100644 (file)
index 0000000..c4a719d
--- /dev/null
@@ -0,0 +1,95 @@
+<div class="facet_box_wrapper">
+[% 
+
+close_facets = CGI.param('close_facet') || [];
+selected_facets = CGI.param('facet') || [];
+
+# collect facet type labels for easier sorting
+labels = []; 
+FOR facet IN ctx.search_facets.values;
+    labels.push(facet.cmf.label);
+END;
+
+FOR facet_label IN labels.sort;
+    FOR facet IN ctx.search_facets.values;
+        IF facet.cmf.label == facet_label;
+            fclass = facet.cmf.field_class;
+            fname = facet.cmf.name;
+            close_key = fclass _ fname %]
+
+        <div class="facet_box_temp">
+            <div class="header">
+                <div class="title">[% facet.cmf.label %]</div>
+                <div class="button">
+
+                    [% IF close_facets.grep(close_key).0;
+                        new_close = [];
+                        FOR fct IN close_facets;
+                            IF fct != close_key;
+                                new_close.push(fct);
+                            END;
+                        END
+                    %]
+                        <a href="[% mkurl('', {close_facet => new_close}) %]"><img 
+                            src="[% ctx.media_prefix %]/images/adv_search_plus_btn.png" alt="[% l('Expand') %]" /></a>
+                    [% ELSE %]
+                        <a href="[% mkurl('', {close_facet => close_facets.merge([close_key])}) %]"><img 
+                            src="[% ctx.media_prefix %]/images/adv_search_minus_btn.png" alt="[% l('Collapse') %]" /></a>
+                    [% END %]
+                </div>
+                <div class="clear">&nbsp;</div>
+            </div>
+            [% IF !close_facets.grep(close_key).0 %]
+            <div class="box_wrapper">
+                <div class="box">
+                [% FOR facet_data IN facet.data;
+                    display_value = facet_data.value | html;
+                    param_string = fclass _ '|' _ fname _ '[' _ facet_data.value _ ']';
+                    new_facets = [];
+                    this_selected = 0;
+                    FOR selected IN selected_facets;
+                        IF selected == param_string; 
+                            this_selected = 1; 
+                        ELSE;
+                            new_facets.push(selected);
+                        END;
+                    END;
+                    IF this_selected;
+                        # This facet is already selected by the user. 
+                        # Link removes the facet from the set of selected facets.
+                    %] 
+                        <div class="facet_template facet_template_selected">
+                            <div class="facet">
+                                [% IF new_facets.size == 0 %]
+                                <a href="[% mkurl('', {}, ['facet']) %]">[% display_value %]</a>
+                                [% ELSE %]
+                                <a href="[% mkurl('', {facet => new_facets}) %]">[% display_value %]</a>
+                                [% END %]
+                            </div>
+                            <div class="count">([% facet_data.count %])</div>
+                            <div class="clear">&nbsp;</div>
+                        </div>
+                    [% 
+                        ELSE;
+                        # This facet is not currently selected.  If selected, 
+                        # append this facet to the list of currently active facets.
+                    %]
+                        <div class="facet_template">
+                            <div class="facet">
+                                <a href='[% mkurl('', {facet => selected_facets.merge([param_string])}) %]'>[% display_value %]</a>
+                            </div>
+                            <div class="count">([% facet_data.count %])</div>
+                            <div class="clear">&nbsp;</div>
+                        </div>
+                    [% END %]
+                [% END %]
+                </div>
+                <div class="clear">&nbsp;</div>
+            </div> <!-- box_wrapper -->
+            [% END %]
+        </div> <!-- facet_box_temp -->
+        [% END %]
+    [% END %]
+[% END %]
+</div> <!-- facet_box_wrapper -->
+
index 0706ef6..b60e647 100644 (file)
@@ -19,8 +19,8 @@
     <table cellpadding="0" cellspacing="0" border="0" width="100%">
         <tr>
             <td valign="top" width="1" style="padding-right:20px;">
-                <div style="width:174px;" class="hide_me">
-                    SIDEBAR TODO
+                <div style="width:174px;">
+                    [% INCLUDE 'opac/parts/result/facets.tt2' %]
                 </div>
             </td>
             <td class='opac-auto-015' width="1"></td>
index 368dad5..e90a0ef 100644 (file)
@@ -886,6 +886,7 @@ div.select-wrapper:hover {
 }
 
 /* some facet styling */
+/*
 .facetClassContainer { margin: 2px; border: 1px solid #CCC; }
 .facetClassLabelContainer { border: 1px solid #CCC; }
 .facetClassLabel { font-weight: bold; text-align: center; }
@@ -897,6 +898,77 @@ div.select-wrapper:hover {
 .facetField { border-top: 1px solid #CCC; }
 .facetFields { padding-left: 5px; }
 .facetFieldLineValue { overflow: hidden; text-overflow: ellipsis; }
+*/
+
+.facet_box_temp {
+       padding-bottom:3px;
+       width:180px;
+       overflow:hidden;
+}
+
+.facet_box_temp .header {
+       width:180px;
+       height:31px;
+       overflow:hidden;
+       background:url('/images/facet_box_bg.png') no-repeat;
+       font-weight:bold;
+       color:#074079;
+       padding-top:4px;
+}
+
+.facet_box_temp .header .title {
+       float:left;
+       padding-top:6px;
+       padding-left:12px;
+       width:134px;
+       overflow:hidden;
+}
+
+.facet_box_temp .header .button {
+       float:right;
+       padding-right:6px;
+}
+
+.facet_box_wrapper .box_wrapper {
+       position:relative;
+       top:-4px;
+       margin-bottom:-5px;
+       *margin-bottom:-6px;
+}
+
+.facet_box_wrapper .box_wrapper .box {
+       width:166px;
+       border-top:1px solid #7ebee5;
+       border-left:1px solid #f3f3f3;
+       border-right:1px solid #f3f3f3;
+       background:white;
+       padding-left:12px;
+       padding-top:6px;
+}
+
+.facet_box_wrapper .box_wrapper .bottom {
+       background:url('/images/facet_box_bg_bottom.png') no-repeat;
+}
+
+.facet_template {
+       padding-bottom:5px;
+}
+
+.facet_template .facet {
+       float:left;
+       width:124px;
+}
+
+.facet_template .count {
+       float:right;
+       color:#818080;
+       padding-right:11px;
+}
+
+.facet_template_selected {
+    background-color: #d7d7d7;
+}
+
 #footer-wrap {
     background: linear-gradient(lightGreen, #252525);
     background: -moz-linear-gradient(lightGreen, #252525);
@@ -904,6 +976,7 @@ div.select-wrapper:hover {
     background: -webkit-linear-gradient(lightGreen, #252525);
     background-color: lightGreen;
 }
+
 #footer {
        padding-top:5px;
        padding-bottom: 10px;
diff --git a/Open-ILS/web/images/adv_search_minus_btn.png b/Open-ILS/web/images/adv_search_minus_btn.png
new file mode 100644 (file)
index 0000000..4050595
Binary files /dev/null and b/Open-ILS/web/images/adv_search_minus_btn.png differ
diff --git a/Open-ILS/web/images/adv_search_plus_btn.png b/Open-ILS/web/images/adv_search_plus_btn.png
new file mode 100644 (file)
index 0000000..7f1ae93
Binary files /dev/null and b/Open-ILS/web/images/adv_search_plus_btn.png differ
diff --git a/Open-ILS/web/images/facet_box_bg.png b/Open-ILS/web/images/facet_box_bg.png
new file mode 100644 (file)
index 0000000..996f0a8
Binary files /dev/null and b/Open-ILS/web/images/facet_box_bg.png differ
diff --git a/Open-ILS/web/images/facet_box_bg_bottom.png b/Open-ILS/web/images/facet_box_bg_bottom.png
new file mode 100644 (file)
index 0000000..fc776c3
Binary files /dev/null and b/Open-ILS/web/images/facet_box_bg_bottom.png differ