Bug 20783: Similar changes for OPAC
[koha.git] / koha-tmpl / opac-tmpl / bootstrap / js / openlibrary.js
1 if (typeof KOHA == "undefined" || !KOHA) {
2     var KOHA = {};
3 }
4
5 /**
6  * A namespace for OpenLibrary related functions.
7  */
8 KOHA.OpenLibrary = new function() {
9
10     /**
11      * Search all:
12      *    <div title="biblionumber" id="isbn" class="openlibrary-thumbnail"></div>
13      * or
14      *    <div title="biblionumber" id="isbn" class="openlibrary-thumbnail-preview"></div>
15      * and run a search with all collected isbns to Open Library Book Search.
16      * The result is asynchronously returned by OpenLibrary and catched by
17      * olCallBack().
18      */
19     this.GetCoverFromIsbn = function() {
20         var bibkeys = [];
21         $("[id^=openlibrary-thumbnail]").each(function(i) {
22             bibkeys.push("ISBN:" + $(this).attr("class")); // id=isbn
23         });
24         bibkeys = bibkeys.join(',');
25         var scriptElement = document.createElement("script");
26         scriptElement.setAttribute("id", "jsonScript");
27         scriptElement.setAttribute("src",
28             "https://openlibrary.org/api/books?bibkeys=" + escape(bibkeys) +
29             "&callback=KOHA.OpenLibrary.olCallBack&jscmd=data");
30         scriptElement.setAttribute("type", "text/javascript");
31         document.documentElement.firstChild.appendChild(scriptElement);
32     }
33
34     /**
35      * Add cover pages <div
36      * and link to preview if div id is gbs-thumbnail-preview
37      */
38     this.olCallBack = function(booksInfo) {
39         for (id in booksInfo) {
40             var book = booksInfo[id];
41             var isbn = id.substring(5);
42             $("[id^=openlibrary-thumbnail]."+isbn).each(function() {
43                 var is_opacdetail = /openlibrary-thumbnail-preview/.exec($(this).attr("id"));
44                 var a = document.createElement("a");
45                 a.href = booksInfo.url;
46                 if (book.cover) {
47                     var img = document.createElement("img");
48                     if (is_opacdetail) {
49                         img.src = book.cover.medium;
50                         $(this).empty().append(img);
51                         $(this).append('<div class="results_summary">' + '<a href="' + book.url + '">' + OL_PREVIEW + '</a></div>');
52                     } else {
53                         img.src = book.cover.medium;
54                         img.height = '110';
55                         $(this).append(img);
56                     }
57                 } else {
58                     var message =  document.createElement("span");
59                     $(message).attr("class","no-image");
60                     $(message).html(NO_OL_JACKET);
61                     $(this).append(message);
62                 }
63             });
64         }
65     }
66
67     var search_url = 'https://openlibrary.org/search?';
68     this.searchUrl = function( q ) {
69         var params = {q: q};
70         return search_url + $.param(params);
71     };
72
73     var search_url_json = 'https://openlibrary.org/search.json';
74     this.search = function( q, page_no, callback ) {
75         var params = {q: q};
76         if (page_no) {
77             params.page = page_no;
78         }
79         $.ajax( {
80             type: 'GET',
81             url: search_url_json,
82             dataType: 'json',
83             data: params,
84             error: function( xhr, error ) {
85                 try {
86                     callback( JSON.parse( xhr.responseText ));
87                 } catch ( e ) {
88                     callback( {error: xhr.responseText || true} );
89                 }
90             },
91             success: callback
92         } );
93     };
94 };
95 /* readapi_automator.js */
96
97 /*
98 This script helps to put readable links to Open Library books into
99 online book catalogs.
100 When loaded, it searches the DOM for <div> elements with class
101 "ol_readapi_book", extracts book identifiers from them (e.g. isbn,
102 lccn, etc.) and puts those into an asynchronous call to the Read API.
103 When the call returns, the results are used to add clickable links
104 to the "ol_readapi_book" elements found earlier.
105 A demonstration use of this script is available here:
106 http://internetarchive.github.com/read_api_extras/readapi_demo.html
107 */
108
109 var ol_readapi_automator =
110 (function () { // open anonymous scope for tidiness
111
112 // 'constants'
113 var readapi_bibids = ['isbn', 'lccn', 'oclc', 'olid', 'iaid', 'bibkeys'];
114 var magic_classname = 'ol_readapi_book';
115
116 // added to book divs to correlate with API results
117 var magic_bookid = 'ol_bookid';
118 var ol_button_classname = 'ol_readapi_button';
119
120 // Find all book divs and concatenate ids from them to create a read
121 // API query url
122 function create_query() {
123     var q = 'https://openlibrary.org/api/volumes/brief/json/';
124
125     function add_el(i, el) {
126         // tag with number found so it's easy to discover later
127         // (necessary?  just go by index?)
128         // (choose better name?)
129         $(el).attr(magic_bookid, i);
130
131         if (i > 0) {
132             q += '|';
133         }
134         q += 'id:' + i;
135
136         for (bi in readapi_bibids) {
137             bibid = readapi_bibids[bi];
138             if ($(el).attr(bibid)) {
139                 q += ';' + bibid + ':' + $(el).attr(bibid);
140             }
141         }
142     }
143
144     $('.' + magic_classname).each(add_el);
145     return q;
146 }
147
148 function make_read_button(bookdata) {
149     buttons = {
150         'full access':
151         "http://openlibrary.org/images/button-read-open-library.png",
152         'lendable':
153         "http://openlibrary.org/images/button-borrow-open-library.png",
154         'checked out':
155         "http://openlibrary.org/images/button-checked-out-open-library.png"
156     };
157     if (bookdata.items.length == 0) {
158         return false;
159     }
160     first = bookdata.items[0];
161     if (!(first.status in buttons)) {
162         return false;
163     }
164     result = '<a href="' + first.itemURL + '">' +
165       '<img class="' + ol_button_classname +
166       '" src="' + buttons[first.status] + '"/></a>';
167     return result;
168 }
169
170 // Default function for decorating document elements with read API data
171 function default_decorate_el_fn(el, bookdata) {
172     // Note that 'bookdata' may be undefined, if the Read API call
173     // didn't return results for this book
174     if (!bookdata) {
175         decoration = 'Not found';
176     } else {
177         decoration = make_read_button(bookdata);
178     }
179     if (decoration) {
180         el.innerHTML += decoration;
181     } else {
182         el.style.visibility = 'hidden';
183     }
184 }
185
186 function do_query(q, decorate_el_fn) {
187     if (!decorate_el_fn) {
188         decorate_el_fn = default_decorate_el_fn;
189     }
190     var starttime = (new Date()).getTime();
191
192     // Call a function on each <div class="ol_readapi_book"> element
193     // with the target element and the data found for that element.
194     // Use decorate_el_fn if supplied, falling back to
195     // default_decorate_el_fn, above.
196     function query_callback(data, textStatus, jqXHR) {
197         var endtime = (new Date()).getTime();
198         var duration = (endtime - starttime) / 1000;
199         // console.log('took ' + duration + ' seconds');
200
201         $('.' + magic_classname).each(function(i, el) {
202                 var bookid = $(el).attr(magic_bookid);
203                 if (bookid && bookid in data) {
204                     decorate_el_fn(el, data[bookid]);
205                 } else {
206                     decorate_el_fn(el);
207                 }
208             });
209     }
210
211     // console.log('calling ' + q);
212     $.ajax({ url: q,
213                 data: { 'show_all_items': 'true' },
214                 dataType: 'jsonp',
215                 success: query_callback
216                 });
217 }
218
219 // Do stuff
220 var q = create_query();
221 do_query(q);
222
223 result = {
224     do_query: do_query,
225     create_query: create_query,
226     make_read_button: make_read_button
227 };
228
229 return result;
230 })(); // close anonymous scope
231
232 /*
233 Possible futures:
234 * Support alternate query targets, e.g. Hathi
235 * show_all_items
236 * show_inlibrary
237 * ezproxy prefix (implies show_inlibrary?)
238 * console debug output? (check all console.log)
239 */