LP#1984269: Bootstrap opac: display of tables on small screens
authorGarry Collum <gcollum@gmail.com>
Thu, 11 Aug 2022 18:44:19 +0000 (18:44 +0000)
committerGalen Charlton <gmc@equinoxOLI.org>
Mon, 30 Jan 2023 15:07:57 +0000 (10:07 -0500)
This incorporates a generic process to display vertical tables in the Bootstrap
opac in small screens by adding a 'mobile-title' attr to any <td> elements
of the table.  This patch uses the copy_table.tt2 and results/table.tt2
as examples.

These two tables are best tested with bibs that contain items that have parts.
The results/table.tt2 is displayed by using the "Show More Details" button
on the results screen.  When the screen is sized so that the tables become
vertical the parts column is not displayed.  After the patch is applied
the parts column is displayed only on those bibs that contain parts.

For these two particular tables, it also refactors the method
in which the copies are numbered with the lists.  Prior to the patch the
mobile display would show the copy number, but it would stop at 10 for both
of these tables, because that's what was defined in CSS.  They should now
display a number for each table row displayed.

Signed-off-by: Garry Collum <gcollum@gmail.com>
Signed-off-by: John Amundson <jamundson@cwmars.org>
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>

Open-ILS/src/templates-bootstrap/opac/css/mediaQuery.css.tt2
Open-ILS/src/templates-bootstrap/opac/css/style.css.tt2
Open-ILS/src/templates-bootstrap/opac/parts/record/copy_table.tt2
Open-ILS/src/templates-bootstrap/opac/parts/result/table.tt2

index d98c372..97399f7 100644 (file)
@@ -48,42 +48,14 @@ only screen and (max-width: 650px)  {
         padding-right: 10px;
         white-space: nowrap;
         position: absolute;
+        font-weight: bold;
+        content :attr(mobile-title);
+        text-align: left;
     }
-    .copyTable tr:nth-of-type(1):before { content: "Copy #1"; display: block; text-align:center; }
-    .copyTable tr:nth-of-type(2):before { content: "Copy #2"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(3):before { content: "Copy #3"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(4):before { content: "Copy #4"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(5):before { content: "Copy #5"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(6):before { content: "Copy #6"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(7):before { content: "Copy #7"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(8):before { content: "Copy #8"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(9):before { content: "Copy #9"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(10):before { content: "Copy #10"; display: block; text-align:center;}
-
-    .copyTable td:nth-of-type(1):before { content: "Library"; display: flex; }
-    .copyTable td:nth-of-type(2):before { content: "Call Number"; display: flex; }
-    .copyTable td:nth-of-type(3):before { content: "Barcode"; display: flex;}
-    .copyTable td:nth-of-type(4):before { content: "Shelving Location"; display: flex;}
-    .copyTable td:nth-of-type(5):before { content: "Status"; display: flex;}
-    .copyTable td:nth-of-type(6):before { content: "Due Date"; display: flex;}
-    .copyTable td:nth-of-type(7):before { content: "[% l('Distance') %]"; display: flex;}
-
-    .holdingsTable tr:nth-of-type(1):before { content: "Copy #1"; display: block; text-align:center; }
-    .holdingsTable tr:nth-of-type(2):before { content: "Copy #2"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(3):before { content: "Copy #3"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(4):before { content: "Copy #4"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(5):before { content: "Copy #5"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(6):before { content: "Copy #6"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(7):before { content: "Copy #7"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(8):before { content: "Copy #8"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(9):before { content: "Copy #9"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(10):before { content: "Copy #10"; display: block; text-align:center;}
-
-
-    .holdingsTable td:nth-of-type(1):before { content: "Library"; display: flex; }
-    .holdingsTable td:nth-of-type(2):before { content: "Shelving location"; display: flex; }
-    .holdingsTable td:nth-of-type(3):before { content: "Call number"; display: flex;}
-    .holdingsTable td:nth-of-type(4):before { content: "Status"; display: flex;}
+
+    .copyTable tr:before { content: attr(mobile-count); display: block; text-align:center; }
+    .holdingsTable tr:before { content: attr(mobile-count); display: block; text-align:center; }
+
 
     .chargesTable td:nth-of-type(1):before { content: "Select"; display: flex; }
     .chargesTable td:nth-of-type(2):before { content: "Owed"; display: flex; }
index fbbd9dd..be545fe 100755 (executable)
@@ -69,42 +69,14 @@ only screen and (max-width: 650px)  {
         padding-right: 10px;
         white-space: nowrap;
         position: absolute;
+        content: attr(mobile-title);
+        font-weight: bold;
+        text-align: left;
     }
-    .copyTable tr:nth-of-type(1):before { content: "Copy #1"; display: block; text-align:center; }
-    .copyTable tr:nth-of-type(2):before { content: "Copy #2"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(3):before { content: "Copy #3"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(4):before { content: "Copy #4"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(5):before { content: "Copy #5"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(6):before { content: "Copy #6"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(7):before { content: "Copy #7"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(8):before { content: "Copy #8"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(9):before { content: "Copy #9"; display: block; text-align:center;}
-    .copyTable tr:nth-of-type(10):before { content: "Copy #10"; display: block; text-align:center;}
-
-    .copyTable td:nth-of-type(1):before { content: "Library"; display: flex; }
-    .copyTable td:nth-of-type(2):before { content: "Call Number"; display: flex; }
-    .copyTable td:nth-of-type(3):before { content: "Barcode"; display: flex;}
-    .copyTable td:nth-of-type(4):before { content: "Shelving Location"; display: flex;}
-    .copyTable td:nth-of-type(5):before { content: "Status"; display: flex;}
-    .copyTable td:nth-of-type(6):before { content: "Due Date"; display: flex;}
-    .copyTable td:nth-of-type(7):before { content: "[% l('Distance') %]"; display: flex;}
-
-    .holdingsTable tr:nth-of-type(1):before { content: "Copy #1"; display: block; text-align:center; }
-    .holdingsTable tr:nth-of-type(2):before { content: "Copy #2"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(3):before { content: "Copy #3"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(4):before { content: "Copy #4"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(5):before { content: "Copy #5"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(6):before { content: "Copy #6"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(7):before { content: "Copy #7"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(8):before { content: "Copy #8"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(9):before { content: "Copy #9"; display: block; text-align:center;}
-    .holdingsTable tr:nth-of-type(10):before { content: "Copy #10"; display: block; text-align:center;}
-
-
-    .holdingsTable td:nth-of-type(1):before { content: "Library"; display: flex; }
-    .holdingsTable td:nth-of-type(2):before { content: "Shelving location"; display: flex; }
-    .holdingsTable td:nth-of-type(3):before { content: "Call number"; display: flex;}
-    .holdingsTable td:nth-of-type(4):before { content: "Status"; display: flex;}
+    
+    .copyTable tr::before { content: attr(mobile-count); display: block; text-align:center; }
+    .holdintsTable tr::before { content: attr(mobile-count); display: block; text-align:center; }
+
 
     .chargesTable td:nth-of-type(1):before { content: "Select"; display: flex; }
     .chargesTable td:nth-of-type(2):before { content: "Owed"; display: flex; }
index ca11395..de11514 100755 (executable)
@@ -81,7 +81,7 @@ IF has_copies or ctx.foreign_copies;
   </a>
 [% END %]
 
-<table class="container-fluid table table-hover mt-4 miniTable copyTable w-100" >
+<table class="container-fluid table table-hover mt-4 miniTable copyTable" >
     <thead>
         <tr>
             [% IF serial_holdings -%]
@@ -156,17 +156,17 @@ END; # FOREACH bib
                 callnum = callnum  _ " " _ callnum_suffix;
             END;
         -%]
-        <tr property="offers" typeof="Offer">
+        <tr property="offers" typeof="Offer" mobile-count="#[% loop.count %]">
             [%- IF serial_holdings %]
             <td class='rdetail-issue-issue'>
                 [%- copy_info.holding_label | html; -%]
             </td>
-            [%- ELSE %]<td>
+            [%- ELSE %]<td mobile-title="[% l('Location') %]">
             [%- INCLUDE "opac/parts/library_name_link.tt2"; -%]
                 <link property="businessFunction" href="http://purl.org/goodrelations/v1#LeaseOut">
                 <meta property="price" content="0.00">
             </td>[% END %]
-            <td><span property="sku">[% callnum | html %]</span> [% IF ctx.get_org_setting(CGI.param('loc')
+            <td mobile-title="[% l('Call Number/Copy Notes') %]"><span property="sku">[% callnum | html %]</span> [% IF ctx.get_org_setting(CGI.param('loc')
                 OR ctx.aou_tree.id, 'sms.enable') == 1 %](<a href="[% mkurl(ctx.opac_root _ '/sms_cn',
                {copy_id => copy_info.id}) %];rec=[%- ctx.bre_id -%]" rel="nofollow" vocab="">Text</a>)[% END %]
 
@@ -201,9 +201,9 @@ END; # FOREACH bib
         [% END %]
         </td>
             [%- IF has_parts == 'true' %]
-            <td>[% copy_info.part_label | html %]</td>
+            <td mobile-title="[% l('Parts') %]">[% copy_info.part_label | html %]</td>
             [%- END %]
-            <td property="serialNumber">
+            <td mobile-title="[% l('Barcode')%]" property="serialNumber">
                 [% copy_info.barcode | html -%]
                 [% IF ctx.is_staff %]
                   [%- IF ctx.is_browser_staff %]
@@ -231,18 +231,18 @@ END; # FOREACH bib
                     '<meta property="gtin13" content="' _ attrs.gtin13 _ '" />';
                 END; -%]
             </td>
-            <td property="availableAtOrFrom">[%- INCLUDE "opac/parts/location_name_link.tt2"; -%]</td>
+            <td mobile-title="[% l('Shelving Location')%]" property="availableAtOrFrom">[%- INCLUDE "opac/parts/location_name_link.tt2"; -%]</td>
             [% IF copy_info.courses.size > 0 || ctx.is_staff %]
-            <td>[% copy_info.circ_modifier | html %]</td>
+            <td mobile-title="[% l('Circulation Modifier') %]">[% copy_info.circ_modifier | html %]</td>
             [% ELSIF ctx.use_courses %]
             <td></td>
             [% END %]
             [% IF ctx.is_staff %]
-            <td>
+            <td mobile-title="[% l('Age Hold Protection') %]">
                 [% copy_info.age_protect ?
                     ctx.get_crahp(copy_info.age_protect).name : l('None') | html %]
             </td>
-            <td>[%
+            <td mobile-title="[% l('Active/Create Date') %]">[%
                 IF ctx.get_org_setting(copy_info.circ_lib, 'circ.holds.age_protect.active_date') == 1;
                     disp_date = copy_info.active_date ? copy_info.active_date : copy_info.create_date;
                 ELSE;
@@ -260,7 +260,7 @@ END; # FOREACH bib
             %]</td>
             [% END # is_staff %]
             [% IF ctx.is_staff OR serial_holdings %]
-            <td>[%  # Show copy/volume hold links to staff (without
+            <td mobile-title="[% l('Holdable') %]">[%  # Show copy/volume hold links to staff (without
                 # checking whether they have permissions to do those).
                 overall_holdable = (
                     copy_info.holdable == 't' AND
@@ -308,11 +308,11 @@ END; # FOREACH bib
                     l("Not holdable");
                 END %]</td>
             [%- END %]
-            <td>[%-
+            <td mobile-title="[% l('Status') %]">[%-
                 schema_copy_status.${copy_info.status_code};
                 copy_info.copy_status | html;
             -%]</td>
-            <td>[%
+            <td mobile-title="[% l('Due Date') %]">[%
                 IF copy_info.due_date;
                     date.format(
                         ctx.parse_datetime(copy_info.due_date, copy_info.circ_circ_lib),
@@ -322,12 +322,12 @@ END; # FOREACH bib
                     '-';
                 END %]</td>
             [%- IF ctx.use_courses %]
-            <td>[%- FOREACH course IN copy_info.courses %]
+            <td mobile-title="[% l('Courses') %]">[%- FOREACH course IN copy_info.courses %]
                 <div>[% course.course_number %]</div>
             [% END %]</td>
             [% END %]
             [%- IF ctx.geo_sort && ctx.has_valid_coords %]
-                <td>[% display_ou_distance(copy_info.circ_lib) %]</td>
+                <td mobile-title="[% l('Distance') %]">[% display_ou_distance(copy_info.circ_lib) %]</td>
             [%- END %]
         </tr>
 
index ce8ab19..e361dc4 100755 (executable)
 
                                     [%- IF !show_detail_view AND args.holdings.size > 0 %]
                                         <div class="result_call_number">
-                                            [% l('Call number:') %] [% args.holdings.0.label | html %]
+                                            [% l('Call Number:') %] [% args.holdings.0.label | html %]
                                         </div>
                                     [% END %]
 
                                                     <table role="presentation" title="[% l('Record Holdings Details') %]" class='container-fluid table table-hover mt-4 miniTable holdingsTable'>
                                                         <thead>
                                                             <tr>
-                                                                <th>[% l('Library') %]</th>
-                                                                <th>[% l('Shelving location') %]</th>
-                                                                <th>[% l('Call number') %]</th>
+                                                                <th>[% l('Location') %]</th>
+                                                                <th>[% l('Shelving Location') %]</th>
+                                                                <th>[% l('Call Number') %]</th>
                                                                 [%- IF has_parts == 'true'; %]
                                                                 <th>[% l('Part') %]</th>
                                                                 [%- END %]
                                                         </thead>
                                                     <tbody>
                                                     [% FOR copy IN args.holdings %]
-                                                        <tr>
-                                                            <td><span class="sr-only">[% l('Library') %] </span>[%- copy_info = copy; INCLUDE "opac/parts/library_name_link.tt2"; %]</td>
-                                                            <td><span class="sr-only">[% l('Shelving Location') %] </span>[% copy.location | html %]</td>
-                                                            <td><span class="sr-only">[% l('Call Number') %] </span>[% copy.label | html %]</td>
+                                                        <tr mobile-count="#[% loop.count %]">
+                                                            <td mobile-title="[% l('Location') %]"><span class="sr-only">Location </span>[%- copy_info = copy; INCLUDE "opac/parts/library_name_link.tt2"; %]</td>
+                                                            <td mobile-title="[% l('Shelving Location') %]"><span class="sr-only">Shelving Location </span>[% copy.location | html %]</td>
+                                                            <td mobile-title="[% l('Call Number') %]"><span class="sr-only">Call Number </span>[% copy.label | html %]</td>
                                                             [%- IF has_parts == 'true'; %]
-                                                            <td><span class="sr-only">[% l('Part') %] </span>[% copy.part_label %]</td>
+                                                            <td mobile-title="[% l('Part') %]"><span class="sr-only">Part </span>[% copy.part_label %]</td>
                                                             [%- END %]
-                                                            <td><span class="sr-only">[% l('Status') %] </span>[% copy.status | html %]</td>
+                                                            <td mobile-title="[% l('Status') %]"><span class="sr-only">Status </span>[% copy.status | html %]</td>
                                                         </tr>
                                                     [% END %]
                                                     </tbody>