1 /* global OD_password_required __ */
3 if ( typeof KOHA == "undefined" || !KOHA ) {
7 KOHA.OverDrive = ( function() {
8 var proxy_base_url = '/cgi-bin/koha/svc/overdrive_proxy';
9 var library_base_url = 'http://api.overdrive.com/v1/libraries/';
11 Get: function( url, params, callback ) {
14 url: url.replace( /https?:\/\/api.overdrive.com\/v[1|2]/, proxy_base_url ),
17 error: function( xhr, error ) {
19 callback( JSON.parse( xhr.responseText ));
21 callback( {error: xhr.responseText || true} );
27 GetCollectionURL: function( library_id, callback ) {
28 if ( KOHA.OverDrive.collection_url ) {
29 callback( KOHA.OverDrive.collection_url );
34 library_base_url + library_id,
42 KOHA.OverDrive.collection_url = data.links.products.href;
44 callback( data.links.products.href );
48 Search: function( library_id, q, limit, offset, callback ) {
49 KOHA.OverDrive.GetCollectionURL( library_id, function( data ) {
57 {q: q, limit: limit, offset: offset},
65 KOHA.OverDriveCirculation = new function() {
66 var svc_url = '/cgi-bin/koha/svc/overdrive';
68 var error_div = $('<div class="overdrive-error">');
69 function display_error ( error ) {
70 error_div.text(error);
73 var login_link = $('<a class="btn btn-primary" href="#">')
76 if( OD_password_required ) { $("#overdrive-login").modal('show'); }
79 .text( __("Log in to your OverDrive account") );
81 var login_div = $('<div class="overdrive-login">').append(login_link);
85 function is_logged_in() {
86 return details ? details.is_logged_in : false;
89 var checkout_popup = null;
90 $( document ).ready(function() {
91 checkout_popup = $("#overdrive-checkout");
92 $("#overdrive-login-form").submit(function(e){
94 $("#overdrive-login").modal('hide');
95 var ODpassword = $("input[name='ODpassword']").val();
99 $("#overdrive-login").on("shown.bs.modal", function(){
100 $("#ODpassword").focus();
103 var p = window.opener;
106 try { cb = p.refresh_overdrive_account_details;}
107 catch(err){ return; } //Catch error if opener is not accessible
117 function display_account (container, data) {
118 if (!data.is_logged_in) {
119 $(container).append(login_div);
123 var button_toolbar = $("<div/>").addClass("btn-toolbar").attr("role","toolbar");
125 var overdrive_link = $("<div/>").addClass("btn-group mr-2").attr("role", "group")
126 .append( $('<a href="https://www.overdrive.com/account/" target="overdrive-account" class="btn btn-sm btn-primary overdrive-link">')
127 .text( __( "OverDrive account page" ) ) );
128 button_toolbar.append(overdrive_link);
130 var logout_link = $("<div/>").addClass("btn-group mr-2").attr("role", "group")
131 .append( $('<a href="#logout" class="btn btn-sm btn-primary overdrive-logout">')
134 $(container).empty().append(error_div);
135 logout(function(data) {
136 display_account(container, data);
138 }).text( __("Log out of your OverDrive account") ) );
140 button_toolbar.append(logout_link);
142 $(container).append( button_toolbar );
144 if (data.checkouts) {
145 var checkouts_div = $('<div class="overdrive-div">').html('<h3>' + __("Checkouts") + '</h3>');
146 var checkouts_list = $('<div class="overdrive-list">');
147 data.checkouts.items.forEach(function(item) {
148 item_line(checkouts_list, item);
150 checkouts_div.append(checkouts_list);
151 $(container).append(checkouts_div);
155 var holds_div = $('<div class="overdrive-div">').html('<h3>' + __("Holds") + '</h3>');
156 var holds_list = $('<div class="overdrive-list">');
157 data.holds.items.forEach(function(item) {
158 item_line(holds_list, item);
160 holds_div.append(holds_list);
161 $(container).append(holds_div);
165 function item_line(ul_el, item) {
166 var line = $('<div class="overdrive-item">');
167 var image_container = $('<div class="overdrive-item-thumbnail">');
169 var thumb_url = item.images.thumbnail;
171 $('<img class="overdrive-thumbnail">')
172 .attr("src", thumb_url)
173 .appendTo( image_container );
176 image_container.appendTo( line );
177 var item_details = $('<div class="overdrive-item-details">')
179 $('<h4 class="overdrive-item-title">')
181 .append( $('<div class="overdrive-item-author">')
184 $('<div class="overdrive-item-subtitle">')
185 .html(item.subtitle) )
187 var actions = $('<div class="actions">');
188 display_actions(actions, item.id);
189 item_details.append( $('<div id="action_' + item.id + '" class="actions-menu">')
192 $(ul_el).append(line);
195 function svc_ajax ( method, params, success_callback ) {
201 success: function (data) {
203 display_error(data.error);
205 success_callback(data);
207 error: function(jqXHR, textStatus, errorThrown) {
208 display_error(errorThrown);
213 function load_account_details ( callback ) {
214 svc_ajax('get', { action: "account" }, function(data) {
221 svc_ajax('get', { action: "login", password: p }, function(data) {
223 if( data.login_success ){
224 $(login_div).detach();
225 if( $("#overdrive-results-page").length > 0 ){
228 KOHA.OverDriveCirculation.display_account_details( $("#opac-user-overdrive_panel") );
234 function logout (callback) {
235 svc_ajax('post', { action: "logout" }, function(data) {
241 function item_action (params, el, copies_available) {
243 svc_ajax('post', params, function(data) {
244 if (data.checkouts) {
245 details.checkouts = data.checkouts;
248 details.holds = data.holds;
250 display_actions(el, id, copies_available);
254 function item_is_checked_out (id) {
255 if ( !(details && details.checkouts) ) {
258 var id_uc = id.toUpperCase();
259 var items = details.checkouts.items;
260 for (var i = 0; i < items.length; i++) {
261 if ( items[i].id.toUpperCase() == id_uc ) {
268 function item_is_on_hold (id) {
269 if ( !(details && details.holds) ) {
272 var id_uc = id.toUpperCase();
273 var items = details.holds.items;
274 for (var i = 0; i < items.length; i++) {
275 if ( items[i].id.toUpperCase() == id_uc ) {
282 function display_actions(el, id, copies_available) {
284 if (is_logged_in()) {
286 var item = item_is_checked_out(id);
288 var expires = new Date(item.expires);
289 $('<div class="overdrive-item-status">')
290 .text( __( "Checked out until: " ) + " " + expires.toLocaleString())
294 var access = $('<a target="_blank">').appendTo(el);
295 decorate_button(access, __("Get item") );
296 svc_ajax('get', {action: "download-url", id: id}, function(data) {
297 access.attr("href", data.action.redirect);
301 $(el).append( ajax_button( __("Check in"), function() {
302 if( confirm( __("Are you sure you want to return this item?") ) ) {
303 item_action({action: "return", id: id}, el, copies_available + 1);
310 item = item_is_on_hold(id);
312 $('<span class="overdrive-item-status">')
318 if(copies_available && checkout_popup) {
319 $(el).append( ajax_button( __("Check out") , function() {
320 if( confirm( __("Are you sure you want to check out this item?") ) ) {
321 svc_ajax('post', {action: "checkout", id: id}, function(data) {
322 if (data.checkouts) {
323 details.checkouts = data.checkouts;
326 details.holds = data.holds;
328 item = display_actions(el, id, copies_available - 1);
329 if (item && item.formats && !item.format) {
330 var has_available_formats = false;
331 var lockable_formats = [];
332 for (var f in item.formats) {
333 if (item.formats[f]) {
334 has_available_formats = true;
337 lockable_formats.push(f);
340 if (!has_available_formats) {
341 checkout_format(el, id, lockable_formats, copies_available - 1);
349 $(el).append( ajax_button( __("Place hold"), function() {
350 item_action({action: "place-hold", id: id}, el, copies_available);
355 $(el).append( ajax_button( __("Cancel hold"), function() {
356 if( confirm( __("Are you sure you want to cancel this hold?") ) ) {
357 item_action({action: "remove-hold", id: id}, el, copies_available);
365 function ajax_button(label, on_click, uniqueName) {
366 var button = $('<a href="#">')
371 decorate_button(button, label, uniqueName);
375 function decorate_button(button, label, uniqueName) {
377 .addClass("btn btn-primary btn-sm")
378 .css("color","white")
380 .addClass(uniqueName);
383 function checkout_format(el, id, formats, copies_available) {
384 if (formats.length == 0) {
385 alert( __("Item cannot be checked out. There are no available formats") );
389 var checkout_format_list = checkout_popup.find("#overdrive-format-list").empty();
390 formats.forEach(function (item) {
391 var line = $("<div/>").addClass("form-check");
392 var input = '<input id="' + item + '" class="form-check-input" value="' + item + '" name="checkout-format" type="radio" /> ';
393 var label = '<label for="' + item + '">' + item + '</label>"';
394 $(input).appendTo( line );
395 $(label).appendTo( line );
396 line.appendTo( checkout_format_list );
398 checkout_popup.modal("show");
399 checkout_popup.find(".overdrive-checkout-submit").click(function(e) {
401 var format = checkout_format_list.find("input[type='radio'][name='checkout-format']:checked").val();
402 item_action({action: "checkout-format", id: id, format: format}, el, copies_available);
404 checkout_popup.modal("hide");
408 this.with_account_details = function( el, callback ) {
409 $(el).append(error_div);
410 load_account_details(function(data) {
411 if (!data.is_logged_in) {
412 $(el).append(login_div);
418 this.display_account_details = function( el ) {
419 window.refresh_overdrive_account_details = function () {
420 KOHA.OverDriveCirculation.display_account_details( el );
422 $(el).empty().append(error_div);
423 load_account_details(function(data) {
424 display_account(el, data);
428 this.display_error = function( el, error ) {
429 $(el).empty().append(error_div);
430 display_error(error);
433 this.is_logged_in = is_logged_in;
435 this.add_actions = function(el, id, copies_available) {
436 var actions = $('<span class="actions">');
437 display_actions(actions, id, copies_available);
438 $('<div id="action_'+id+'" class="actions-menu">')