Bug 7088: (follow-up) Default hold checkbox display
[koha.git] / koha-tmpl / intranet-tmpl / prog / js / checkouts.js
1 $(document).ready(function() {
2     $.ajaxSetup ({ cache: false });
3
4     var barcodefield = $("#barcode");
5
6     var onHoldDueDateSet = false;
7
8     var onHoldChecked = function() {
9         var isChecked = false;
10         $('input[data-on-reserve]').each(function() {
11             if ($(this).is(':checked')) {
12                 isChecked=true;
13             }
14         });
15         return isChecked;
16     };
17
18     var showHideOnHoldRenewal = function() {
19         // Display the date input
20         if (onHoldChecked()) {
21             $('#newonholdduedate').show()
22         } else {
23             $('#newonholdduedate').hide();
24         }
25     };
26
27     // Handle the select all/none links for checkouts table columns
28     $("#CheckAllRenewals").on("click",function(){
29         $("#UncheckAllCheckins").click();
30         $(".renew:visible").prop("checked", true);
31         showHideOnHoldRenewal();
32         return false;
33     });
34     $("#UncheckAllRenewals").on("click",function(){
35         $(".renew:visible").prop("checked", false);
36         showHideOnHoldRenewal();
37         return false;
38     });
39
40     $("#CheckAllCheckins").on("click",function(){
41         $("#UncheckAllRenewals").click();
42         $(".checkin:visible").prop("checked", true);
43         return false;
44     });
45     $("#UncheckAllCheckins").on("click",function(){
46         $(".checkin:visible").prop("checked", false);
47         return false;
48     });
49
50     $("#newduedate").on("change", function() {
51         if (!onHoldDueDateSet) {
52             $('#newonholdduedate input').val($('#newduedate').val());
53         }
54     });
55
56     $("#newonholdduedate").on("change", function() {
57         onHoldDueDateSet = true;
58     });
59
60     // Don't allow both return and renew checkboxes to be checked
61     $(document).on("change", '.renew', function(){
62         if ( $(this).is(":checked") ) {
63             $( "#checkin_" + $(this).val() ).prop("checked", false);
64         }
65     });
66     $(document).on("change", '.checkin', function(){
67         if ( $(this).is(":checked") ) {
68             $( "#renew_" + $(this).val() ).prop("checked", false);
69         }
70     });
71
72     // Display on hold due dates input when an on hold item is
73     // selected
74     $(document).on('change', '.renew', function(){
75         showHideOnHoldRenewal();
76     });
77
78     $("#output_format > option:first-child").attr("selected", "selected");
79     $("select[name='csv_profile_id']").hide();
80     $(document).on("change", '#issues-table-output-format', function(){
81         if ( $(this).val() == 'csv' ) {
82             $("select[name='csv_profile_id']").show();
83         } else {
84             $("select[name='csv_profile_id']").hide();
85         }
86     });
87
88     // Clicking the table cell checks the checkbox inside it
89     $(document).on("click", 'td', function(e){
90         if(e.target.tagName.toLowerCase() == 'td'){
91           $(this).find("input:checkbox:visible").each( function() {
92             $(this).click();
93           });
94         }
95     });
96
97     // Handle renewals and returns
98     $("#RenewCheckinChecked").on("click",function(){
99         $(".checkin:checked:visible").each(function() {
100             itemnumber = $(this).val();
101
102             $(this).replaceWith("<img id='checkin_" + itemnumber + "' src='" + interface + "/" + theme + "/img/spinner-small.gif' />");
103
104             params = {
105                 itemnumber:     itemnumber,
106                 borrowernumber: borrowernumber,
107                 branchcode:     branchcode,
108                 exempt_fine:    $("#exemptfine").is(':checked')
109             };
110
111             $.post( "/cgi-bin/koha/svc/checkin", params, function( data ) {
112                 id = "#checkin_" + data.itemnumber;
113
114                 content = "";
115                 if ( data.returned ) {
116                     content = CIRCULATION_RETURNED;
117                     $(id).parent().parent().addClass('ok');
118                     $('#date_due_' + data.itemnumber).html(CIRCULATION_RETURNED);
119                     if ( data.patronnote != null ) {
120                         $('.patron_note_' + data.itemnumber).html("Patron note: " + data.patronnote);
121                     }
122                 } else {
123                     content = CIRCULATION_NOT_RETURNED;
124                     $(id).parent().parent().addClass('warn');
125                 }
126
127                 $(id).replaceWith( content );
128             }, "json")
129         });
130
131         $(".renew:checked:visible").each(function() {
132             var override_limit = $("#override_limit").is(':checked') ? 1 : 0;
133
134             var isOnReserve = $(this).data().hasOwnProperty('onReserve');
135
136             var itemnumber = $(this).val();
137
138             $(this).parent().parent().replaceWith("<img id='renew_" + itemnumber + "' src='" + interface + "/" + theme + "/img/spinner-small.gif' />");
139
140             var params = {
141                 itemnumber:      itemnumber,
142                 borrowernumber:  borrowernumber,
143                 branchcode:      branchcode,
144                 override_limit:  override_limit,
145             };
146
147             // Determine which due date we need to use
148             var dueDate = isOnReserve ?
149                 $("#newonholdduedate input").val() :
150                 $("#newduedate").val();
151
152             if (dueDate && dueDate.length > 0) {
153                 params.date_due = dueDate
154             }
155
156             $.post( "/cgi-bin/koha/svc/renew", params, function( data ) {
157                 var id = "#renew_" + data.itemnumber;
158
159                 var content = "";
160                 if ( data.renew_okay ) {
161                     content = CIRCULATION_RENEWED_DUE + " " + data.date_due;
162                     $('#date_due_' + data.itemnumber).replaceWith( data.date_due );
163                 } else {
164                     content = CIRCULATION_RENEW_FAILED + " ";
165                     if ( data.error == "no_checkout" ) {
166                         content += NOT_CHECKED_OUT;
167                     } else if ( data.error == "too_many" ) {
168                         content += TOO_MANY_RENEWALS;
169                     } else if ( data.error == "on_reserve" ) {
170                         content += ON_RESERVE;
171                     } else if ( data.error == "restriction" ) {
172                         content += NOT_RENEWABLE_RESTRICTION;
173                     } else if ( data.error == "overdue" ) {
174                         content += NOT_RENEWABLE_OVERDUE;
175                     } else if ( data.error ) {
176                         content += data.error;
177                     } else {
178                         content += REASON_UNKNOWN;
179                     }
180                 }
181
182                 $(id).replaceWith( content );
183             }, "json")
184         });
185
186         // Refocus on barcode field if it exists
187         if ( $("#barcode").length ) {
188             $("#barcode").focus();
189         }
190
191         // Prevent form submit
192         return false;
193     });
194
195     $("#RenewAll").on("click",function(){
196         $("#CheckAllRenewals").click();
197         $("#UncheckAllCheckins").click();
198         showHideOnHoldRenewal();
199         $("#RenewCheckinChecked").click();
200
201         // Prevent form submit
202         return false;
203     });
204
205     var ymd = $.datepicker.formatDate('yy-mm-dd', new Date());
206
207     $('#issues-table').hide();
208     $('#issues-table-actions').hide();
209     $('#issues-table-load-immediately').change(function(){
210         if ( this.checked && typeof issuesTable === 'undefined') {
211             $('#issues-table-load-now-button').click();
212         }
213         barcodefield.focus();
214     });
215     $('#issues-table-load-now-button').click(function(){
216         LoadIssuesTable();
217         barcodefield.focus();
218         return false;
219     });
220
221     if ( $.cookie("issues-table-load-immediately-" + script) == "true" ) {
222         LoadIssuesTable();
223         $('#issues-table-load-immediately').prop('checked', true);
224     }
225     $('#issues-table-load-immediately').on( "change", function(){
226         $.cookie("issues-table-load-immediately-" + script, $(this).is(':checked'), { expires: 365 });
227     });
228
229     function LoadIssuesTable() {
230         $('#issues-table-loading-message').hide();
231         $('#issues-table').show();
232         $('#issues-table-actions').show();
233
234         issuesTable = KohaTable("issues-table", {
235             "oLanguage": {
236                 "sEmptyTable" : MSG_DT_LOADING_RECORDS,
237                 "sProcessing": MSG_DT_LOADING_RECORDS,
238             },
239             "bAutoWidth": false,
240             "dom": 'B<"clearfix">rt',
241             "aoColumns": [
242                 {
243                     "mDataProp": function( oObj ) {
244                         return oObj.sort_order;
245                     }
246                 },
247                 {
248                     "mDataProp": function( oObj ) {
249                         if ( oObj.issued_today ) {
250                             return "<strong>" + TODAYS_CHECKOUTS + "</strong>";
251                         } else {
252                             return "<strong>" + PREVIOUS_CHECKOUTS + "</strong>";
253                         }
254                     }
255                 },
256                 {
257                     "mDataProp": "date_due",
258                     "bVisible": false,
259                 },
260                 {
261                     "iDataSort": 2, // Sort on hidden unformatted date due column
262                     "mDataProp": function( oObj ) {
263                         var due = oObj.date_due_formatted;
264
265                         if ( oObj.date_due_overdue ) {
266                             due = "<span class='overdue'>" + due + "</span>";
267                         }
268
269                         due = "<span id='date_due_" + oObj.itemnumber + "' class='date_due'>" + due + "</span>";
270
271                         if ( oObj.lost ) {
272                             due += "<span class='lost'>" + oObj.lost.escapeHtml() + "</span>";
273                         }
274
275                         if ( oObj.damaged ) {
276                             due += "<span class='dmg'>" + oObj.damaged.escapeHtml() + "</span>";
277                         }
278
279                         var patron_note = " <span class='patron_note_" + oObj.itemnumber + "'></span>";
280                         due +="<br>" + patron_note;
281
282                         return due;
283                     }
284                 },
285                 {
286                     "mDataProp": function ( oObj ) {
287                         title = "<span id='title_" + oObj.itemnumber + "' class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
288                               + oObj.biblionumber
289                               + "'>"
290                               + oObj.title.escapeHtml();
291
292                         $.each(oObj.subtitle, function( index, value ) {
293                                   title += " " + value.subfield.escapeHtml();
294                         });
295
296                         if ( oObj.enumchron ) {
297                             title += " (" + oObj.enumchron.escapeHtml() + ")";
298                         }
299
300                         title += "</a></span>";
301
302                         if ( oObj.author ) {
303                             title += " " + BY.replace( "_AUTHOR_",  " " + oObj.author.escapeHtml() );
304                         }
305
306                         if ( oObj.itemnotes ) {
307                             var span_class = "text-muted";
308                             if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
309                                 span_class = "circ-hlt";
310                             }
311                             title += " - <span class='" + span_class + " item-note-public'>" + oObj.itemnotes.escapeHtml() + "</span>";
312                         }
313
314                         if ( oObj.itemnotes_nonpublic ) {
315                             var span_class = "text-danger";
316                             if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
317                                 span_class = "circ-hlt";
318                             }
319                             title += " - <span class='" + span_class + " item-note-nonpublic'>" + oObj.itemnotes_nonpublic.escapeHtml() + "</span>";
320                         }
321
322                         var onsite_checkout = '';
323                         if ( oObj.onsite_checkout == 1 ) {
324                             onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
325                         }
326
327                         title += " "
328                               + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
329                               + oObj.biblionumber
330                               + "&itemnumber="
331                               + oObj.itemnumber
332                               + "#"
333                               + oObj.itemnumber
334                               + "'>"
335                               + oObj.barcode.escapeHtml()
336                               + "</a>"
337                               + onsite_checkout
338
339                         return title;
340                     },
341                     "sType": "anti-the"
342                 },
343                 {
344                     "mDataProp": function ( oObj ) {
345                         return oObj.itemtype_description.escapeHtml();
346                     }
347                 },
348                 {
349                     "mDataProp": function ( oObj ) {
350                         return ( oObj.collection ? oObj.collection.escapeHtml() : '' );
351                     }
352                 },
353                 {
354                     "mDataProp": function ( oObj ) {
355                         return ( oObj.location ? oObj.location.escapeHtml() : '' );
356                     }
357                 },
358                 {
359                     "mDataProp": function ( oObj ) {
360                         return oObj.homebranch.escapeHtml();
361                     }
362                 },
363                 {
364                     "mDataProp": "issuedate",
365                     "bVisible": false,
366                 },
367                 {
368                     "iDataSort": 9, // Sort on hidden unformatted issuedate column
369                     "mDataProp": "issuedate_formatted",
370                 },
371                 {
372                     "mDataProp": function ( oObj ) {
373                         return oObj.branchname.escapeHtml();
374                     }
375                 },
376                 {
377                     "mDataProp": function ( oObj ) {
378                         return ( oObj.itemcallnumber ? oObj.itemcallnumber.escapeHtml() : '' );
379                     }
380                 },
381                 {
382                     "mDataProp": function ( oObj ) {
383                         if ( ! oObj.charge ) oObj.charge = 0;
384                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.charge).toFixed(2) + '<span>';
385                     }
386                 },
387                 {
388                     "mDataProp": function ( oObj ) {
389                         if ( ! oObj.fine ) oObj.fine = 0;
390                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.fine).toFixed(2)  + '<span>';
391                     }
392                 },
393                 {
394                     "mDataProp": function ( oObj ) {
395                         if ( ! oObj.price ) oObj.price = 0;
396                         return '<span style="text-align: right; display: block;">' + parseFloat(oObj.price).toFixed(2) + '<span>';
397                     }
398                 },
399                 {
400                     "bSortable": false,
401                     "bVisible": AllowCirculate ? true : false,
402                     "mDataProp": function ( oObj ) {
403                         var content = "";
404                         var msg = "";
405                         var span_style = "";
406                         var span_class = "";
407
408                         if ( oObj.can_renew ) {
409                             // Do nothing
410                         } else if ( oObj.can_renew_error == "on_reserve" ) {
411                             msg += "<span>"
412                                     + "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>"
413                                     + "</span>";
414
415                             span_style = "display: none";
416                             span_class = "renewals-allowed";
417                         } else if ( oObj.can_renew_error == "too_many" ) {
418                             msg += "<span class='renewals-disabled'>"
419                                     + NOT_RENEWABLE
420                                     + "</span>";
421
422                             span_style = "display: none";
423                             span_class = "renewals-allowed";
424                         } else if ( oObj.can_renew_error == "restriction" ) {
425                             msg += "<span class='renewals-disabled'>"
426                                     + NOT_RENEWABLE_RESTRICTION
427                                     + "</span>";
428
429                             span_style = "display: none";
430                             span_class = "renewals-allowed";
431                         } else if ( oObj.can_renew_error == "overdue" ) {
432                             msg += "<span class='renewals-disabled'>"
433                                     + NOT_RENEWABLE_OVERDUE
434                                     + "</span>";
435
436                             span_style = "display: none";
437                             span_class = "renewals-allowed";
438                         } else if ( oObj.can_renew_error == "too_soon" ) {
439                             msg += "<span class='renewals-disabled'>"
440                                     + NOT_RENEWABLE_TOO_SOON.format( oObj.can_renew_date )
441                                     + "</span>";
442
443                             span_style = "display: none";
444                             span_class = "renewals-allowed";
445                         } else if ( oObj.can_renew_error == "auto_too_soon" ) {
446                             msg += "<span class='renewals-disabled'>"
447                                     + NOT_RENEWABLE_AUTO_TOO_SOON
448                                     + "</span>";
449
450                             span_style = "display: none";
451                             span_class = "renewals-allowed";
452                         } else if ( oObj.can_renew_error == "auto_too_late" ) {
453                             msg += "<span class='renewals-disabled'>"
454                                     + NOT_RENEWABLE_AUTO_TOO_LATE
455                                     + "</span>";
456
457                             span_style = "display: none";
458                             span_class = "renewals-allowed";
459                         } else if ( oObj.can_renew_error == "auto_too_much_oweing" ) {
460                             msg += "<span class='renewals-disabled'>"
461                                     + NOT_RENEWABLE_AUTO_TOO_MUCH_OWEING
462                                     + "</span>";
463
464                             span_style = "display: none";
465                             span_class = "renewals-allowed";
466                         } else if ( oObj.can_renew_error == "auto_account_expired" ) {
467                             msg += "<span class='renewals-disabled'>"
468                                     + NOT_RENEWABLE_AUTO_ACCOUNT_EXPIRED
469                                     + "</span>";
470
471                             span_style = "display: none";
472                             span_class = "renewals-allowed";
473                         } else if ( oObj.can_renew_error == "auto_renew" ) {
474                             msg += "<span class='renewals-disabled'>"
475                                     + NOT_RENEWABLE_AUTO_RENEW
476                                     + "</span>";
477
478                             span_style = "display: none";
479                             span_class = "renewals-allowed";
480                         } else if ( oObj.can_renew_error == "onsite_checkout" ) {
481                             // Don't display something if it's an onsite checkout
482                         } else if ( oObj.can_renew_error == "item_denied_renewal" ) {
483                             content += "<span class='renewals-disabled'>"
484                                     + NOT_RENEWABLE_DENIED
485                                     + "</span>";
486
487                             span_style = "display: none";
488                             span_class = "renewals-allowed";
489                         } else {
490                             msg += "<span class='renewals-disabled'>"
491                                     + oObj.can_renew_error
492                                     + "</span>";
493
494                             span_style = "display: none";
495                             span_class = "renewals-allowed";
496                         }
497
498                         var can_force_renew = ( oObj.onsite_checkout == 0 ) &&
499                             ( oObj.can_renew_error != "on_reserve" || (oObj.can_renew_error == "on_reserve" && AllowRenewalOnHoldOverride))
500                             ? true : false;
501                         var can_renew = ( oObj.renewals_remaining > 0  && !oObj.can_renew_error );
502                         content += "<span>";
503                         if ( can_renew || can_force_renew ) {
504                             content += "<span style='padding: 0 1em;'>" + oObj.renewals_count + "</span>";
505                             content += "<span class='" + span_class + "' style='" + span_style + "'>"
506                                     +  "<input type='checkbox' ";
507                             if ( oObj.date_due_overdue && can_renew ) {
508                                 content += "checked='checked' ";
509                             }
510                             if (oObj.can_renew_error == "on_reserve") {
511                                 content += "data-on-reserve ";
512                             }
513                             content += "class='renew' id='renew_" + oObj.itemnumber + "' name='renew' value='" + oObj.itemnumber +"'/>"
514                                     +  "</span>";
515                         }
516                         content += msg;
517                         if ( can_renew || can_force_renew ) {
518                             content += "<span class='renewals'>("
519                                     + RENEWALS_REMAINING.format( oObj.renewals_remaining, oObj.renewals_allowed )
520                                     + ")</span>";
521                         }
522
523                         content += "</span>";
524
525                         return content;
526                     }
527                 },
528                 {
529                     "bSortable": false,
530                     "bVisible": AllowCirculate ? true : false,
531                     "mDataProp": function ( oObj ) {
532                         if ( oObj.can_renew_error == "on_reserve" ) {
533                             return "<a href='/cgi-bin/koha/reserve/request.pl?biblionumber=" + oObj.biblionumber + "'>" + ON_HOLD + "</a>";
534                         } else {
535                             return "<input type='checkbox' class='checkin' id='checkin_" + oObj.itemnumber + "' name='checkin' value='" + oObj.itemnumber +"'></input>";
536                         }
537                     }
538                 },
539                 {
540                     "bVisible": exports_enabled == 1 ? true : false,
541                     "bSortable": false,
542                     "mDataProp": function ( oObj ) {
543                         var s = "<input type='checkbox' name='itemnumbers' value='" + oObj.itemnumber + "' style='visibility:hidden;' />";
544
545                         s += "<input type='checkbox' class='export' id='export_" + oObj.biblionumber + "' name='biblionumbers' value='" + oObj.biblionumber + "' />";
546                         return s;
547                     }
548                 }
549             ],
550             "fnFooterCallback": function ( nRow, aaData, iStart, iEnd, aiDisplay ) {
551                 var total_charge = 0;
552                 var total_fine  = 0;
553                 var total_price = 0;
554                 for ( var i=0; i < aaData.length; i++ ) {
555                     total_charge += aaData[i]['charge'] * 1;
556                     total_fine += aaData[i]['fine'] * 1;
557                     total_price  += aaData[i]['price'] * 1;
558                 }
559                 $("#totaldue").html(total_charge.toFixed(2));
560                 $("#totalfine").html(total_fine.toFixed(2));
561                 $("#totalprice").html(total_price.toFixed(2));
562             },
563             "bPaginate": false,
564             "bProcessing": true,
565             "bServerSide": false,
566             "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
567             "fnServerData": function ( sSource, aoData, fnCallback ) {
568                 aoData.push( { "name": "borrowernumber", "value": borrowernumber } );
569
570                 $.getJSON( sSource, aoData, function (json) {
571                     fnCallback(json)
572                 } );
573             },
574             "fnInitComplete": function(oSettings, json) {
575                 // Disable rowGrouping plugin after first use
576                 // so any sorting on the table doesn't use it
577                 var oSettings = issuesTable.fnSettings();
578
579                 for (f = 0; f < oSettings.aoDrawCallback.length; f++) {
580                     if (oSettings.aoDrawCallback[f].sName == 'fnRowGrouping') {
581                         oSettings.aoDrawCallback.splice(f, 1);
582                         break;
583                     }
584                 }
585
586                 oSettings.aaSortingFixed = null;
587
588                 // Build a summary of checkouts grouped by itemtype
589                 var checkoutsByItype = json.aaData.reduce(function (obj, row) {
590                     obj[row.itemtype_description] = (obj[row.itemtype_description] || 0) + 1;
591                     return obj;
592                 }, {});
593                 var ul = $('<ul>');
594                 Object.keys(checkoutsByItype).sort().forEach(function (itype) {
595                     var li = $('<li>')
596                         .append($('<strong>').html(itype || MSG_NO_ITEMTYPE))
597                         .append(': ' + checkoutsByItype[itype]);
598                     ul.append(li);
599                 })
600                 $('<details>')
601                     .addClass('checkouts-by-itemtype')
602                     .append($('<summary>').html(MSG_CHECKOUTS_BY_ITEMTYPE))
603                     .append(ul)
604                     .insertBefore(oSettings.nTableWrapper)
605             },
606         }, columns_settings_issues_table).rowGrouping(
607             {
608                 iGroupingColumnIndex: 1,
609                 iGroupingOrderByColumnIndex: 0,
610                 sGroupingColumnSortDirection: "asc"
611             }
612         );
613
614         if ( $("#issues-table").length ) {
615             $("#issues-table_processing").position({
616                 of: $( "#issues-table" ),
617                 collision: "none"
618             });
619         }
620     }
621
622     // Don't load relatives' issues table unless it is clicked on
623     var relativesIssuesTable;
624     $("#relatives-issues-tab").click( function() {
625         if ( ! relativesIssuesTable ) {
626             relativesIssuesTable = $("#relatives-issues-table").dataTable({
627                 "bAutoWidth": false,
628                 "sDom": "rt",
629                 "aaSorting": [],
630                 "aoColumns": [
631                     {
632                         "mDataProp": "date_due",
633                         "bVisible": false,
634                     },
635                     {
636                         "iDataSort": 0, // Sort on hidden unformatted date due column
637                         "mDataProp": function( oObj ) {
638                             var today = new Date();
639                             var due = new Date( oObj.date_due );
640                             if ( today > due ) {
641                                 return "<span class='overdue'>" + oObj.date_due_formatted + "</span>";
642                             } else {
643                                 return oObj.date_due_formatted;
644                             }
645                         }
646                     },
647                     {
648                         "mDataProp": function ( oObj ) {
649                             title = "<span class='strong'><a href='/cgi-bin/koha/catalogue/detail.pl?biblionumber="
650                                   + oObj.biblionumber
651                                   + "'>"
652                                   + oObj.title.escapeHtml();
653
654                             $.each(oObj.subtitle, function( index, value ) {
655                                       title += " " + value.subfield.escapeHtml();
656                             });
657
658                             if ( oObj.enumchron ) {
659                                 title += " (" + oObj.enumchron.escapeHtml() + ")";
660                             }
661
662                             title += "</a></span>";
663
664                             if ( oObj.author ) {
665                                 title += " " + BY.replace( "_AUTHOR_", " " + oObj.author.escapeHtml() );
666                             }
667
668                             if ( oObj.itemnotes ) {
669                                 var span_class = "";
670                                 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
671                                     span_class = "circ-hlt";
672                                 }
673                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes.escapeHtml() + "</span>"
674                             }
675
676                             if ( oObj.itemnotes_nonpublic ) {
677                                 var span_class = "";
678                                 if ( $.datepicker.formatDate('yy-mm-dd', new Date(oObj.issuedate) ) == ymd ) {
679                                     span_class = "circ-hlt";
680                                 }
681                                 title += " - <span class='" + span_class + "'>" + oObj.itemnotes_nonpublic.escapeHtml() + "</span>"
682                             }
683
684                             var onsite_checkout = '';
685                             if ( oObj.onsite_checkout == 1 ) {
686                                 onsite_checkout += " <span class='onsite_checkout'>(" + INHOUSE_USE + ")</span>";
687                             }
688
689                             title += " "
690                                   + "<a href='/cgi-bin/koha/catalogue/moredetail.pl?biblionumber="
691                                   + oObj.biblionumber
692                                   + "&itemnumber="
693                                   + oObj.itemnumber
694                                   + "#"
695                                   + oObj.itemnumber
696                                   + "'>"
697                                   + oObj.barcode.escapeHtml()
698                                   + "</a>"
699                                   + onsite_checkout;
700
701                             return title;
702                         },
703                         "sType": "anti-the"
704                     },
705                     {
706                         "mDataProp": function ( oObj ) {
707                             return oObj.itemtype_description.escapeHtml();
708                         }
709                     },
710                     {
711                         "mDataProp": function ( oObj ) {
712                             return ( oObj.collection ? oObj.collection.escapeHtml() : '' );
713                         }
714                     },
715                     {
716                         "mDataProp": function ( oObj ) {
717                             return ( oObj.location ? oObj.location.escapeHtml() : '' );
718                         }
719                     },
720                     {
721                         "mDataProp": "issuedate",
722                         "bVisible": false,
723                     },
724                     {
725                         "iDataSort": 7, // Sort on hidden unformatted issuedate column
726                         "mDataProp": "issuedate_formatted",
727                     },
728                     {
729                         "mDataProp": function ( oObj ) {
730                             return oObj.branchname.escapeHtml();
731                         }
732                     },
733                     {
734                         "mDataProp": function ( oObj ) {
735                             return ( oObj.itemcallnumber ? oObj.itemcallnumber.escapeHtml() : '' );
736                         }
737                     },
738                     {
739                         "mDataProp": function ( oObj ) {
740                             if ( ! oObj.charge ) oObj.charge = 0;
741                             return parseFloat(oObj.charge).toFixed(2);
742                         }
743                     },
744                     {
745                         "mDataProp": function ( oObj ) {
746                             if ( ! oObj.fine ) oObj.fine = 0;
747                             return parseFloat(oObj.fine).toFixed(2);
748                         }
749                     },
750                     {
751                         "mDataProp": function ( oObj ) {
752                             if ( ! oObj.price ) oObj.price = 0;
753                             return parseFloat(oObj.price).toFixed(2);
754                         }
755                     },
756                     {
757                         "mDataProp": function( oObj ) {
758                             return "<a href='/cgi-bin/koha/members/moremember.pl?borrowernumber=" + oObj.borrowernumber + "'>"
759                                 + oObj.borrower.firstname.escapeHtml()
760                                 + " " +
761                                 oObj.borrower.surname.escapeHtml()
762                                 + " (" + oObj.borrower.cardnumber.escapeHtml() + ")</a>"
763                         }
764                     },
765                 ],
766                 "bPaginate": false,
767                 "bProcessing": true,
768                 "bServerSide": false,
769                 "sAjaxSource": '/cgi-bin/koha/svc/checkouts',
770                 "fnServerData": function ( sSource, aoData, fnCallback ) {
771                     $.each(relatives_borrowernumbers, function( index, value ) {
772                         aoData.push( { "name": "borrowernumber", "value": value } );
773                     });
774
775                     $.getJSON( sSource, aoData, function (json) {
776                         fnCallback(json)
777                     } );
778                 },
779             });
780         }
781     });
782
783     if ( $("#relatives-issues-table").length ) {
784         $("#relatives-issues-table_processing").position({
785             of: $( "#relatives-issues-table" ),
786             collision: "none"
787         });
788     }
789
790     if ( AllowRenewalLimitOverride ) {
791         $( '#override_limit' ).click( function () {
792             if ( this.checked ) {
793                 $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
794             } else {
795                 $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
796             }
797         } ).prop('checked', false);
798     }
799  });