From fac08ad3cf420e35550c8e64cb36b866210ea125 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Wed, 14 Sep 2011 14:25:41 -0400 Subject: [PATCH] TPac: Page through search results on details page Consistent with jspac, when you land on a record details page and you got there from doing a search, let the user page through the search results directly on the record detail page. This also includes the necessary JS callbacks to support paging in the staff client. Signed-off-by: Bill Erickson Signed-off-by: Lebbeous Fogle-Weekley --- .../perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm | 31 ++++++++++- .../perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm | 52 ++++++++++++++----- Open-ILS/src/templates/opac/parts/js.tt2 | 12 +++++ Open-ILS/src/templates/opac/parts/record/body.tt2 | 60 ++++++++++++---------- Open-ILS/src/templates/opac/parts/searchbar.tt2 | 2 + Open-ILS/web/css/skin/default/opac/style.css | 1 + Open-ILS/web/js/ui/default/opac/staff.js | 26 ++++++++++ 7 files changed, 144 insertions(+), 40 deletions(-) diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm index 009372c575..9b21d56fe4 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Record.pm @@ -12,7 +12,7 @@ my $U = 'OpenILS::Application::AppUtils'; sub load_record { my $self = shift; my $ctx = $self->ctx; - $ctx->{page} = 'record'; + $ctx->{page} = 'record'; my $org = $self->cgi->param('loc') || $ctx->{aou_tree}->()->id; my $depth = $self->cgi->param('depth') || 0; @@ -27,6 +27,8 @@ sub load_record { $ctx->{saved_searches} = ($self->staff_load_searches)[1]; } + $self->fetch_related_search_info($rec_id); + # run copy retrieval in parallel to bib retrieval # XXX unapi my $cstore = OpenSRF::AppSession->create('open-ils.cstore'); @@ -99,6 +101,33 @@ sub load_record { return Apache2::Const::OK; } +# collect IDs and info on the search that lead to this details page +# If no search query, etc is present, we leave ctx.search_result_index == -1 +sub fetch_related_search_info { + my $self = shift; + my $rec_id = shift; + my $ctx = $self->ctx; + $ctx->{search_result_index} = -1; + + $self->load_rresults(internal => 1); + + my @search_ids = @{$ctx->{ids}}; + return unless @search_ids; + + for my $idx (0..$#search_ids) { + if ($search_ids[$idx] == $rec_id) { + $ctx->{prev_search_record} = $search_ids[$idx - 1] if $idx > 0; + $ctx->{next_search_record} = $search_ids[$idx + 1]; + $ctx->{search_result_index} = $idx; + last; + } + } + + $ctx->{first_search_record} = $search_ids[0]; + $ctx->{last_search_record} = $search_ids[-1]; +} + + sub mk_copy_query { my $self = shift; my $rec_id = shift; diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm index 7dc650b44f..635678b982 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Search.pm @@ -10,6 +10,10 @@ use Data::Dumper; $Data::Dumper::Indent = 0; my $U = 'OpenILS::Application::AppUtils'; +# when fetching "all" search results for staff client +# start/end paging, fetch this many IDs at most +my $all_recs_limit = 10000; + sub _prepare_biblio_search_basics { my ($cgi) = @_; @@ -140,15 +144,21 @@ sub _get_search_limit { # records : list of bre's and copy-count objects sub load_rresults { my $self = shift; + my %args = @_; + my $internal = $args{internal}; my $cgi = $self->cgi; my $ctx = $self->ctx; my $e = $self->editor; - $ctx->{page} = 'rresult'; + $ctx->{page} = 'rresult' unless $internal; + $ctx->{ids} = []; + $ctx->{records} = []; + $ctx->{search_facets} = {}; + $ctx->{hit_count} = 0; # Special alternative searches here. This could all stand to be cleaner. if ($cgi->param("_special")) { - return $self->marc_expert_search if scalar($cgi->param("tag")); + return $self->marc_expert_search(%args) if scalar($cgi->param("tag")); return $self->item_barcode_shortcut if ( $cgi->param("qtype") and ($cgi->param("qtype") eq "item_barcode") ); @@ -165,6 +175,15 @@ sub load_rresults { my $metarecord = $cgi->param('metarecord'); my $results; + $ctx->{page_size} = $limit; + $ctx->{search_page} = $page; + + # fetch the first hit from the next page + if ($internal) { + $limit = $all_recs_limit; + $offset = 0; + } + my ($query, $site, $depth) = _prepare_biblio_search($cgi, $ctx); $self->get_staff_search_settings; @@ -184,7 +203,7 @@ sub load_rresults { } } - if ($metarecord) { + if ($metarecord and !$internal) { # TODO: other limits, like SVF/format, etc. $results = $U->simplereq( @@ -198,7 +217,10 @@ sub load_rresults { } else { - return $self->generic_redirect unless $query; + if (!$query) { + return Apache2::Const::OK if $internal; + return $self->generic_redirect; + } # Limit and offset will stay here. Everything else should be part of # the query string, not special args. @@ -226,13 +248,11 @@ sub load_rresults { my $rec_ids = [map { $_->[0] } @{$results->{ids}}]; - $ctx->{records} = []; - $ctx->{search_facets} = {}; - $ctx->{page_size} = $limit; + $ctx->{ids} = $rec_ids; $ctx->{hit_count} = $results->{count}; $ctx->{parsed_query} = $results->{parsed_query}; - return Apache2::Const::OK if @$rec_ids == 0; + return Apache2::Const::OK if @$rec_ids == 0 or $internal; my ($facets, @data) = $self->get_records_and_facets( $rec_ids, $results->{facet_key}, @@ -306,7 +326,7 @@ sub item_barcode_shortcut { # like item_barcode_search, this can't take all the usual search params, but # this one will at least do site, limit and page sub marc_expert_search { - my ($self) = @_; + my ($self, %args) = @_; my @tags = $self->cgi->param("tag"); my @subfields = $self->cgi->param("subfield"); @@ -334,10 +354,17 @@ sub marc_expert_search { $self->ctx->{search_facets} = {}; $self->ctx->{page_size} = $limit; $self->ctx->{hit_count} = 0; + $self->ctx->{ids} = []; + $self->ctx->{search_page} = $page; # nothing to do return Apache2::Const::OK if @$query == 0; + if ($args{internal}) { + $limit = $all_recs_limit; + $offset = 0; + } + my $timeout = 120; my $ses = OpenSRF::AppSession->create('open-ils.search'); my $req = $ses->request( @@ -357,14 +384,13 @@ sub marc_expert_search { return Apache2::Const::HTTP_INTERNAL_SERVER_ERROR; } + $self->ctx->{ids} = [ grep { $_ } @{$results->{ids}} ]; + my ($facets, @data) = $self->get_records_and_facets( - # filter out nulls that will turn up here - [ grep { $_ } @{$results->{ids}} ], - undef, {flesh => "{holdings_xml,mra}"} + $self->ctx->{ids}, undef, {flesh => "{holdings_xml,mra}"} ); $self->ctx->{records} = [@data]; - $self->ctx->{page_size} = $limit; $self->ctx->{hit_count} = $results->{count}; return Apache2::Const::OK; diff --git a/Open-ILS/src/templates/opac/parts/js.tt2 b/Open-ILS/src/templates/opac/parts/js.tt2 index 22ae555b2e..c0b2e70603 100644 --- a/Open-ILS/src/templates/opac/parts/js.tt2 +++ b/Open-ILS/src/templates/opac/parts/js.tt2 @@ -5,6 +5,18 @@ [%- IF ctx.is_staff %] + [% IF ctx.page == 'record' AND ctx.search_result_index >= 0 %] + + [% END %] [%- END %] [%- IF ENV.OILS_NOVELIST_URL AND ctx.page == 'record'; diff --git a/Open-ILS/src/templates/opac/parts/record/body.tt2 b/Open-ILS/src/templates/opac/parts/record/body.tt2 index 184bd7cd63..bc42f5d56a 100644 --- a/Open-ILS/src/templates/opac/parts/record/body.tt2 +++ b/Open-ILS/src/templates/opac/parts/record/body.tt2 @@ -2,40 +2,48 @@ [% attrs = {marc_xml => ctx.marc_xml}; PROCESS "opac/parts/misc_util.tt2"; PROCESS get_marc_attrs args=attrs %] +
-
[%# - XXX Does it make sense for now to even have this section? Why - should the record detail page be aware of the ongoing search? - The user can use the back button to go back to their search results - like on any other website. %] + + [% IF ctx.search_result_index >= 0 %] +
- Search Results    - - Showing Item -  of  + 0}) %]'>[% l('◄ Search Results') %] + + [% l('Showing Item [_1] of [_2]', ctx.search_result_index + 1, ctx.hit_count) %]
- - [% l("Start") %] - - Previous - - Next - [% l("End") %] + [% + IF ctx.prev_search_record; + prev_args = {}; + IF ctx.search_result_index % (ctx.page_size + 1) == 0; # first record in the page + prev_args.page = ctx.search_page - 1; + END; + ctx.prev_rec_url = mkurl(ctx.prev_search_record, prev_args); + %] + [% l('Previous') %] + [% END %] + + + + [% + IF ctx.next_search_record; + next_args = {}; + IF ctx.page_size == ctx.search_result_index + 1; + next_args.page = ctx.search_page + 1; + END; + ctx.next_rec_url = mkurl(ctx.next_search_record, next_args); + %] + [% l('Next') %] + [% END %] +
+ [% END %]
diff --git a/Open-ILS/src/templates/opac/parts/searchbar.tt2 b/Open-ILS/src/templates/opac/parts/searchbar.tt2 index 3dbd70ae0f..1f1f0a8303 100644 --- a/Open-ILS/src/templates/opac/parts/searchbar.tt2 +++ b/Open-ILS/src/templates/opac/parts/searchbar.tt2 @@ -65,8 +65,10 @@ %] ]
[% END %] +
diff --git a/Open-ILS/web/css/skin/default/opac/style.css b/Open-ILS/web/css/skin/default/opac/style.css index 7c1cd69b39..cc8dcf4e19 100644 --- a/Open-ILS/web/css/skin/default/opac/style.css +++ b/Open-ILS/web/css/skin/default/opac/style.css @@ -342,6 +342,7 @@ div.select-wrapper:hover { color: black; font-size: 11px; font-weight: normal; + padding-left: 10px; } #rdetail_result_nav { diff --git a/Open-ILS/web/js/ui/default/opac/staff.js b/Open-ILS/web/js/ui/default/opac/staff.js index c170198fc6..5521e5063b 100644 --- a/Open-ILS/web/js/ui/default/opac/staff.js +++ b/Open-ILS/web/js/ui/default/opac/staff.js @@ -24,3 +24,29 @@ window.onload = function() { if(rec && rec[1]) { runEvt('rdetail', 'recordRetrieved', rec[1]); } // fire other events the staff client is expecting... } + +function rdetail_next_prev_actions(index, count, prev, next, start, end) { + /* we get the relative URL from the template: recid?query_args... + replace the recid and args on location.href to get the new URL */ + function fullurl(url) { return location.href.replace(/\/\d+\??.*/, '/' + url); } + + if (index > 0) { + if(prev) + window.rdetailPrev = function() { location.href = fullurl(prev); } + if(start) + window.rdetailStart = function() { location.href = fullurl(start); } + } + + if (index < count - 1) { + if(next) + window.rdetailNext = function() { location.href = fullurl(next); } + if(end) + window.rdetailEnd = function() { location.href = fullurl(end); } + } + + ol = window.onload; + window.onload = function() { + if(ol) ol(); + runEvt('rdetail', 'nextPrevDrawn', Number(index), Number(count)); + }; +} -- 2.11.0