Bug 12550 - Add ability to delay loading of patron's checkouts in circulation and...
authorKyle M Hall <kyle@bywatersolutions.com>
Thu, 10 Jul 2014 16:37:44 +0000 (12:37 -0400)
committerTomas Cohen Arazi <tomascohen@gmail.com>
Sun, 19 Oct 2014 14:26:06 +0000 (11:26 -0300)
Now that a patron's checkouts are loaded asynchronously, we can further
improve Koha's performance by not loading the checkouts table when it is
not needed. For example, if a librarian is checking out 5 items to a
patron, we really don't need to load the table during the scanning of
items 1 to 4, just for item 5. Another example would be browsing to the
patron details table in order to change a patron's password.

Test Plan:
1) Apply this patch
2) Browse to circulation.pl for a patron
3) Note the table is not loaded automatically
4) Click the "Show checkouts" button
5) Note the checkouts table loads
6) Check the "Always show checkouts immediately" checkbox
7) Reload the page, the checkouts should now load immediately
8) Repeat steps 3-7 for the patron details page ( moremember.pl )

Signed-off-by: Jonathan Druart <jonathan.druart@biblibre.com>
Amended patch: remove trailing spaces.
Note: I am not sure the checkbox is at the best place, but I don't have
a better suggestion.

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com>
koha-tmpl/intranet-tmpl/prog/en/js/checkouts.js
koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt
koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt

index b2e47e4..910cd1f 100644 (file)
@@ -126,241 +126,260 @@ $(document).ready(function() {
 
     var ymd = $.datepicker.formatDate('yy-mm-dd', new Date());
 
-    var issuesTable;
-    var drawn = 0;
-    issuesTable = $("#issues-table").dataTable({
-        "oLanguage": {
-            "sEmptyTable" : MSG_DT_LOADING_RECORDS,
-        },
-        "bAutoWidth": false,
-        "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t",
-        "aoColumns": [
-            {
-                "mDataProp": function( oObj ) {
-                    if ( oObj.issued_today ) {
-                        return "0";
-                    } else {
-                        return "100";
-                    }
-                }
+    $('#issues-table').hide();
+    $('#issues-table-actions').hide();
+    $('#issues-table-load-now-button').click(function(){
+        LoadIssuesTable();
+        return false;
+    });
+
+    if ( $.cookie("issues-table-load-immediately-" + script) == "true" ) {
+        LoadIssuesTable();
+        $('#issues-table-load-immediately').prop('checked', true);
+    }
+    $('#issues-table-load-immediately').on( "change", function(){
+        $.cookie("issues-table-load-immediately-" + script, $(this).is(':checked'));
+    });
+
+    function LoadIssuesTable() {
+        $('#issues-table-loading-message').hide();
+        $('#issues-table').show();
+        $('#issues-table-actions').show();
+
+        issuesTable = $("#issues-table").dataTable({
+            "oLanguage": {
+                "sEmptyTable" : MSG_DT_LOADING_RECORDS,
             },
-            {
-                "mDataProp": function( oObj ) {
-                    if ( oObj.issued_today ) {
-                        return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
-                    } else {
-                        return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
+            "bAutoWidth": false,
+            "sDom": "<'row-fluid'<'span6'><'span6'>r>t<'row-fluid'>t",
+            "aoColumns": [
+                {
+                    "mDataProp": function( oObj ) {
+                        if ( oObj.issued_today ) {
+                            return "0";
+                        } else {
+                            return "100";
+                        }
                     }
-                }
-            },
-            {
-                "mDataProp": "date_due",
-                "bVisible": false,
-            },
-            {
-                "iDataSort": 1, // Sort on hidden unformatted date due column
-                "mDataProp": function( oObj ) {
-                    if ( oObj.date_due_overdue ) {
-                        return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
-                    } else {
-                        return oObj.date_due_formatted;
+                },
+                {
+                    "mDataProp": function( oObj ) {
+                        if ( oObj.issued_today ) {
+                            return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
+                        } else {
+                            return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
+                        }
                     }
-                }
-            },
-            {
-                "mDataProp": function ( oObj ) {
-                    title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
-                          + oObj.biblionumber
-                          + "'>"
-                          + oObj.title;
-
-                    $.each(oObj.subtitle, function( index, value ) {
-                              title += " " + value.subfield;
-                    });
+                },
+                {
+                    "mDataProp": "date_due",
+                    "bVisible": false,
+                },
+                {
+                    "iDataSort": 1, // Sort on hidden unformatted date due column
+                    "mDataProp": function( oObj ) {
+                        if ( oObj.date_due_overdue ) {
+                            return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
+                        } else {
+                            return oObj.date_due_formatted;
+                        }
+                    }
+                },
+                {
+                    "mDataProp": function ( oObj ) {
+                        title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
+                              + oObj.biblionumber
+                              + "'>"
+                              + oObj.title;
 
-                    title += "</a></span>";
+                        $.each(oObj.subtitle, function( index, value ) {
+                                  title += " " + value.subfield;
+                        });
 
-                    if ( oObj.author ) {
-                        title += " " + BY.replace( "_AUTHOR_",  " " + oObj.author );
-                    }
+                        title += "</a></span>";
 
-                    if ( oObj.itemnotes ) {
-                        var span_class = "";
-                        if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
-                            span_class = "circ-hlt";
+                        if ( oObj.author ) {
+                            title += " " + BY.replace( "_AUTHOR_",  " " + oObj.author );
                         }
-                        title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
-                    }
 
-                    title += " "
-                          + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
-                          + oObj.biblionumber
-                          + "&itemnumber="
-                          + oObj.itemnumber
-                          + "#"
-                          + oObj.itemnumber
-                          + "'>"
-                          + oObj.barcode
-                          + "</a>";
-
-                    return title;
-                }
-            },
-            { "mDataProp": "itemtype" },
-            { "mDataProp": "issuedate_formatted" },
-            { "mDataProp": "branchname" },
-            { "mDataProp": "itemcallnumber" },
-            {
-                "mDataProp": function ( oObj ) {
-                    if ( ! oObj.charge ) oObj.charge = 0;
-                    return parseFloat(oObj.charge).toFixed(2);
-                }
-            },
-            {
-                "mDataProp": function ( oObj ) {
-                    if ( ! oObj.price ) oObj.price = 0;
-                    return parseFloat(oObj.price).toFixed(2);
-                }
-            },
-            {
-                "bSortable": false,
-                "mDataProp": function ( oObj ) {
-                    var content = "";
-                    var span_style = "";
-                    var span_class = "";
-
-                    content += "<span>";
-                    content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
-
-                    if ( oObj.can_renew ) {
-                        // Do nothing
-                    } else if ( oObj.can_renew_error == "on_reserve" ) {
-                        content += "<span class='renewals-disabled'>"
-                                + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
-                                + "</span>";
-
-                        span_style = "display: none";
-                        span_class = "renewals-allowed";
-                    } else if ( oObj.can_renew_error == "too_many" ) {
-                        content += "<span class='renewals-disabled'>"
-                                + NOT_RENEWABLE
-                                + "</span>";
-
-                        span_style = "display: none";
-                        span_class = "renewals-allowed";
-                    } else if ( oObj.can_renew_error == "too_soon" ) {
-                        content += "<span class='renewals-disabled'>"
-                                + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
-                                + "</span>";
-
-                        span_style = "display: none";
-                        span_class = "renewals-allowed";
-                    } else if ( oObj.can_renew_error == "auto_too_soon" ) {
-                        content += "<span class='renewals-disabled'>"
-                                + NOT_RENEWABLE_AUTO_TOO_SOON
-                                + "</span>";
-
-                        span_style = "display: none";
-                        span_class = "renewals-allowed";
-                    } else if ( oObj.can_renew_error == "auto_renew" ) {
-                        content += "<span class='renewals-disabled'>"
-                                + NOT_RENEWABLE_AUTO_RENEW
-                                + "</span>";
-
-                        span_style = "display: none";
-                        span_class = "renewals-allowed";
-                    } else {
-                        content += "<span class='renewals-disabled'>"
-                                + oObj.can_renew_error
-                                + "</span>";
+                        if ( oObj.itemnotes ) {
+                            var span_class = "";
+                            if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
+                                span_class = "circ-hlt";
+                            }
+                            title += " - <span class='" + span_class + "'>" + oObj.itemnotes + "</span>"
+                        }
 
-                        span_style = "display: none";
-                        span_class = "renewals-allowed";
+                        title += " "
+                              + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
+                              + oObj.biblionumber
+                              + "&itemnumber="
+                              + oObj.itemnumber
+                              + "#"
+                              + oObj.itemnumber
+                              + "'>"
+                              + oObj.barcode
+                              + "</a>";
+
+                        return title;
+                    }
+                },
+                { "mDataProp": "itemtype" },
+                { "mDataProp": "issuedate_formatted" },
+                { "mDataProp": "branchname" },
+                { "mDataProp": "itemcallnumber" },
+                {
+                    "mDataProp": function ( oObj ) {
+                        if ( ! oObj.charge ) oObj.charge = 0;
+                        return parseFloat(oObj.charge).toFixed(2);
                     }
+                },
+                {
+                    "mDataProp": function ( oObj ) {
+                        if ( ! oObj.price ) oObj.price = 0;
+                        return parseFloat(oObj.price).toFixed(2);
+                    }
+                },
+                {
+                    "bSortable": false,
+                    "mDataProp": function ( oObj ) {
+                        var content = "";
+                        var span_style = "";
+                        var span_class = "";
 
-                    content += "<span class='" + span_class + "' style='" + span_style + "'>"
-                            +  "<input type='checkbox' class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
-                            +  "</span>";
+                        content += "<span>";
+                        content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
+
+                        if ( oObj.can_renew ) {
+                            // Do nothing
+                        } else if ( oObj.can_renew_error == "on_reserve" ) {
+                            content += "<span class='renewals-disabled'>"
+                                    + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
+                                    + "</span>";
+
+                            span_style = "display: none";
+                            span_class = "renewals-allowed";
+                        } else if ( oObj.can_renew_error == "too_many" ) {
+                            content += "<span class='renewals-disabled'>"
+                                    + NOT_RENEWABLE
+                                    + "</span>";
+
+                            span_style = "display: none";
+                            span_class = "renewals-allowed";
+                        } else if ( oObj.can_renew_error == "too_soon" ) {
+                            content += "<span class='renewals-disabled'>"
+                                    + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
+                                    + "</span>";
+
+                            span_style = "display: none";
+                            span_class = "renewals-allowed";
+                        } else if ( oObj.can_renew_error == "auto_too_soon" ) {
+                            content += "<span class='renewals-disabled'>"
+                                    + NOT_RENEWABLE_AUTO_TOO_SOON
+                                    + "</span>";
+
+                            span_style = "display: none";
+                            span_class = "renewals-allowed";
+                        } else if ( oObj.can_renew_error == "auto_renew" ) {
+                            content += "<span class='renewals-disabled'>"
+                                    + NOT_RENEWABLE_AUTO_RENEW
+                                    + "</span>";
+
+                            span_style = "display: none";
+                            span_class = "renewals-allowed";
+                        } else {
+                            content += "<span class='renewals-disabled'>"
+                                    + oObj.can_renew_error
+                                    + "</span>";
+
+                            span_style = "display: none";
+                            span_class = "renewals-allowed";
+                        }
 
-                    if ( oObj.renewals_remaining ) {
-                        content += "<span class='renewals'>("
-                                + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
-                                + ")</span>";
-                    }
+                        content += "<span class='" + span_class + "' style='" + span_style + "'>"
+                                +  "<input type='checkbox' class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
+                                +  "</span>";
+
+                        if ( oObj.renewals_remaining ) {
+                            content += "<span class='renewals'>("
+                                    + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
+                                    + ")</span>";
+                        }
 
-                    content += "</span>";
+                        content += "</span>";
 
 
-                    return content;
+                        return content;
+                    }
+                },
+                {
+                    "bSortable": false,
+                    "mDataProp": function ( oObj ) {
+                        if ( oObj.can_renew_error == "on_reserve" ) {
+                            return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
+                        } else {
+                            return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
+                        }
+                    }
+                },
+                {
+                    "bVisible": exports_enabled ? true : false,
+                    "bSortable": false,
+                    "mDataProp": function ( oObj ) {
+                        return "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
+                    }
                 }
+            ],
+            "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
+                var total_charge = 0;
+                var total_price = 0;
+                for ( var i=0; i < aaData.length; i++ ) {
+                    total_charge += aaData[i]['charge'] * 1;
+                    total_price  += aaData[i]['price'] * 1;
+                }
+                var nCells = nRow.getElementsByTagName('td');
+                nCells[1].innerHTML = total_charge.toFixed(2);
+                nCells[2].innerHTML = total_price.toFixed(2);
             },
-            {
-                "bSortable": false,
-                "mDataProp": function ( oObj ) {
-                    if ( oObj.can_renew_error == "on_reserve" ) {
-                        return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
-                    } else {
-                        return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
+            "bPaginate": false,
+            "bProcessing": true,
+            "bServerSide": false,
+            "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
+            "fnServerData": function ( sSource, aoData, fnCallback ) {
+                aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
+
+                $.getJSON( sSource, aoData, function (json) {
+                    fnCallback(json)
+                } );
+            },
+            "fnInitComplete": function(oSettings) {
+                // Disable rowGrouping plugin after first use
+                // so any sorting on the table doesn't use it
+                var oSettings = issuesTable.fnSettings();
+
+                for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
+                    if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
+                        oSettings.aoDrawCallback.splice(f, 1);
+                        break;
                     }
                 }
+
+                oSettings.aaSortingFixed = null;
             },
+        }).rowGrouping(
             {
-                "bVisible": exports_enabled ? true : false,
-                "bSortable": false,
-                "mDataProp": function ( oObj ) {
-                    return "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
-                }
-            }
-        ],
-        "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
-            var total_charge = 0;
-            var total_price = 0;
-            for ( var i=0; i < aaData.length; i++ ) {
-                total_charge += aaData[i]['charge'] * 1;
-                total_price  += aaData[i]['price'] * 1;
-            }
-            var nCells = nRow.getElementsByTagName('td');
-            nCells[1].innerHTML = total_charge.toFixed(2);
-            nCells[2].innerHTML = total_price.toFixed(2);
-        },
-        "bPaginate": false,
-        "bProcessing": true,
-        "bServerSide": false,
-        "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
-        "fnServerData": function ( sSource, aoData, fnCallback ) {
-            aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
-
-            $.getJSON( sSource, aoData, function (json) {
-                fnCallback(json)
-            } );
-        },
-        "fnInitComplete": function(oSettings) {
-            // Disable rowGrouping plugin after first use
-            // so any sorting on the table doesn't use it
-            var oSettings = issuesTable.fnSettings();
-
-            for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
-                if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
-                    oSettings.aoDrawCallback.splice(f, 1);
-                    break;
-                }
+                iGroupingColumnIndex: 1,
+                iGroupingOrderByColumnIndex: 0,
+                sGroupingColumnSortDirection: "asc"
             }
+        );
 
-            oSettings.aaSortingFixed = null;
-        },
-    }).rowGrouping(
-        {
-            iGroupingColumnIndex: 1,
-            iGroupingOrderByColumnIndex: 0,
-            sGroupingColumnSortDirection: "asc"
+        if ( $("#issues-table").length ) {
+            $("#issues-table_processing").position({
+                of: $( "#issues-table" ),
+                collision: "none"
+            });
         }
-    );
-
-    if ( $("#issues-table").length ) {
-        $("#issues-table_processing").position({
-            of: $( "#issues-table" ),
-            collision: "none"
-        });
     }
 
     // Don't load relatives' issues table unless it is clicked on
index fc61059..91eac71 100644 (file)
@@ -1,3 +1,4 @@
+[% USE Koha %]
 [% USE Branches %]
 [% USE KohaDates %]
 [% IF ( export_remove_fields OR export_with_csv_profile ) %]
@@ -33,6 +34,7 @@ var borrowernumber = "[% borrowernumber %]";
 var branchcode = "[% branch %]";
 var exports_enabled = "[% exports_enabled %]";
 var AllowRenewalLimitOverride = [% (CAN_user_circulate_override_renewals && AllowRenewalLimitOverride)? 1: 0 %];
+var script = "circulation";
 var relatives_borrowernumbers = new Array();
 [% FOREACH b IN relatives_borrowernumbers %]
     relatives_borrowernumbers.push("[% b %]");
@@ -693,6 +695,12 @@ No patron matched <span class="ex">[% message %]</span>
 <!-- SUMMARY : TODAY & PREVIOUS ISSUES -->
 <div id="checkouts">
     [% IF ( issuecount ) %]
+        <div id="issues-table-loading-message">
+            <p>
+                <a id="issues-table-load-now-button" href="#" class="btn"><i class="icon-book"></i> Show checkouts</a>
+            </p>
+        </div>
+
         <table id="issues-table">
             <thead>
                 <tr>
@@ -715,7 +723,10 @@ No patron matched <span class="ex">[% message %]</span>
             [% INCLUDE 'checkouts-table-footer.inc' %]
         </table>
 
-        <fieldset class="action">
+        <label for="issues-table-load-immediately">Always show checkouts immediately</label>
+        <input id="issues-table-load-immediately" type="checkbox" />
+
+        <fieldset id="issues-table-actions" class="action">
             [% IF ( CAN_user_circulate_override_renewals ) %]
                 [% IF ( AllowRenewalLimitOverride ) %]
                     <label for="override_limit">Override renewal limit:</label>
index 64f1fe3..24408ca 100644 (file)
@@ -1,3 +1,4 @@
+[% USE Koha %]
 [% USE KohaDates %]
 [% INCLUDE 'doc-head-open.inc' %]
 <title>Koha &rsaquo; Patrons &rsaquo;
@@ -27,6 +28,7 @@ var borrowernumber = "[% borrowernumber %]";
 var branchcode = "[% branch %]";
 var exports_enabled = "[% exports_enabled %]";
 var AllowRenewalLimitOverride = [% (CAN_user_circulate_override_renewals && AllowRenewalLimitOverride)? 1: 0 %];
+var script = "moremember";
 var relatives_borrowernumbers = new Array();
 [% FOREACH b IN relatives_borrowernumbers %]
     relatives_borrowernumbers.push("[% b %]");
@@ -410,6 +412,12 @@ function validate1(date) {
 
     <div id="checkouts">
         [% IF ( issuecount ) %]
+            <div id="issues-table-loading-message">
+                <p>
+                    <a id="issues-table-load-now-button" href="#" class="btn"><i class="icon-book"></i> Show checkouts</a>
+                </p>
+            </div>
+
             <form name="issues" action="/cgi-bin/koha/tools/export.pl" method="post" class="checkboxed">
                 <table id="issues-table" style="width: 100% !Important;">
                     <thead>
@@ -433,37 +441,42 @@ function validate1(date) {
                     [% INCLUDE 'checkouts-table-footer.inc' %]
                 </table>
 
+                <label for="issues-table-load-immediately">Always show checkouts immediately</label>
+                <input id="issues-table-load-immediately" type="checkbox" />
+
                 [% IF ( issuecount ) %]
-                    <fieldset class="action">
-                        [% IF ( CAN_user_circulate_override_renewals ) %]
-                            [% IF ( AllowRenewalLimitOverride ) %]
-                                <label for="override_limit">Override renewal limit:</label>
-                                <input type="checkbox" name="override_limit" id="override_limit" value="1" />
-                            [% END %]
-                        [% END %]
-                        <button class="btn" id="RenewCheckinChecked"><i class="icon-check"></i> Renew or return checked items</button>
-                        <button class="btn" id="RenewAll"><i class="icon-book"></i> Renew all</button>
-                    </fieldset>
-
-                    [% IF ( exports_enabled ) %]
-                        <fieldset>
-                            <label for="export_formats"><b>Export checkouts using format:</b></label>
-                            <select name="export_formats" id="export_formats">
-                                <option value="iso2709_995">ISO2709 with items</option>
-                                <option value="iso2709">ISO2709 without items</option>
-                                [% IF ( export_with_csv_profile ) %]
-                                    <option value="csv">CSV</option>
+                    <div id="issues-table-actions">
+                        <fieldset class="action">
+                            [% IF ( CAN_user_circulate_override_renewals ) %]
+                                [% IF ( AllowRenewalLimitOverride ) %]
+                                    <label for="override_limit">Override renewal limit:</label>
+                                    <input type="checkbox" name="override_limit" id="override_limit" value="1" />
                                 [% END %]
-                            </select>
-
-                           <label for="export_remove_fields">Don't export fields:</label> <input type="text" id="export_remove_fields" name="export_remove_fields" value="[% export_remove_fields %]" title="Use for iso2709 exports" />
-                            <input type="hidden" name="op" value="export" />
-                            <input type="hidden" id="export_format" name="format" value="iso2709" />
-                            <input type="hidden" id="dont_export_item" name="dont_export_item" value="0" />
-                            <input type="hidden" id="record_type" name="record_type" value="bibs" />
-                            <button class="btn btn-small" id="export_submit"><i class="icon-download-alt"></i> Export</button>
+                            [% END %]
+                            <button class="btn" id="RenewCheckinChecked"><i class="icon-check"></i> Renew or return checked items</button>
+                            <button class="btn" id="RenewAll"><i class="icon-book"></i> Renew all</button>
                         </fieldset>
-                    [% END %]
+
+                        [% IF ( exports_enabled ) %]
+                            <fieldset>
+                                <label for="export_formats"><b>Export checkouts using format:</b></label>
+                                <select name="export_formats" id="export_formats">
+                                    <option value="iso2709_995">ISO2709 with items</option>
+                                    <option value="iso2709">ISO2709 without items</option>
+                                    [% IF ( export_with_csv_profile ) %]
+                                        <option value="csv">CSV</option>
+                                    [% END %]
+                                </select>
+
+                               <label for="export_remove_fields">Don't export fields:</label> <input type="text" id="export_remove_fields" name="export_remove_fields" value="[% export_remove_fields %]" title="Use for iso2709 exports" />
+                                <input type="hidden" name="op" value="export" />
+                                <input type="hidden" id="export_format" name="format" value="iso2709" />
+                                <input type="hidden" id="dont_export_item" name="dont_export_item" value="0" />
+                                <input type="hidden" id="record_type" name="record_type" value="bibs" />
+                                <button class="btn btn-small" id="export_submit"><i class="icon-download-alt"></i> Export</button>
+                            </fieldset>
+                        [% END %]
+                    </div>
                 [% END %]
             </form>
         [% ELSE %]