Bug 20898: Replace OPAC detail's results browser with non-JavaScript version
authorOwen Leonard <oleonard@myacpl.org>
Fri, 31 Aug 2018 14:09:01 +0000 (14:09 +0000)
committerNick Clemens <nick@bywatersolutions.com>
Thu, 6 Sep 2018 16:54:07 +0000 (16:54 +0000)
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>
koha-tmpl/opac-tmpl/bootstrap/css/src/_responsive.scss
koha-tmpl/opac-tmpl/bootstrap/css/src/opac.scss
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-detail.tt
opac/opac-detail.pl

index 321691d..5b160b8 100644 (file)
 }
 
 @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;
                 }
             }
         }
index 69387d7..de9d5b1 100644 (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;
+            }
+        }
+
+        .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;
-        }
     }
 }
 
index 975d5a3..55fe8aa 100644 (file)
         <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 %]
                             <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 %]
                         [% 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 %]
 
 [% 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 %]'}
     //]]>
 [% 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
 
             }
         });
 
+        [% 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", {
             });
     [% 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(){
         }
     [% 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>
 
index 2c61b36..2ee3fd4 100755 (executable)
@@ -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 );
 }
 }