return Apache2::Const::OK;
}
+sub load_course_browse {
+ my $self = shift;
+ my $cgi = $self->cgi;
+ my $ctx = $self->ctx;
+ my $e = $self->editor;
+
+ my $browse_results = [];
+
+ # Are we searching? Cool, let's generate some links
+ if ($cgi->param('bterm')) {
+ my $bterm = $cgi->param('bterm');
+ my $qtype = $cgi->param('qtype');
+ # Search term is optional. If it's empty, start at the
+ # beginning. Otherwise, center results on a match.
+ # Regardless, we're listing everything, so retrieve all.
+ my $results;
+ my $instructors;
+ if ($qtype eq 'instructor') {
+ $instructors = $e->json_query({
+ "from" => "acmcu",
+ "select" => {"acmcu" => [
+ 'id',
+ 'usr',
+ 'is_public'
+ ]},
+ # TODO: We need to support the chosen library as well...
+ "where" => {'+acmcu' => 'is_public'}
+ });
+ $results = $e->json_query({
+ "from" => "au",
+ "select" => {"au" => [
+ 'id',
+ 'pref_first_given_name',
+ 'first_given_name',
+ 'pref_second_given_name',
+ 'second_given_name',
+ 'pref_family_name',
+ 'family_name'
+ ]},
+ "order_by" => {'au' => ['pref_family_name', 'family_name']},
+ "where" => {'-and' => [{
+ "id" => { "in" => {
+ "from" => "acmcu",
+ "select" => {
+ "acmcu" => ['usr']
+ },
+ "where" => {'-and' => [
+ {'+acmcu' => 'is_public'},
+ {"course" => { "in" =>{
+ "from" => "acmc",
+ "select" => {
+ "acmc" => ['id']
+ },
+ "where" => {'-not' => [{'+acmc' => 'is_archived'}]}
+ }}}
+ ]}
+ }}
+ }]}
+ });
+ } else {
+ $results = $e->json_query({
+ "from" => "acmc",
+ "select" => {"acmc" => [
+ 'id',
+ 'name',
+ 'course_number',
+ 'is_archived',
+ 'owning_lib'
+ ]},
+ "order_by" => {"acmc" => [$qtype]},
+ # TODO: We need to support the chosen library as well...
+ "where" => {'-not' => {'+acmc' => 'is_archived'}}
+ });
+ }
+ my $bterm_match = 0;
+ for my $result(@$results) {
+ my $value_exists = 0;
+ my $rqtype = $qtype;
+ my $entry = {
+ 'value' => '',
+ 'results_count' => 0,
+ 'match' => 0
+ };
+
+ if ($qtype eq 'instructor') {
+ # Put together the name
+ my $name_str = '';
+ if ($result->{'pref_family_name'}) {
+ $name_str = $result->{'pref_family_name'} . ", ";
+ } elsif ($result->{'family_name'}) {
+ $name_str = $result->{'family_name'} . ", ";
+ }
+
+ if ($result->{'pref_first_given_name'}) {
+ $name_str .= $result->{'pref_first_given_name'};
+ } elsif ($result->{'first_given_name'}) {
+ $name_str .= $result->{'first_given_name'};
+ }
+
+ if ($result->{'pref_second_given_name'}) {
+ $name_str .= " " . $result->{'pref_second_given_name'};
+ } elsif ($result->{'second_given_name'}) {
+ $name_str .= " " . $result->{'second_given_name'};
+ }
+
+ $result->{$rqtype} = $name_str;
+
+ # Get an accurate count of matching courses
+ for my $instructor(@$instructors) {
+ if ($instructor->{'usr'} eq $result->{'id'}) {
+ $entry->{'results_count'} += 1;
+ last;
+ }
+ }
+ } else {
+ $entry->{'results_count'} += 1;
+ }
+
+ for my $existing_entry(@$browse_results) {
+ if ($existing_entry->{'value'} eq $result->{$rqtype} && $value_exists eq 0) {
+ $value_exists = 1;
+ $existing_entry->{'results_count'} += 1;
+ last;
+ }
+ }
+
+ if ($value_exists eq 0) {
+ # For Name/Course Number browse queries...
+ if ($bterm_match eq 0) {
+ if ($result->{$qtype} =~ m/^$bterm./ || $result->{$qtype} eq $bterm) {
+ $bterm_match = 1;
+ $entry->{'match'} = 1;
+ }
+ }
+ $entry->{'value'} = $result->{$rqtype};
+ push @$browse_results, $entry;
+ }
+ }
+ # Feels a bit hacky, but we need the index of the matching entry
+ my $match_idx = 0;
+ if ($bterm_match) {
+ for my $i (0..$#$browse_results) {
+ if ($browse_results->[$i]->{'match'}) {
+ $match_idx = $i;
+ last;
+ }
+ }
+ }
+
+ for my $i(0..$#$browse_results) {
+ $browse_results->[$i]->{'browse_index'} = $i;
+ }
+ $ctx->{match_idx} = $match_idx;
+ $ctx->{browse_results} = $browse_results;
+ }
+
+ return Apache2::Const::OK;
+}
+
sub load_cresults {
my $self = shift;
my %args = @_;
--- /dev/null
+[%-
+
+ PROCESS "opac/parts/header.tt2";
+ PROCESS "opac/parts/misc_util.tt2";
+ PROCESS "opac/parts/org_selector.tt2";
+ WRAPPER "opac/parts/base.tt2";
+ INCLUDE "opac/parts/topnav.tt2";
+
+ ctx.page_title = l("Browse Courses");
+ blimit = CGI.param('blimit') || ctx.opac_hits_per_page || 10;
+ display_idx = CGI.param('didx') || ctx.match_idx || 0;
+
+ upper_limit = 0;
+ lower_limit = 0;
+ depart_list = ['blimit', 'bterm', 'bpivot'];
+ ctx.metalinks.push('<meta name="robots" content="noindex,follow">');
+%]
+
+<h2 class="sr-only">[% l('Course Browse') %]</h2>
+<div id="search-wrapper">
+ <div id="search-box">
+ <div id="search-box">
+ <span class="search_catalog_lbl"><a href="[% mkurl(ctx.opac_root _ '/home', {}, depart_list) %]">[% l('Basic Search') %]</a></span>
+ <span class="adv_search_catalog_lbl"><a href="[% mkurl(ctx.opac_root _ '/advanced', {}, depart_list) %]"
+ id="home_adv_search_link">[%l('Advanced Search')%]</a></span>
+ <span class="browse_the_catalog_lbl mobile_hide">[% l('Browse the Catalog') %]</span>
+ <span class="browse_the_catalog_lbl mobile_hide">[% l('Search Courses') %]</span>
+ <span class="browse_the_catalog_lbl mobile_hide">[% l('Browse for Courses') %]</span>
+ [% INCLUDE 'opac/parts/cart.tt2' %]
+ </div>
+ </div>
+</div>
+
+<div id="content-wrapper">
+ <div id="main-content">
+ <div id="browse-for-courses">
+ <div id="browse-controls" class='searchbar'>
+ <form method="get" onsubmit="$('browse-submit-spinner').className = ''; return true">
+ <input type="hidden" name="blimit"
+ value="[% blimit | html %]" />
+ [% control_qtype = INCLUDE "opac/parts/course_search/qtype_selector.tt2"
+ id="browse-search-class" browse_only=1 plural=1 %]
+
+ [% control_bterm = BLOCK %]
+ <input type="text" name="bterm" id="browse-term"
+ aria-label="[% l('Browse term') %]"
+ value="[% CGI.param('bterm') | html %]">
+ [% END; #control_bterm BLOCK %]
+
+ [% control_locg = INCLUDE build_org_selector id='browse-context'
+ show_log_groups=1 arialabel=l('Select owning Library') %]
+
+ [% l('Browse for [_1] starting with [_2] in [_3]',
+ control_qtype, control_bterm, control_locg) %]
+
+ <input id='search-submit-go' type="submit" value="[% l('Browse') %]"
+ alt="[% l('Browse') %]" class='opac-button' />
+ <img id="browse-submit-spinner" class="hidden"
+ style="width: 16px; height: 16px;"
+ alt="[% l('Search in progress icon') %]"
+ src="[% ctx.media_prefix %]/opac/images/progressbar_green.gif[% ctx.cache_key %]" />
+ </form>
+ </div>
+
+ [% BLOCK browse_pager %]
+ [%
+ pivot_lower = CGI.param('didx') - blimit;
+ pivot_higher = CGI.param('didx') + blimit;
+ IF pivot_lower < 0;
+ pivot_lower = 0;
+ END;
+ IF CGI.param('didx') <= 0;
+ lower_limit = 1;
+ ELSE;
+ lower_limit = 0;
+ END;
+
+ IF pivot_higher > ctx.browse_results.size;
+ pivot_higher = ctx.browse_results.size - (blimit + 1);
+ upper_limit = 1;
+ ELSE;
+ upper_limit = 0;
+ END;
+ %]
+ [% IF ctx.browse_results.size >= blimit %]
+ <div class="browse-pager">
+ [% IF lower_limit == 0 %]
+ <a class="opac-button" href="[% mkurl('', {didx => pivot_lower}) %]"
+ onclick="$('browse-pager-spinner-[% id %]').className = '';"
+ >← [%l ('Back') %]</a>
+ [% END %]
+ [% IF upper_limit == 0 %]
+ <a class="opac-button" href="[% mkurl('', {didx => pivot_higher}) %]"
+ onclick="$('browse-pager-spinner-[% id %]').className = '';"
+ >[%l ('Next') %] →</a>
+ [% END %]
+ <img id="browse-pager-spinner-[% id %]"
+ src="[% ctx.media_prefix %]/opac/images/progressbar_green.gif[% ctx.cache_key %]"
+ class="hidden" style="width: 16px; height: 16px;"
+ alt="[% l('Search in progress icon') %]" />
+ </div>
+ [% END %]
+ [% END %]
+
+ [% PROCESS browse_pager id=0 %]
+
+ <div id="browse-results">
+ [% IF ctx.browse_error %]
+ <span class="browse-error">
+ [% l("An error occurred browsing records. " _
+ "Please try again in a moment or report the issue " _
+ "to library staff.") %]
+ </span>
+ [% ELSE %]
+ [% IF ctx.browse_leading_article_warning %]
+ <div class="browse-leading-article-warning">
+ [% l("Your browse term seems to begin with an article (a, an, the). You might get better results by omitting the article.") %]
+ [% IF ctx.browse_leading_article_alternative %]
+ <p>[% alternative_link = BLOCK %]
+ <a href="[% mkurl('', {bterm => ctx.browse_leading_article_alternative}, ['bpivot']) %]">[% ctx.browse_leading_article_alternative | html %]</a>
+ [%- END; # alternative_link BLOCK
+ l("Did you mean [_1]?", alternative_link);
+ END # IF %]
+ </p>
+ </div>
+ [% END # IF browse leading article warning %]
+
+ <ul class="browse-result-list">
+ [% FOR result IN ctx.browse_results %]
+ [% IF result.browse_index >= CGI.param('didx') &&
+ result.browse_index <= (CGI.param('didx') + blimit - 1) %]
+ <li class="browse-result">
+ <span class="browse-result-value[% result.match == 1 ? ' browse-result-best-match' : '' %]">
+ [% IF result.results_count > 0 %]
+ <a href="[% mkurl(ctx.opac_root _ '/course/results', {
+ 'query' => result.value, 'bool' => 'and'}
+ )%]">[% result.value | html %]</a>
+ <span class="browse-result-sources">([%
+ IF result.accurate == 'f';
+ l("At least"); " ";
+ END; #result.accurate IF
+ result.results_count %])</span>
+ [% ELSE %]
+ [% result.value | html %]
+ [% END; #result.sources IF %]
+ </span>
+ </li>
+ [% END %]
+ [% END; #result in browse_results %]
+ </ul>
+ [% END; #browse error ELSE %]
+ </div>
+
+ [% PROCESS browse_pager id=1 %]
+ </div>
+
+ <div class="common-full-pad"></div>
+ </div>
+</div>
+
+[% END %]
\ No newline at end of file