[Koha-patches] [PATCH] Bug 9887 - Use DataTables on circulation page

Owen Leonard oleonard at myacpl.org
Fri Mar 22 16:10:10 CET 2013


The circulation page, when the  UseTablesortForCirc preference is
enabled, uses the old tablesorter plugin. It should use DataTables
instead.

This patch removes references to the tablesorter plugin and makes these
changes to enable use of DataTables:

- Pass two new unformatted date variables to the template from
  circulation.pl so that sorting can be performed on this data.
- Add DataTables configurations for the table of checkouts and the
  table of relatives' checkouts.
- Add a new plugin to the main DataTables configuration script to allow
  sorting on data embedded in a <span>'s 'title' attribute.
- Add <span>s to each table with a title attribute containing the
  unformatted date data which DataTables needs to perform correct
  sorting.  This eliminates the need for a special sorting algorithm to
  accomodate various date and datetime formatting options.
- Set a template variable for checking whether circ exports are enabled.
  This reduces repetition. DataTables configuration changes based on how
  many columns are present.

To test, load the circulation page for patrons who match various
conditions:

- Having only checkouts from today
- Having checkouts from today and previous days
- Having checkouts only from previous days
- Having relatives who have checkouts (from today, from previous days,
  from both)

Test these situations with UseTablesortForCirc enabled and disabled.
Test these situations with circ exports enabled or disabled (with
ExportRemoveFields filled or empty, for instance).

Sorting should work correctly on all columns with the dateformat
preference set to any option.

All other circulation functions should work normally.
---
 circ/circulation.pl                                |    2 +
 koha-tmpl/intranet-tmpl/prog/en/js/datatables.js   |   25 +++-
 .../prog/en/modules/circ/circulation.tt            |  119 +++++++++++---------
 3 files changed, 93 insertions(+), 53 deletions(-)

diff --git a/circ/circulation.pl b/circ/circulation.pl
index 24b1576..455f47b 100755
--- a/circ/circulation.pl
+++ b/circ/circulation.pl
@@ -464,7 +464,9 @@ sub build_issue_data {
         $totalprice += $it->{'replacementprice'};
         $it->{'itemtype'} = $itemtypeinfo->{'description'};
         $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'};
+        $it->{'dd_sort'} = $it->{'date_due'};
         $it->{'dd'} = output_pref($it->{'date_due'});
+        $it->{'displaydate_sort'} = $it->{'issuedate'};
         $it->{'displaydate'} = output_pref($it->{'issuedate'});
         #$it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ;
         $it->{'od'} = $it->{'overdue'};
diff --git a/koha-tmpl/intranet-tmpl/prog/en/js/datatables.js b/koha-tmpl/intranet-tmpl/prog/en/js/datatables.js
index b350211..703944e 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/js/datatables.js
+++ b/koha-tmpl/intranet-tmpl/prog/en/js/datatables.js
@@ -470,4 +470,27 @@ jQuery.extend( jQuery.fn.dataTableExt.oSort, {
     }
 } );
 
-}());
\ No newline at end of file
+}());
+/* Plugin to allow sorting on data stored in a span's title attribute
+ *
+ * Ex: <td><span title="[% ISO_date %]">[% formatted_date %]</span></td>
+ *
+ * In DataTables config:
+ *     "aoColumns": [
+ *        { "sType": "title-string" },
+ *      ]
+ * http://datatables.net/plug-ins/sorting#hidden_title_string
+ */
+jQuery.extend( jQuery.fn.dataTableExt.oSort, {
+    "title-string-pre": function ( a ) {
+        return a.match(/title="(.*?)"/)[1].toLowerCase();
+    },
+
+    "title-string-asc": function ( a, b ) {
+        return ((a < b) ? -1 : ((a > b) ? 1 : 0));
+    },
+
+    "title-string-desc": function ( a, b ) {
+        return ((a < b) ? 1 : ((a > b) ? -1 : 0));
+    }
+} );
\ No newline at end of file
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
index 19b5bd7..cae3759 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
@@ -1,4 +1,7 @@
 [% USE KohaDates %]
+[% IF ( export_remove_fields OR export_with_csv_profile ) %]
+   [% SET exports_enabled = 1 %]
+[% END %]
 [% USE KohaAuthorisedValues %]
 [% INCLUDE 'doc-head-open.inc' %]
 [% SET destination = "circ" %]
@@ -9,45 +12,57 @@
 </title>
 [% INCLUDE 'doc-head-close.inc' %]
 [% INCLUDE 'calendar.inc' %]
-[% IF ( UseTablesortForCirc ) %]<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script>[% END %]
+[% IF ( UseTablesortForCirc ) %]<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
+<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script>
+[% INCLUDE 'datatables-strings.inc' %]
+<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script>[% END %]
 <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.checkboxes.min.js"></script>
 <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery-ui-timepicker-addon.js"></script>
 <script type="text/javascript">
 //<![CDATA[
+[% IF ( UseTablesortForCirc && dateformat == 'metric' ) %]dt_add_type_uk_date();[% END %]
 [% IF ( borrowernumber ) %]if($.cookie("holdfor") != [% borrowernumber %]){ $.cookie("holdfor",null, { path: "/", expires: 0 }); }[% ELSE %]$.cookie("holdfor",null, { path: "/", expires: 0 });[% END %]
-[% IF ( UseTablesortForCirc ) %]$.tablesorter.addParser({
-    id: 'articles',
-    is: function(s) {return false;  },
-    format: function(s) { return s.toLowerCase().replace(/^(the|an|a) /,''); },
-    type: 'text'
-});[% END %]
 [% UNLESS ( borrowernumber ) %][% UNLESS ( CGIselectborrower ) %]window.onload=function(){ $('#findborrower').focus(); };[% END %][% END %]
 	 $(document).ready(function() {
-
-        $('#patronlists').tabs();
-		[% IF ( UseTablesortForCirc ) %]$.tablesorter.defaults.widgets = ['zebra'];
-		$("#issuest").tablesorter({[% IF ( dateformat_metric ) %]
-		dateFormat: 'uk',[% END %]
-		headers: { 1: { sorter: 'articles' },6: { sorter: false },7:{sorter:false},8:{sorter:false},9:{sorter:false}}
-		});
-		$("#relissuest").tablesorter({[% IF ( dateformat_metric ) %]
-		dateFormat: 'uk',[% END %]
-		headers: { 1: { sorter: 'articles' },6: { sorter: false },7:{sorter:false},8:{sorter:false},9:{sorter:false}}
-		});
-
-		//FIXME: Sorting does not work when there are previous checkouts only
-		// (It works fine when there are only checkouts of the day, or both previous and today checkouts)
-		$("#issuest").bind("sortEnd",function() {
-        	$("#previous").parents("tr").remove();  // 'previous checkouts' header chokes table sorter
-	    });
-		$("#relissuest").bind("sortEnd",function() {
-		    $("#relprevious").parents("tr").remove();  // 'previous checkouts' header chokes table sorter
-		});
-		$("#holdst").tablesorter({[% IF ( dateformat_metric ) %]
-		dateFormat: 'uk',[% END %]
-			sortList: [[0,0]],
-			headers: { 1: { sorter: 'articles' },5: { sorter: false }}
-		});[% END %]
+        $('#patronlists').tabs([% IF ( UseTablesortForCirc ) %]{
+            // Correct table sizing for tables hidden in tabs
+            // http://www.datatables.net/examples/api/tabs_and_scrolling.html
+            "show": function(event, ui) {
+                var oTable = $('div.dataTables_wrapper>table', ui.panel).dataTable();
+                if ( oTable.length > 0 ) {
+                    oTable.fnAdjustColumnSizing();
+                }
+            }
+        }[% END %]);
+        [% IF ( UseTablesortForCirc ) %]
+        $("#issuest").dataTable($.extend(true, {}, dataTablesDefaults, {
+            "sDom": 't',
+            "aaSorting": [],
+            "aoColumnDefs": [
+                { "aTargets": [ -1, -2[% IF ( exports_enabled ) %], -3[% END %] ], "bSortable": false, "bSearchable": false }
+            ],
+            "aoColumns": [
+                { "sType": "title-string" },{ "sType": "html" },null,{ "sType": "title-string" },null,null,null,null,null,null[% IF ( exports_enabled ) %],null[% END %]
+            ],
+            "bPaginate": false
+        }));
+
+        $("#relissuest").dataTable($.extend(true, {}, dataTablesDefaults, {
+            "sDom": 't',
+            "aaSorting": [],
+            "aoColumns": [
+                { "sType": "title-string" },{ "sType": "html" },null,{ "sType": "title-string" },null,null,null,null,{ "sType": "html" }
+            ],
+            "bPaginate": false
+        }));
+
+        $("#issuest").on("sort",function() {
+            $("#previous").hide();  // Don't want to see "previous checkouts" header sorted with other rows
+        });
+        $("#relissuest").on("sort",function() {
+            $("#relprevious").hide();  // Don't want to see "previous checkouts" header sorted with other rows
+        });
+        [% END %]
         [% IF ( AllowRenewalLimitOverride ) %]
         $( '#override_limit' ).click( function () {
             if ( this.checked ) {
@@ -788,11 +803,11 @@ No patron matched <span class="ex">[% message %]</span>
         <th scope="col">Price</th>
         <th scope="col">Renew <p class="column-tool"><a href="#" id="CheckAllitems">select all</a> | <a href="#" id="CheckNoitems">none</a></p></th>
         <th scope="col">Check in <p class="column-tool"><a href="#" id="CheckAllreturns">select all</a> | <a href="#" id="CheckNoreturns">none</a></p></th>
-        [% IF export_remove_fields OR export_with_csv_profile %]
+        [% IF ( exports_enabled ) %]
           <th scope="col">Export <p class="column-tool"><a href="#" id="CheckAllexports">select all</a> | <a href="#" id="CheckNoexports">none</a></p></th>
         [% END %]
-    </tr>
-[% IF ( todayissues ) %]</thead>
+    </tr></thead>
+[% IF ( todayissues ) %]
 [% INCLUDE 'checkouts-table-footer.inc' %]
 	<tbody>
 
@@ -803,11 +818,11 @@ No patron matched <span class="ex">[% message %]</span>
     <tr class="highlight">
     [% END %]
         [% IF ( todayissue.od ) %]<td class="od">[% ELSE %]<td>[% END %]
-        [% todayissue.dd %]
+        <span title="[% todayissue.dd_sort %]">[% todayissue.dd %]</span>
         </td>
         <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% todayissue.biblionumber %]&type=intra"><strong>[% todayissue.title |html %]</strong></a>[% IF ( todayissue.author ) %], by [% todayissue.author %][% END %][% IF ( todayissue.itemnotes ) %]- <span class="circ-hlt">[% todayissue.itemnotes %]</span>[% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% todayissue.biblionumber %]&itemnumber=[% todayissue.itemnumber %]#item[% todayissue.itemnumber %]">[% todayissue.barcode %]</a></td>
         <td>[% UNLESS ( noItemTypeImages ) %] [% IF ( todayissue.itemtype_image ) %]<img src="[% todayissue.itemtype_image %]" alt="" />[% END %][% END %][% todayissue.itemtype %]</td>
-        <td>[% todayissue.checkoutdate %]</td>
+        <td><span title="[% todayissue.displaydate_sort %]">[% todayissue.checkoutdate %]</span></td>
         [% IF ( todayissue.multiple_borrowers ) %]<td>[% todayissue.firstname %] [% todayissue.surname %]</td>[% END %]
         <td>[% todayissue.issuingbranchname %]</td>
         <td>[% todayissue.itemcallnumber %]</td>
@@ -860,7 +875,7 @@ No patron matched <span class="ex">[% message %]</span>
             </td>
             [% END %]
         [% END %]
-        [% IF export_remove_fields OR export_with_csv_profile %]
+        [% IF ( exports_enabled ) %]
           <td style="text-align:center;">
             <input type="checkbox" id="export_[% todayissue.biblionumber %]" name="biblionumbers" value="[% todayissue.biblionumber %]" />
             <input type="checkbox" name="itemnumbers" value="[% todayissue.itemnumber %]" style="visibility:hidden;" />
@@ -869,12 +884,12 @@ No patron matched <span class="ex">[% message %]</span>
     </tr>
     [% END %] <!-- /loop todayissues -->
     <!-- /if todayissues -->[% END %]
+
 [% IF ( previssues ) %]
-[% IF ( todayissues ) %]<tr><th colspan="11"><a name="previous" id="previous"></a>Previous checkouts</th></tr>[% ELSE %]
-<tr><th class="{sorter: false}" colspan="11"><a name="previous" id="previous"></a>Previous checkouts</th></tr></thead>
-[% INCLUDE 'checkouts-table-footer.inc' %]
-	<tbody>
-[% END %]
+    [% UNLESS ( todayissues ) %]
+        <tbody>
+    [% END %]
+    [% IF ( UseTablesortForCirc ) %]<tr id="previous"><th><span title="">Previous checkouts</span></th><th> </th><th> </th><th><span title=""></span></th><th> </th><th> </th><th> </th><th> </th><th> </th><th> </th>[% IF ( exports_enabled ) %]<th> </th>[% END %]</tr>[% ELSE %]<tr id="previous">[% IF ( exports_enabled ) %]<th colspan="11">[% ELSE %]<th colspan="10">[% END %]Previous checkouts</th></tr>[% END %]
     [% FOREACH previssue IN previssues %]
     [% IF ( loop.odd ) %]
         <tr>
@@ -882,13 +897,13 @@ No patron matched <span class="ex">[% message %]</span>
         <tr class="highlight">
     [% END %]
         [% IF ( previssue.od ) %]<td class="od">[% ELSE %]<td>[% END %]
-        [% previssue.dd %]
+        <span title="[% previssue.dd_sort %]">[% previssue.dd %]</span>
         </td>
         <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% previssue.biblionumber %]&type=intra"><strong>[% previssue.title |html %]</strong></a>[% IF ( previssue.author ) %], by [% previssue.author %][% END %] [% IF ( previssue.itemnotes ) %]- [% previssue.itemnotes %][% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% previssue.biblionumber %]&itemnumber=[% previssue.itemnumber %]#item[% previssue.itemnumber %]">[% previssue.barcode %]</a></td>
         <td>
             [% previssue.itemtype %]
         </td>
-        <td>[% previssue.displaydate %]</td>
+        <td><span title="[% previssue.displaydate_sort %]">[% previssue.displaydate %]</span></td>
         [% IF ( previssue.multiple_borrowers ) %]<td>[% previssue.firstname %] [% previssue.surname %]</td>[% END %]
         <td>[% previssue.issuingbranchname %]</td>
         <td>[% previssue.itemcallnumber %]</td>
@@ -941,7 +956,7 @@ No patron matched <span class="ex">[% message %]</span>
             </td>
             [% END %]
         [% END %]
-        [% IF export_remove_fields OR export_with_csv_profile %]
+        [% IF ( exports_enabled ) %]
           <td style="text-align:center;">
             <input type="checkbox" id="export_[% previssue.biblionumber %]" name="biblionumbers" value="[% previssue.biblionumber %]" />
             <input type="checkbox" name="itemnumbers" value="[% previssue.itemnumber %]" style="visibility:hidden;" />
@@ -963,7 +978,7 @@ No patron matched <span class="ex">[% message %]</span>
         <input type="submit" name="renew_checked" value="Renew or Return checked items" />
         <input type="submit" id="renew_all" name="renew_all" value="Renew all" />
     </fieldset>
-        [% IF export_remove_fields OR export_with_csv_profile %]
+        [% IF ( exports_enabled ) %]
             <fieldset>
             <label for="export_formats"><b>Export checkouts using format:</b></label>
             <select name="export_formats" id="export_formats">
@@ -1013,10 +1028,10 @@ No patron matched <span class="ex">[% message %]</span>
     <tr class="highlight">
     [% END %]
         [% IF ( relissue.overdue ) %]<td class="od">[% ELSE %]<td>[% END %]
-            [% relissue.dd %]</td>
+            <span title="[% relissue.dd_sort %]">[% relissue.dd %]</span></td>
         <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% relissue.biblionumber %]&type=intra"><strong>[% relissue.title |html %]</strong></a>[% IF ( relissue.author ) %], by [% relissue.author %][% END %][% IF ( relissue.itemnotes ) %]- <span class="circ-hlt">[% relissue.itemnotes %]</span>[% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% relissue.biblionumber %]&itemnumber=[% relissue.itemnumber %]#item[% relissue.itemnumber %]">[% relissue.barcode %]</a></td>
         <td>[% UNLESS ( noItemTypeImages ) %] [% IF ( relissue.itemtype_image ) %]<img src="[% relissue.itemtype_image %]" alt="" />[% END %][% END %][% relissue.itemtype %]</td>
-        <td>[% relissue.displaydate %]</td>
+        <td><span title="[% relissue.displaydate_sort %]">[% relissue.displaydate %]</span></td>
         <td>[% relissue.issuingbranchname %]</td>
         <td>[% relissue.itemcallnumber %]</td>
         <td>[% relissue.charge %]</td>
@@ -1025,7 +1040,7 @@ No patron matched <span class="ex">[% message %]</span>
     [% END %] <!-- /loop relissues -->
     <!-- /if relissues -->[% END %]
 [% IF ( relprevissues ) %]
-<tr><th class="{sorter: false}" colspan="11"><a name="relprevious" id="relprevious"></a>Previous checkouts</th></tr>
+    [% IF ( UseTablesortForCirc ) %]<tr id="relprevious"><th><span title="">Previous checkouts</span></th><th> </th><th> </th><th><span title=""></span></th><th> </th><th> </th><th> </th><th> </th><th> </th></tr>[% ELSE %]<tr id="relprevious"><th colspan="9">Previous checkouts</th></tr>[% END %]
     [% FOREACH relprevissue IN relprevissues %]
     [% IF ( loop.odd ) %]
         <tr>
@@ -1033,11 +1048,11 @@ No patron matched <span class="ex">[% message %]</span>
         <tr class="highlight">
     [% END %]
         [% IF ( relprevissue.overdue ) %]<td class="od">[% ELSE %]<td>[% END %]
-        [% relprevissue.dd %]
+        <span title="[% relprevissue.dd_sort %]">[% relprevissue.dd %]</span>
         </td>
         <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% relprevissue.biblionumber %]&type=intra"><strong>[% relprevissue.title |html %]</strong></a>[% IF ( relprevissue.author ) %], by [% relprevissue.author %][% END %] [% IF ( relprevissue.itemnotes ) %]- [% relprevissue.itemnotes %][% END %] <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% relprevissue.biblionumber %]&itemnumber=[% relprevissue.itemnumber %]#item[% relprevissue.itemnumber %]">[% relprevissue.barcode %]</a></td>
         <td>[% UNLESS noItemTypeImages %][% IF relprevissue.itemtype_image %]<img src="[% relprevissue.itemtype_image %]" alt="" />[% END %][% END %][% relprevissue.itemtype %]</td>
-        <td>[% relprevissue.displaydate %]</td>
+        <td><span title="[% relprevissue.displaydate_sort %]">[% relprevissue.displaydate %]</span></td>
         <td>[% relprevissue.issuingbranchname %]</td>
         <td>[% relprevissue.itemcallnumber %]</td>
 	[% IF ( relprevissue.multiple_borrowers ) %]<td>[% relprevissue.firstname %] [% relprevissue.surname %]</td>[% END %]
-- 
1.7.9.5


More information about the Koha-patches mailing list