Bug 20898: Replace OPAC detail's results browser with non-JavaScript version

This patch moves generation of the OPAC detail page's results browser
from JavaScript to the template. This makes the template easier to
understand and easier to debug. It also makes it possible for the widget
to be completely non-dependent on JavaScript.

To test, apply the patch and regenerate the OPAC CSS
(https://wiki.koha-community.org/wiki/Working_with_SCSS_in_the_OPAC_and_staff_client)

 - Enable the OpacBrowseResults system preference and perform a search
   in the OPAC which will return multiple results.
 - Click on any title in the first page of search results.
 - On the bibliographic detail page there should be a "Browse results"
   link in the right-hand sidebar just as before.
   - Test that the "Previous," "Back to results," and "Next" links work
     correctly.
   - Click the "Browse results" link. A list of the first 20 search
     results should appear. An arrow should indicate the title you're
     viewing.
   - Click any title in the results browser. The page should correctly
     load that record.
   - Clicking the numbered links at the top of the results browser
     should do the same.

Signed-off-by: Cab Vinton <bibliwho@gmail.com>
Signed-off-by: Katrin Fischer <katrin.fischer.83@web.de>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
This commit is contained in:
Owen Leonard 2018-08-31 14:09:01 +00:00 committed by Nick Clemens
parent 00606e1300
commit 662e64f766
4 changed files with 110 additions and 227 deletions

View file

@ -497,17 +497,24 @@
}
@media only screen and ( max-width: 1040px ) {
#a_listResults,
#close_pagination {
padding: 5px;
}
.pg_menu {
li {
a {
display: block;
float: none;
text-align: left;
}
&.back_results {
a {
border: 1px solid #D0D0D0;
border-width: 1px 0 1px 0;
border: 0;
border-bottom: 1px solid #DDD;
border-top: 1px solid #DDD;
}
}
}

View file

@ -1458,17 +1458,13 @@ div {
/* pagination */
.results-pagination {
background-color: #F3F3F3;
border: 1px solid #D0D0D0;
display: none;
height: auto;
left: -1px;
padding-bottom: 10px;
position: absolute;
top: 32px;
width: 100%;
z-index: 100;
}
.close_pagination {
display: none;
}
.back {
float: right;
@ -1481,20 +1477,19 @@ div {
.pagination_list {
ul {
padding-left: 0;
padding-top: 40px;
margin: 0;
padding: 0;
}
li {
border-top: 1px solid #DDDDDD;
color: #999;
float: bottom;
list-style: none;
padding: 4px;
&.highlight {
background-color: #F3F3F3;
border-bottom: 1px solid #DDDDDD;
border-top: 1px solid #DDDDDD;
background-color: #DDDDDD;
}
a {
@ -1503,9 +1498,8 @@ div {
}
.li_pag_index {
color: #999999;
float: left;
font-size: 15px;
color: #636363;
font-size: 90%;
font-weight: bold;
padding-right: 10px;
text-align: right;
@ -1513,37 +1507,49 @@ div {
}
}
.pagination_footer {
background-color: #E1E1E1;
text-align: center;
.close_pagination {
display: none;
}
}
.l_Results {
background-color: #E1E1E1;
.close_pagination {
float: right;
padding: 8px 12px;
}
}
.nav_results {
background-color: #F3F3F3;
border: 1px solid #D0D0D0;
font-size: 95%;
font-weight: bold;
margin-top: .5em;
position: relative;
}
.l_Results {
a {
background: #E1E1E1 url( "../images/sprite.png" ) no-repeat 0 -504px; /* Browse results menu */
color: #006699;
display: block;
padding: 8px 28px;
text-decoration: none;
}
&:hover {
background-color: #D9D9D9;
}
}
#a_listResults {
color: #006699;
display: inline-block;
padding: 8px 28px;
text-decoration: none;
}
.pg_menu {
background-color: #F3F3F3;
border-top: 1px solid #D0D0D0;
margin: 0;
white-space: nowrap;
li {
color: #B2B2B2;
display: inline;
display: inline-block;
float: left;
list-style: none;
margin: 0;
@ -1573,61 +1579,55 @@ div {
#listResults {
li {
background-color: #999999;
color: #C5C5C5;
display: block;
display: inline-block;
font-size: 80%;
font-weight: normal;
margin-right: 1px;
min-width: 18px;
padding: 0;
text-align: center;
&:hover {
background-color: #006699;
a {
background-color: #999999;
color: #FFFFFF;
display: block;
font-weight: normal;
min-width: 18px;
text-decoration: none;
&:hover {
background-color: #006699;
}
}
a {
color: #FFFFFF;
font-weight: normal;
.highlight {
a {
background-color: #616161;
}
}
}
}
/* nav */
.nav_pages {
.close_pagination {
padding-right: 10px;
position: absolute;
right: 3px;
top: -25px;
a {
text-decoration: none !important;
}
}
border-top: 1px solid #DDD;
padding: .6em;
ul {
padding-top: 10px;
display: inline-block;
margin: 0;
padding: 0;
}
li {
color: #999;
float: left;
list-style: none;
padding: 4px;
a {
text-decoration: none !important;
&:hover {
text-decoration: underline;
}
}
ul {
float: left;
}
}
}

View file

@ -1062,19 +1062,20 @@
<div class="span3">
<div id="ulactioncontainer">
[% IF ( OpacBrowseResults && busc ) %]
[% IF ( Koha.Preference('OpacBrowseResults') && busc ) %]
<div class="nav_results">
<div class="l_Results">
<div class="l_Results" style="display:none;">
[% IF ( listResults ) %]
<a href="#" id="a_listResults">Browse results</a>
<a href="#" id="a_listResults"><i class="fa fa-bars"></i> Browse results</a>
[% ELSE %]
<span>Browse results</span>
<span><i class="fa fa-bars"></i> Browse results</span>
[% END %]
<a href="#" class="close_pagination"><i class="fa fa-remove"></i> Close</a>
</div>
<ul class="pg_menu clearfix">
<li class="left_results">
[% IF ( previousBiblionumber ) %]
<a href="opac-detail.pl?biblionumber=[% previousBiblionumber | html %][% IF ( query_desc && OpacHighlightedWords ) %]&query_desc=[% query_desc |uri %][% END %]" title="See: [% IF ( previousTitle ) %][% previousTitle | html %][% ELSE %]previous biblio[% END %]">&laquo; Previous</a>
<a href="opac-detail.pl?biblionumber=[% previousBiblionumber | html %][% IF ( query_desc && OpacHighlightedWords ) %]&query_desc=[% query_desc |uri %][% END %]" title="See: [% IF ( previousTitle ) %][% previousTitle | html %][% ELSE %]previous biblio[% END %]"><i class="fa fa-angle-double-left"></i> Previous</a>
[% ELSE %]
<span>Previous</span>
[% END %]
@ -1083,7 +1084,7 @@
<li class="back_results"><a href="opac-search.pl?[% busc | html %]" title="Back to the results search list">Back to results</a></li>
<li class="right_results">
[% IF ( nextBiblionumber ) %]
<a href="opac-detail.pl?biblionumber=[% nextBiblionumber | html %][% IF ( query_desc && OpacHighlightedWords ) %]&query_desc=[% query_desc |uri %][% END %]" title="See: [% IF ( nextTitle ) %][% nextTitle | html %][% ELSE %]next biblio[% END %]">Next &raquo;</a>
<a href="opac-detail.pl?biblionumber=[% nextBiblionumber | html %][% IF ( query_desc && OpacHighlightedWords ) %]&query_desc=[% query_desc |uri %][% END %]" title="See: [% IF ( nextTitle ) %][% nextTitle | html %][% ELSE %]next biblio[% END %]">Next <i class="fa fa-angle-double-right"></i></a>
[% ELSE %]
<span>Next</span>
[% END %]
@ -1092,14 +1093,33 @@
[% IF ( listResults ) %]
<div class="results-pagination">
<div class="nav_pages">
<span class="close_pagination"><a href="#" id="close_pagination">Close</a></span>
<ul id="listResults"></ul>
<ul id="listResults">
[% FOREACH listitem IN listResults %]
[% IF ( listitem.biblionumber == biblionumber ) %]
<li class="li_pag_[% loop.count %] highlight">
[% ELSE %]
<li class="li_pag_[% loop.count %]">
[% END %]
<a href="opac-detail.pl?biblionumber=[% listitem.biblionumber %]&amp;query_desc=[% query_desc |uri %]" title="View record &quot;[% listitem.title %]&quot;" class="a_pag" id="a_pag_[% loop.count %]">[% loop.count + offset %]</a></li>
[% END %]
</ul>
</div>
<div class="pagination_list">
<ul id="ul_pagination_list"></ul>
<ul id="ul_pagination_lists">
[% FOREACH listitem IN listResults %]
[% IF ( listitem.biblionumber == biblionumber ) %]
<li id="li_pag_[% loop.count %]" class="highlight" title="Go to detail"><span class="li_pag_index"><i class="fa fa-arrow-left"></i> [% loop.count + offset %]</span><a href="opac-detail.pl?biblionumber=[% biblionumber %]&amp;query_desc=[% query_desc |uri %]">[% title %]</a><br> [% IF ( author ) %]by [% author %][% END %]</li>
[% ELSE %]
<li id="li_pag_[% loop.count %]" title="Go to detail"><span class="li_pag_index">[% loop.count + offset %]</span><a href="opac-detail.pl?biblionumber=[% listitem.biblionumber %]&amp;query_desc=[% query_desc |uri %]">[% listitem.title %]</a><br> [% IF ( listitem.author ) %]by [% listitem.author %][% END %]</li>
[% END %]
[% END %]
</ul>
</div>
</div>
[% END %]
<div class="pagination_footer">
<a href="#" class="close_pagination"><i class="fa fa-remove"></i> Close</a>
</div>
</div>
[% END # / IF OpacBrowseResults && busc %]
@ -1354,7 +1374,7 @@
[% INCLUDE 'datatables.inc' %]
[% INCLUDE 'columns_settings.inc' %]
[% IF ( SocialNetworks ) %]
<script src="https://apis.google.com/js/plusone.js"></script>
<script src="https://apis.google.com/js/plusone.js">
//<![CDATA[
{lang: '[% lang | html %]'}
//]]>
@ -1366,23 +1386,6 @@
[% IF ( OpacHighlightedWords ) %][% Asset.js("lib/jquery/plugins/jquery.highlight-3.js") | $raw %][% END %]
<script>
//<![CDATA[
[% IF ( OpacBrowseResults && busc ) %]
var arrPagination = new Array();
var pag_index_ini = [% indexPag | html %];
[% IF ( listResults ) %]
[% FOREACH listResult IN listResults %]
arrPagination[[% listResult.index | html %]] = {
url:"[% listResult.url | html %][% IF ( listResult.url && query_desc && OpacHighlightedWords ) %]&query_desc=[% query_desc |uri %][% END %]",
title:"[% listResult.title|remove('\n') | html %]",
author:"[% listResult.author | html %]",
biblionumber:[% listResult.biblionumber | html %]
};
[% END %]
[% END %]
[% END %]
[% IF ( OpacHighlightedWords ) %]
var q_array = new Array(); // holds search terms if available
@ -1420,6 +1423,19 @@
}
});
[% IF ( Koha.Preference('OpacBrowseResults') && busc ) %]
$(".l_Results").show();
$("#a_listResults").on("click", function(e){
e.preventDefault();
$(".results-pagination, .close_pagination, .pg_menu").toggle();
});
$(".close_pagination").on("click", function(e){
e.preventDefault();
$(".results-pagination, .close_pagination, .pg_menu").toggle();
});
[% END %]
var columns_settings = [% ColumnsSettings.GetColumns( 'opac', 'biblio-detail', 'holdingst', 'json' ) | $raw %];
KohaTable("#holdingst", {
@ -1528,34 +1544,6 @@
});
[% END %]
[% IF ( OpacBrowseResults && busc ) %]
var list_title_showmsg = _("Show pagination list (%s-%s / %s)").format([% indexPag | html %], [% indexPagEnd | html %], [% totalPag | html %]);
var list_title_hidemsg = _("Hide pagination list (%s-%s / %s)").format([% indexPag | html %], [% indexPagEnd | html %], [% totalPag | html %]);
if (arrPagination.length > 0) {
renderPagIndexList(pag_index_ini, $("#listResults"));
var reslist = $("#a_listResults");
reslist.attr('title', list_title_showmsg);
}
$("#a_listResults").click(function(e) {
if (arrPagination.length > 0) {
e.preventDefault();
var navigation = $(".results-pagination");
if (navigation.css("display") == 'none') {
navigation.show();
$(this).attr('title',list_title_hidemsg);
renderPagination(pag_index_ini, arrPagination.length - 1, $("#ul_pagination_list"), false);
} else {
navigation.hide();
$(this).attr('title',list_title_showmsg);
}
}
});
$("#close_pagination").click(function(e) {
e.preventDefault();
var navigation = $(".results-pagination");
navigation.hide();
});
[% END %]
[% IF ( OPACShelfBrowser ) %]
(function prepareShelfBrowser(){
@ -1721,118 +1709,6 @@
}
[% END # / IF IDreamBooksReviews || IDreamBooksReadometer %]
[% IF ( OpacBrowseResults && busc ) %]
var timeoutRFW;
var totalPagItemList = 10;
function rewindList()
{
var ul = $("#listResults");
var li_ini = ul.children(':first').next();
var index_ini = pag_index_ini;
if (li_ini) {
index_ini = parseInt(li_ini.attr("class").substring(7), 10);
}
var li_end = ul.children(':last').prev();
var index_end = arrPagination.length - 1;
if (li_end) {
index_end = parseInt(li_end.attr("class").substring(7), 10);
}
if (index_ini > pag_index_ini) {
renderPagIndexList(index_ini - 1, ul, false);
renderPagination(index_ini - 1, arrPagination.length - 1, $("#ul_pagination_list"), true);
}
}//rewindList
function forwardList()
{
var ul = $("#listResults");
var li_ini = ul.children(':first').next();
var index_ini = pag_index_ini;
if (li_ini) {
index_ini = parseInt(li_ini.attr("class").substring(7), 10);
}
var li_end = ul.children(':last').prev();
var index_end = arrPagination.length - 1;
if (li_end) {
index_end = parseInt(li_end.attr("class").substring(7), 10);
}
if (index_end < arrPagination.length - 1) {
renderPagIndexList(index_ini + 1, ul, false);
renderPagination(index_ini + 1, arrPagination.length - 1, $("#ul_pagination_list"), true);
}
}//forwardList
function renderPagIndexList(index, ul)
{
var $kids = ul.children("li");
if ($kids.length > 0) {
$kids.each(function() {
$(this).remove();
});
}
var li;
var html = "";
var ini = index - 1;
var end = ini + totalPagItemList - 1;
li = $("<li />");
html = (index > pag_index_ini)?"<a href='#' id='rew_list_index' onclick='rewindList()' title='" + _("Click to rewind the list to") + " " + ini + " - " + end + "'>&laquo;</a>":"&laquo;";
li.html(html);
ul.append(li);
var title = "";
for (var i=index; i < arrPagination.length && i < index + totalPagItemList; i++) {
if (arrPagination[i] == undefined) continue;
var li = $("<li />");
if (arrPagination[i].url != "") {
title = _("See biblio") + " &quot;" + arrPagination[i].title + "&quot; ";
if (arrPagination[i].author != "") title += " " + _("by") + "&quot;" + arrPagination[i].author + "&quot;";
title += " " + _("with biblionumber") + " " + arrPagination[i].biblionumber;
html = "<a href='" + arrPagination[i].url + "' title='" + title + "' class='a_pag' id='a_pag_" + i + "'";
html += " onmouseover='renderPagination(" + i + ", " + (arrPagination.length - 1) + ", $(\"#ul_pagination_list\"), true)'";
html += ">" + i + "</a>";
} else html = i;
li.html(html);
li.attr("class", "li_pag_" + i);
ul.append(li);
}
li = $("<li />");
ini = index + 1;
end = (arrPagination.length > index + totalPagItemList)?index + totalPagItemList:arrPagination.length - 1;
html = (end <= arrPagination.length - 1 && (end - index) >= totalPagItemList)?"<a href='#' id='fw_list_index' onclick='forwardList()' title='" + _("Click to forward the list to") + " " + ini + " - " + end + "'>&raquo;</a>":"&raquo;";
li.html(html);
ul.append(li);
}//renderPagIndexList
function renderPagination(index, total, ul, highlIndex)
{
for (var i = pag_index_ini; i <= total; i++) {
if (arrPagination[i] == undefined || arrPagination[i].url == "") continue;
$("#li_pag_" + i).remove();
}
var j = 0;
for (var i = index; i <= total && j < totalPagItemList; i++) {
if (arrPagination[i] == undefined || arrPagination[i].url == "") continue;
var li = $("<li id='li_pag_" + i + "' " + ((j % 2 == 0)?"class='highlight'":"") + " title='" + _("Go to detail") + "' />");
var html = "<span class='li_pag_index'>" + i + "</span><a href='" + arrPagination[i].url + "'>" + arrPagination[i].title + "</a>";
if (arrPagination[i].author) html += "<br /> " + _("by") + " " + arrPagination[i].author;
li.html(html);
if (highlIndex && i == index) li.css("backgroundColor", "#DDDDDD");
ul.append(li);
j++;
}
for (i = pag_index_ini; i < index && j < totalPagItemList; i++) {
if (arrPagination[i] == undefined || arrPagination[i].url == "") continue;
$("#li_pag_" + i).remove();
var li = $("<li id='li_pag_" + i + "' " + ((j % 2 == 0)?"class='highlight'":"") + " title='" + _("Go to detail") + "' />");
var html = "<span class='li_pag_index'>" + i + "</span><a href='" + arrPagination[i].url + "'>" + arrPagination[i].title + "</a>";
if (arrPagination[i].author) html += "<br /> " + _("by") + " " + arrPagination[i].author;
li.html(html);
ul.append(li);
j++;
}
}//renderPagination
[% END # / IF ( OpacBrowseResults && busc ) %]
//]]>
</script>

View file

@ -173,7 +173,6 @@ if ( $xslfile ) {
}
my $OpacBrowseResults = C4::Context->preference("OpacBrowseResults");
$template->{VARS}->{'OpacBrowseResults'} = $OpacBrowseResults;
# We look for the busc param to build the simple paging from the search
if ($OpacBrowseResults) {
@ -460,6 +459,7 @@ if ($session->param('busc')) {
}
$template->param('listResults' => \@listResults) if (@listResults);
$template->param('indexPag' => 1 + $offset, 'totalPag' => $arrParamsBusc{'total'}, 'indexPagEnd' => scalar(@arrBiblios) + $offset);
$template->param( 'offset' => $offset );
}
}