Bug 32302: Hide "ISBN" label when no ISBN data when sending list
[koha.git] / koha-tmpl / opac-tmpl / bootstrap / js / recordedbooks.js
1 if ( typeof KOHA == "undefined" || !KOHA ) {
2     var KOHA = {};
3 }
4
5 KOHA.RecordedBooks = new function() {
6     var svc_url = '/cgi-bin/koha/svc/recordedbooks';
7
8     var error_div = $('<div class="recordedbooks-error">');
9     function display_error ( error ) {
10         error_div.text(error);
11     }
12
13     var details = null;
14
15     function is_identified() {
16         return details ? details.is_identified : false;
17     }
18
19     var checkout_popup = null;
20     $( document ).ready(function() {
21         checkout_popup = $("#recordedbooks-checkout");
22     });
23
24     function display_account (container, data) {
25         if (!data.is_identified) {
26             return;
27         }
28
29         if (data.checkouts) {
30             var checkouts_div = $('<div class="recordedbooks-div">').html('<h3>' + MSG_CHECKOUTS + '</h3>');
31             var items = data.checkouts.items;
32             var checkouts_list;
33             if (items.length == 0) {
34                 checkouts_list = MSG_NO_CHECKOUTS;
35             } else {
36                 checkouts_list = $('<ul class="recordedbooks-list">');
37                 data.checkouts.items.forEach(function(item) {
38                     item_line(checkouts_list, item);
39                 });
40             }
41             checkouts_div.append(checkouts_list);
42             $(container).append(checkouts_div);
43         }
44
45         if (data.holds) {
46             var holds_div = $('<div class="recordedbooks-div">').html('<h3>' + MSG_HOLDS + '</h3>');
47             var items = data.holds.items;
48             var holds_list;
49             if (items.length == 0) {
50                 holds_list = MSG_NO_HOLDS;
51             } else {
52                 holds_list = $('<ul class="recordedbooks-list">');
53                 data.holds.items.forEach(function(item) {
54                     item_line(holds_list, item);
55                 });
56             }
57             holds_div.append(holds_list);
58             $(container).append(holds_div);
59         }
60     }
61
62     function item_line(ul_el, item) {
63         var line = $('<li class="recordedbooks-item">');
64         if (item.images) {
65             var thumb_url = item.images.small;
66             if (thumb_url) {
67                 $('<img class="recordedbooks-item-thumbnail">')
68                     .attr("src", thumb_url)
69                     .appendTo(line);
70             }
71         }
72         $('<div class="recordedbooks-item-title">')
73             .text(item.title)
74             .appendTo(line);
75         $('<div class="recordedbooks-item-subtitle">')
76             .text(item.subtitle)
77             .appendTo(line);
78         $('<div class="recordedbooks-item-author">')
79             .text(item.author)
80             .appendTo(line);
81         if (item.files && item.files.length > 0) {
82             downloads = $('<div class="recordedbooks-item-author">')
83                 .text("Downloads")
84                 .appendTo(line);
85             render_downloads(downloads, item.files);
86         }
87         var actions = $('<span class="actions">');
88         display_actions(actions, item.isbn);
89         $('<div id="action_'+item.isbn+'" class="actions-menu">')
90             .append(actions)
91             .appendTo(line);
92         $('<span id="waiting_'+item.isbn+'" style="display:none;"><img class="throbber" src="' + SPINNER_THROBBER + '" /></span>').appendTo(line);
93         $(ul_el).append(line);
94     }
95
96     function render_downloads(el, files) {
97         if (files.length == 0) return;
98         var file_spec = files.shift();
99         if (/^https?:\/\/api\./.test(file_spec.url)) {
100             $.ajax({
101                 dataType: "json",
102                 url: file_spec.url,
103                 success: function (data) {
104                     append_download_link(el, data.url, data.id);
105                     render_downloads(el, files);
106                 },
107                 error: function(jqXHR, textStatus, errorThrown) {
108                     display_error(errorThrown);
109                 }
110             });
111         } else {
112             append_download_link(el, file_spec.url, file_spec.filename);
113             render_downloads(el, files);
114         }
115     }
116     function append_download_link(el, url, text) {
117         var p = $("<p>");
118         $( '<a href="' + url + '" target="recordedbooks">' )
119             .text(text)
120             .appendTo(p);
121         el.append(p);
122     }
123
124     function svc_ajax ( method, params, success_callback, callback_for_error_too ) {
125         // remove when jquery is upgraded
126         for (var key in params) {
127             if (params[key] === null) delete params[key];
128         }
129         return $.ajax({
130             method: method,
131             dataType: "json",
132             url: svc_url,
133             data: params,
134             success: function (data) {
135                 if (data.error && !callback_for_error_too) {
136                     display_error(data.error);
137                 }
138                 success_callback(data);
139             },
140             error: function(jqXHR, textStatus, errorThrown) {
141                 if (callback_for_error_too) {
142                     success_callback({error: errorThrown});
143                     return;
144                 }
145                 display_error(errorThrown);
146             }
147         });
148     }
149
150     function load_account_details ( callback ) {
151         svc_ajax('get', { action: "account" }, function(data) {
152             details = data;
153             callback(data);
154         });
155     }
156
157     function item_action (params, el) {
158         var isbn = params.isbn;
159         $("#action_"+isbn).hide();
160         $("#waiting_"+isbn).show();
161         svc_ajax('post', params, function(data) {
162             if (data.checkouts) {
163                 details.checkouts = data.checkouts;
164             }
165             if (data.holds) {
166                 details.holds = data.holds;
167             }
168             display_actions(el, isbn);
169               $("#action_"+isbn).show();
170               $("#waiting_"+isbn).hide();
171         });
172     }
173
174     function item_is_checked_out (isbn) {
175         if ( !(details && details.checkouts) ) {
176             return null;
177         }
178         var isbn_uc = isbn.toUpperCase();
179         var items = details.checkouts.items;
180         for (var i = 0; i < items.length; i++) {
181             if ( items[i].isbn.toUpperCase() == isbn_uc ) {
182                 return items[i];
183             }
184         }
185         return null;
186     }
187
188     function item_is_on_hold (isbn) {
189         if ( !(details && details.holds) ) {
190             return false;
191         }
192         var isbn_uc = isbn.toUpperCase();
193         var items = details.holds.items;
194         for (var i = 0; i < items.length; i++) {
195             if ( items[i].isbn.toUpperCase() == isbn_uc ) {
196                 return items[i];
197             }
198         }
199         return null;
200     }
201
202     function display_actions(el, isbn) {
203         $(el).empty();
204         if (is_identified()) {
205
206             var item = item_is_checked_out(isbn);
207             if (item) {
208                 var expires = new Date(item.expires);
209                 $('<span class="recordedbooks-item-status">')
210                     .text(MSG_CHECKED_OUT_UNTIL.format(expires.toLocaleString()))
211                     .appendTo(el);
212                 $(el).append(" ");
213
214                 if (item.url) {
215                     var download = $('<a href="'+item.url+'">').appendTo(el);
216                     decorate_button(download, MSG_DOWNLOAD);
217                     $(el).append(" ");
218                 }
219
220                 $(el).append( ajax_button(MSG_CHECK_IN, function() {
221                     if( confirm(MSG_CHECK_IN_CONFIRM) ) {
222                         item_action({action: "return", isbn: isbn}, el);
223                     }
224                 }) );
225
226                 return item;
227             }
228
229             item = item_is_on_hold(isbn);
230             if (item) {
231                 $('<span class="recordedbooks-status">')
232                     .text(MSG_ON_HOLD)
233                     .appendTo(el);
234                 $(el).append(" ");
235             }
236
237             if(checkout_popup) {
238                 $(el).append( ajax_button(MSG_CHECK_OUT, function() {
239                     if( confirm(MSG_CHECK_OUT_CONFIRM) ) {
240                        $("#action_"+isbn).hide();
241                        $("#waiting_"+isbn).show();
242                         svc_ajax('post', {action: "checkout", isbn: isbn}, function(data) {
243                             if (data.checkouts) {
244                                 details.checkouts = data.checkouts;
245                             }
246                             if (data.holds) {
247                                 details.holds = data.holds;
248                             }
249                             item = display_actions(el, isbn);
250                             $("#action_"+isbn).show();
251                             $("#waiting_"+isbn).hide();
252                         });
253                     }
254                 }) );
255             }
256             if (!item) {
257                 $(el).append( ajax_button(MSG_PLACE_HOLD, function() {
258                     item_action({action: "place_hold", isbn: isbn}, el);
259                 }) );
260             }
261
262             if (item) {
263                 $(el).append( ajax_button(MSG_CANCEL_HOLD, function() {
264                     if( confirm(MSG_CANCEL_HOLD_CONFIRM) ) {
265                         item_action({action: "remove_hold", isbn: isbn}, el);
266                     }
267                 }) );
268             }
269             return item;
270         }
271     }
272
273     function ajax_button(label, on_click) {
274         var button = $('<a href="#">')
275             .click(function(e) {
276                 e.preventDefault();
277                 on_click();
278             });
279         decorate_button(button, label);
280         return button;
281     }
282
283     function decorate_button(button, label) {
284         $(button)
285             .addClass("btn btn-primary btn-mini")
286             .css("color","white")
287             .text(label);
288     }
289
290     this.with_account_details = function( el, callback ) {
291         $(el).append(error_div);
292         load_account_details( callback );
293     }
294
295     this.display_account_details = function( el ) {
296         $(el).empty().append(error_div);
297         load_account_details(function(data) {
298             display_account(el, data);
299         });
300     };
301
302     this.display_error = function( el, error ) {
303         $(el).empty().append(error_div);
304         display_error(error);
305     };
306
307     this.is_identified = is_identified;
308
309     this.add_actions = function(el, isbn) {
310         var actions = $('<span class="actions">');
311         display_actions(actions, isbn);
312         $('<div id="action_'+isbn+'" class="actions-menu">')
313             .append(actions)
314             .appendTo(el);
315         $("#action_"+isbn).before('<span id="waiting_'+isbn+'" style="display:none;"><img class="throbber" src="' + SPINNER_THROBBER + '" /></span>');
316     };
317
318     this.search = function( q, page_size, page, callback ) {
319         svc_ajax('get', { action: "search", q: q, page_size: page_size, page: page }, function (data) {
320             var results;
321             if (data.results) {
322                 results = data.results;
323                 if (!results.total) {
324                     var total = results.items.length;
325                     if ( total == results.page_size ) total = total + "+";
326                     results.total = total;
327                 }
328             }
329             else results = {};
330             results.error = data.error;
331             callback(results);
332         }, true);
333     };
334 }