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;
$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');
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;
$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) = @_;
# 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")
);
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;
}
}
- if ($metarecord) {
+ if ($metarecord and !$internal) {
# TODO: other limits, like SVF/format, etc.
$results = $U->simplereq(
} 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.
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},
# 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");
$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(
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;
[%- IF ctx.is_staff %]
<script type="text/javascript" src="[% ctx.media_prefix %]/js/ui/default/opac/staff.js"></script>
+ [% IF ctx.page == 'record' AND ctx.search_result_index >= 0 %]
+ <script>
+ rdetail_next_prev_actions(
+ "[% ctx.search_result_index %]",
+ "[% ctx.hit_count %]",
+ "[% ctx.prev_rec_url || '' %]",
+ "[% ctx.next_rec_url || '' %]",
+ "[% mkurl(ctx.first_search_record, {page => 0}) %]",
+ "[% mkurl(ctx.last_search_record, {page => POSIX.floor(ctx.hit_count / ctx.page_size)}) %]"
+ );
+ </script>
+ [% END %]
[%- END %]
[%- IF ENV.OILS_NOVELIST_URL AND ctx.page == 'record';
[% attrs = {marc_xml => ctx.marc_xml};
PROCESS "opac/parts/misc_util.tt2";
PROCESS get_marc_attrs args=attrs %]
+
<div id='canvas_main' class='canvas'>
- <div id="rdetail_header" class="hide_me">[%#
- 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 %]
+ <div id="rdetail_header">
<div style="float:left;">
- Search Results
- <span id="rdetail_result_count" class="hide_me">
- Showing Item <strong id='np_offset'></strong>
- of <strong id='np_count'></strong>
+ <a href='[% mkurl(ctx.opac_root _ '/results', {page => 0}) %]'>[% l('◄ Search Results') %]</a>
+ <span id="rdetail_result_count">
+ [% l('Showing Item [_1] of [_2]', ctx.search_result_index + 1, ctx.hit_count) %]
</span>
</div>
<div id="rdetail_result_nav">
- <span class="hide_me">
- <a class='np_nav_link classic_link' id='np_start'
- href='#'
- title="[% l("First results page") %]">[% l("Start") %]</a>
- </span>
- <a class='np_nav_link classic_link hide_me' id='np_prev'
- href='#'
- title='[% l("Previous page") %]'><span
- class="nav_arrow_fix">◄</span> Previous</a>
- <span style="padding:0px 10px;"> </span>
- <a class='np_nav_link classic_link hide_me' id='np_next'
- href='#'
- title='[% l("Next page") %]'>Next <span
- class="nav_arrow_fix">►</span></a>
- <span class="hide_me"><a class='np_nav_link classic_link'
- id='np_end' href='#'
- title="[% l("Last results page") %]">[% l("End") %]</a></span>
+ [%
+ 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);
+ %]
+ <a class='np_nav_link classic_link' title='[% l("Previous Record") %]'
+ href='[% ctx.prev_rec_url %]'><span class="nav_arrow_fix">◄ </span>[% l('Previous') %]</a>
+ [% END %]
+
+ <span style="padding:0px 10px;"> </span>
+
+ [%
+ 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);
+ %]
+ <a class='np_nav_link classic_link' title='[% l("Next Record") %]'
+ href='[% ctx.next_rec_url %]'>[% l('Next') %]<span class="nav_arrow_fix"> ►</span></a>
+ [% END %]
+
</div>
<div class="clear-both"></div>
</div>
+ [% END %]
<div style='font-weight: bold; padding: 5px; margin: 5px; width: 100%;'
class='hide_me color_4' id='rdetail_deleted_exp'>
%]</a> ]
</div>
[% END %]
+ <!--
<div id="breadcrumb">
<a href="[% ctx.opac_root %]/home">[% l('Catalog Home') %]</a> >
</div>
+ -->
<div class="clear-both"></div>
</div>
color: black;
font-size: 11px;
font-weight: normal;
+ padding-left: 10px;
}
#rdetail_result_nav {
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));
+ };
+}