Initial dev repository
[kcls-web.git] / opac / skin / nogrey1 / js / rdetail.js
1 /* */\r
2 dojo.require('openils.BibTemplate');\r
3 \r
4 if(findCurrentPage()==RDETAIL){\r
5 detachAllEvt('common', 'run');\r
6 attachEvt("common", "run", rdetailDraw);\r
7 attachEvt("rdetail", "recordDrawn", rdetailBuildStatusColumns);\r
8 attachEvt("rdetail", "recordDrawn", rdetailBuildInfoRows);\r
9 attachEvt("rdetail", "recordDrawn", rdetailGetPageIds);\r
10 \r
11 /* Per-skin configuration settings */\r
12 var rdetailLocalOnly = true;\r
13 var rdetailShowLocal = true;\r
14 var rdetailShowCopyLocation = true;\r
15 var rdetailGoogleBookPreview = false;\r
16 var rdetailDisplaySerialHoldings = true;\r
17 var rdetailEnableRefWorks = false;\r
18 var rdetailRefWorksHost = 'http://www.refworks.com';\r
19 \r
20 /* vars vars vars */\r
21 var record = null;\r
22 var cp_statuses = null;\r
23 var recordsCache = [];\r
24 \r
25 var copyRowParent = null;\r
26 var copyRow = null;\r
27 var statusRow = null;\r
28 var numStatuses = null;\r
29 var defaultCN;\r
30 var callnumberCache = {};\r
31 var globalCNCache = {};\r
32 var localTOC;\r
33 var cachedRecords;\r
34 var _statusPositions = {};\r
35 var opac_strings;\r
36 \r
37 var nextContainerIndex;\r
38 \r
39 var nextRecord;\r
40 var prevRecord;\r
41 \r
42 var rdetailPrev = null;\r
43 var rdetailNext = null;\r
44 var rdetailStart = null;\r
45 var rdetailEnd = null;\r
46 \r
47 if(location.href.match(/&place_hold=1/)) {\r
48     // prevent load flicker between canvases\r
49     hideMe(dojo.byId('canvas_main'));\r
50 }\r
51 \r
52 /* serials are currently the only use of Dojo strings in the OPAC */\r
53         if (rdetailDisplaySerialHoldings) {\r
54                 dojo.require("dijit.Menu");\r
55                 dojo.require("dijit.form.Button");\r
56                 dojo.requireLocalization("openils.opac", "opac");\r
57                 opac_strings = dojo.i18n.getLocalization("openils.opac", "opac");\r
58         }\r
59 }\r
60 \r
61 function rdetailReload() {\r
62         var args = {};\r
63         args[PARAM_LOCATION] = getNewSearchLocation();\r
64         args[PARAM_DEPTH] = depthSelGetDepth();\r
65         goTo(buildOPACLink(args));\r
66 }\r
67 \r
68 /* looks to see if we have a next and/or previous record in the\r
69    record cache, if so, set up the nav links */\r
70 function rdetailSetPaging(ids) {\r
71 \r
72         cachedRecords = {};\r
73         cachedRecords.ids = ids;\r
74 \r
75         for( var i = 0; i < cachedRecords.ids.length; i++ ) {\r
76                 var rec = cachedRecords.ids[i];\r
77                 if( rec == getRid() ) {\r
78                         if( i > 0 ) prevRecord = cachedRecords.ids[i-1];\r
79                         if( i < cachedRecords.ids.length - 1 )\r
80                                 nextRecord = cachedRecords.ids[i+1];\r
81                         break;\r
82                 }\r
83         }\r
84 \r
85         $('np_offset').appendChild(text(i + 1));\r
86         $('np_count').appendChild(text(getHitCount()));\r
87 \r
88         if(prevRecord) {\r
89                 unHideMe($('np_table'));\r
90                 unHideMe($('np_prev'));\r
91                 unHideMe($('np_start'));\r
92                 rdetailPrev = function() { _rdetailNav(prevRecord); };\r
93                 rdetailStart = function() { _rdetailNav(cachedRecords.ids[0]); };\r
94         }\r
95 \r
96         if(nextRecord) {\r
97                 unHideMe($('np_table'));\r
98                 unHideMe($('np_next'));\r
99                 unHideMe($('np_end'));\r
100                 rdetailNext = function() { _rdetailNav(nextRecord); };\r
101                 rdetailEnd = function() { _rdetailNav(cachedRecords.ids[cachedRecords.ids.length-1]); };\r
102         }\r
103 \r
104         runEvt('rdetail', 'nextPrevDrawn', i, cachedRecords.ids.length);\r
105 }\r
106 \r
107 \r
108 function _rdetailNav(id, offset) {\r
109         var args = {};\r
110         args[PARAM_RID] = id;\r
111         goTo(buildOPACLink(args));\r
112 }\r
113 \r
114 function rdetailHandlePlaceHold() {\r
115     function reload() {\r
116         location.href = location.href.replace(/&place_hold=1/, '');\r
117     }\r
118     attachEvt("common", "holdUpdated", reload);\r
119     attachEvt("common", "holdUpdateCanceled", reload);\r
120     attachEvt("common", "loginCanceled", reload);\r
121     holdsDrawEditor({record:getRid(), type: 'T'});\r
122 }\r
123 \r
124 function rdetailDraw() {\r
125     if(new CGI().param('place_hold')) {\r
126        rdetailHandlePlaceHold();\r
127         return;\r
128     }\r
129 \r
130         detachAllEvt('common','depthChanged');\r
131         detachAllEvt('common','locationUpdated');\r
132         attachEvt('common','depthChanged', rdetailReload);\r
133         attachEvt('common','locationUpdated', rdetailReload);\r
134         attachEvt('common','holdUpdated', rdetailReload);\r
135         attachEvt('common','holdUpdateCanceled', rdetailReload);\r
136 \r
137         copyRowParent = G.ui.rdetail.cp_info_row.parentNode;\r
138         copyRow = copyRowParent.removeChild(G.ui.rdetail.cp_info_row);\r
139         statusRow = G.ui.rdetail.cp_status.parentNode;\r
140         statusRow.id = '__rdsrow';\r
141 \r
142         G.ui.rdetail.cp_info_local.onclick = rdetailShowLocalCopies;\r
143         G.ui.rdetail.cp_info_all.onclick = rdetailShowAllCopies;\r
144 \r
145         if(getLocation() == globalOrgTree.id())\r
146                 hideMe(G.ui.rdetail.cp_info_all);\r
147 \r
148    if(getRid()) {\r
149                    var req = new Request(FETCH_RMODS, getRid());  \r
150                    req.callback(_rdetailDraw);  \r
151                    req.send();  \r
152  \r
153    } else { // No record ID was specified\r
154  \r
155           // If we have an ISBN in the URL, let's try to find that record\r
156           // This allows direct linking by ISBN.\r
157           // Note, this uses the first record it finds\r
158           if(getRtype() == RTYPE_ISBN) {\r
159                    var req = new Request(FETCH_ADV_ISBN_RIDS, getAdvTerm());\r
160                    req.callback(\r
161                            function(r) {\r
162                                    var blob = r.getResultObject();\r
163                                    if(blob && blob.count > 0)\r
164                                            RID = blob.ids[0];\r
165                                    var req2 = new Request(FETCH_RMODS, getRid());\r
166                                    req2.callback(_rdetailDraw);\r
167                                    req2.send();\r
168                            }\r
169                    );\r
170                    req.send();\r
171            }\r
172    }\r
173 \r
174 \r
175         if (rdetailDisplaySerialHoldings) {\r
176                 var req = new Request(FETCH_MFHD_SUMMARY, getRid());\r
177                 req.callback(_holdingsDraw);\r
178                 req.send();\r
179                 if (isXUL()) {\r
180                         var here = findOrgUnit(getLocation());\r
181                         dojo.place("<div id='mfhd_ad_menu' class='hide_me'></div>", "rdetail_details_table", "after");\r
182                         var mfhd_add = new dijit.Menu({style:"float: right;"});\r
183                         new dijit.MenuItem({onClick:function(){\r
184                                 var req = new Request(CREATE_MFHD_RECORD, G.user.session, 1, here.id(), getRid());\r
185                                 var res = req.send();\r
186                                 alert(dojo.string.substitute(opac_strings.CREATED_MFHD_RECORD, [here.name()]));\r
187                         }, label:opac_strings.CREATE_MFHD}).placeAt(mfhd_add);\r
188                         mfhd_add.placeAt('mfhd_ad_menu');\r
189                 }\r
190         }\r
191 \r
192         detachAllEvt("result", "idsReceived");\r
193         G.evt.result.hitCountReceived = [];\r
194         G.evt.result.recordReceived = [];\r
195         G.evt.result.copyCountsReceived = [];\r
196         G.evt.result.allRecordsReceived = [];\r
197         //unHideMe($('rdetail_copy_info_link'));\r
198 }\r
199 \r
200 function rdetailGetPageIds() {\r
201         attachEvt("result", "idsReceived", rdetailSetPaging );\r
202         resultFetchAllRecords = true;\r
203         rresultCollectIds(true);\r
204 }\r
205 \r
206 \r
207 function buildunAPISpan (span, type, id) {\r
208         var cgi = new CGI();\r
209         var d = new Date();\r
210 \r
211         addCSSClass(span,'unapi-id');\r
212 \r
213         span.setAttribute(\r
214                 'title', 'tag:' + cgi.server_name + ',' +\r
215                 d.getFullYear() + ':' + type + '/' + id\r
216         );\r
217 }\r
218 \r
219 function rdetailViewMarc(r,id) {\r
220         hideMe($('rdetail_extras_loading'));\r
221         $('rdetail_view_marc_box').innerHTML = r.getResultObject();\r
222 \r
223         var div = elem('div', { "class" : 'hide_me' });\r
224         var span = div.appendChild( elem('abbr') );\r
225 \r
226         buildunAPISpan( span, 'biblio-record_entry', record.doc_id() );\r
227 \r
228         $('rdetail_view_marc_box').insertBefore(span, $('rdetail_view_marc_box').firstChild);\r
229 }\r
230 \r
231 \r
232 function rdetailShowLocalCopies() {\r
233         rdetailShowLocal = true;\r
234         rdetailBuildInfoRows();\r
235         hideMe(G.ui.rdetail.cp_info_local);\r
236         unHideMe(G.ui.rdetail.cp_info_all);\r
237         hideMe(G.ui.rdetail.cp_info_none); \r
238 }\r
239 \r
240 function rdetailShowAllCopies() {\r
241 \r
242         rdetailShowLocal = false;\r
243         rdetailBuildInfoRows();\r
244         hideMe(G.ui.rdetail.cp_info_all);\r
245         unHideMe(G.ui.rdetail.cp_info_local);\r
246         hideMe(G.ui.rdetail.cp_info_none); \r
247 }\r
248 \r
249 function OpenMarcEditWindow(pcrud, rec) {\r
250         /*\r
251            To run in Firefox directly, must set signed.applets.codebase_principal_support\r
252            to true in about:config\r
253          */\r
254         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');\r
255         win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?\r
256         dojo.require('openils.PermaCrud');\r
257 \r
258         win.xulG = {\r
259                 "record": {"marc": rec.marc()},\r
260                 "save": {\r
261                         "label": opac_strings.SAVE_MFHD_LABEL,\r
262                         "func": function(xmlString) {\r
263                                 rec.marc(xmlString);\r
264                                 rec.ischanged(true);\r
265                                 pcrud.update(rec);\r
266                         }\r
267                 }\r
268         };\r
269 }\r
270 \r
271 function loadMarcEditor(recId) {\r
272         var pcrud = new openils.PermaCrud({"authtoken": G.user.session});\r
273         var rec = pcrud.retrieve("sre", recId);\r
274         if (rec) {\r
275                 OpenMarcEditWindow(pcrud, rec);\r
276         }\r
277 }\r
278 \r
279 /*\r
280  * This function could be written much more intelligently\r
281  * Limited brain power means that I'm brute-forcing it for now\r
282  */\r
283 function _holdingsDraw(h) {\r
284         holdings = h.getResultObject();\r
285         if (!holdings) { return null; }\r
286 \r
287         dojo.forEach(holdings, _holdingsDrawMFHD);\r
288 \r
289 }\r
290 \r
291 function _holdingsDrawMFHD(holdings, entryNum) {\r
292 \r
293         var here = findOrgUnit(getLocation());\r
294         if (getDepth() > 0 || getDepth === 0 ) {\r
295                 while (getDepth() < findOrgDepth(here))\r
296                 here = findOrgUnit( here.parent_ou() );\r
297                 if (!orgIsMine(findOrgUnit(here), findOrgUnit(holdings.owning_lib()))) {\r
298                         return null;\r
299                 }\r
300         }\r
301 \r
302         var hh = holdings.holdings();\r
303         var hch = holdings.current_holdings();\r
304         var hs = holdings.supplements();\r
305         var hcs = holdings.current_supplements();\r
306         var hi = holdings.indexes();\r
307         var hci = holdings.current_indexes();\r
308         var ho = holdings.online();\r
309         var hm = holdings.missing();\r
310         var hinc = holdings.incomplete();\r
311         var hloc = holdings.location() || 'MFHD';\r
312 \r
313         if (    hh.length == 0 && hch.length == 0 && hs.length == 0 &&\r
314                 hcs.length == 0 && hi.length == 0 && hci.length == 0 &&\r
315                 ho.length == 0 && hm.length == 0 && hinc.length == 0\r
316         ) {\r
317 \r
318                 if (isXUL()) {\r
319                         /* \r
320                          * If we have a record, but nothing to show for it, then the\r
321                          * record is likely empty or corrupt. This gives cataloguers a\r
322                          * chance to add holdings or correct the record\r
323                          */\r
324                         hh = 'PLACEHOLDER';\r
325                 } else {\r
326                         return null;\r
327                 }\r
328         }\r
329 \r
330         dojo.place("<table style='width: 100%;'><caption id='mfhdHoldingsCaption" + entryNum + "' class='rdetail_header color_1'>" +\r
331                 dojo.string.substitute(opac_strings.HOLDINGS_TABLE_CAPTION, [hloc]) +\r
332                 "</caption><tbody id='rdetail_holdings_tbody_" + entryNum +\r
333                 "'></tbody></table>", "rdetail_details_table", "after"\r
334         );\r
335         if (hh.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.HOLDINGS, hh); }\r
336         if (hch.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.CURRENT_HOLDINGS, hch); }\r
337         if (hs.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.SUPPLEMENTS, hs); }\r
338         if (hcs.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.CURRENT_SUPPLEMENTS, hcs); }\r
339         if (hi.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.INDEXES, hi); }\r
340         if (hci.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.CURRENT_INDEXES, hci); }\r
341         if (ho.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.ONLINE_VOLUMES, ho); }\r
342         if (hm.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.MISSING_VOLUMES, hm); }\r
343         if (hinc.length > 0) { _holdingsDrawMFHDEntry(entryNum, opac_strings.INCOMPLETE_VOLUMES, hinc); }\r
344 \r
345         if (isXUL()) {\r
346                 dojo.require('openils.Event');\r
347                 dojo.require('openils.PermaCrud');\r
348                 var mfhd_edit = new dijit.Menu({});\r
349                 new dijit.MenuItem({onClick: function(){loadMarcEditor(holdings.id())}, label:opac_strings.EDIT_MFHD_RECORD}).placeAt(mfhd_edit, "first");\r
350                 new dijit.MenuItem({onClick:function(){\r
351                         var pcrud = new openils.PermaCrud({"authtoken": G.user.session});\r
352                         var mfhd_rec = pcrud.retrieve("sre", holdings.id());\r
353                         if (mfhd_rec) {\r
354                                 pcrud.eliminate(mfhd_rec);\r
355                                 alert(dojo.string.substitute(opac_strings.DELETED_MFHD_RECORD, [holdings.id()]));\r
356                         }\r
357                 }, label:opac_strings.DELETE_MFHD}).placeAt(mfhd_edit, "last");\r
358                 // new dijit.MenuItem({onClick:function(){alert("Edit properties " + holdings.id());}, label:opac_strings.EDIT_PROPERTIES}).placeAt(mfhd_edit, "last");\r
359                 var mfhd_mb = new dijit.form.DropDownButton({dropDown: mfhd_edit, label:opac_strings.EDIT_MFHD_MENU, style:"float:right"});\r
360                 mfhd_mb.placeAt("mfhdHoldingsCaption" + entryNum, "last");\r
361                 mfhd_edit.startup();\r
362         }\r
363 }\r
364 \r
365 function _holdingsDrawMFHDEntry(entryNum, entryName, entry) {\r
366         var flatEntry = entry.toString().replace(/,/g, ', ');\r
367         dojo.place("<tr><td> </td><td nowrap='nowrap' class='rdetail_desc'>" + entryName + "</td><td class='rdetail_item'>" + flatEntry + "</td></tr>", "rdetail_holdings_tbody_" + entryNum, "last");\r
368 }\r
369 \r
370 function _rdetailDraw(r) {\r
371         record = r.getResultObject();\r
372 \r
373         runEvt('rdetail', 'recordRetrieved', record.doc_id());\r
374         \r
375         if(isInAnonList(parseInt(record.doc_id()))) { \r
376                 $('add_mylist').innerHTML = '';\r
377                 $('add_mylist').appendChild(elem('img', {src:'/opac/skin/kcls/graphics/add_mylist_sel.gif'}, null));\r
378         }\r
379 \r
380         G.ui.rdetail.title.appendChild(text(record.title()));\r
381         buildSearchLink(STYPE_AUTHOR, record.author(), G.ui.rdetail.author);\r
382         if(record.isbn()) { unHideMe($('rdetail_isbn_lbl')); G.ui.rdetail.isbn.appendChild(text(cleanISBN(record.isbn()))); }\r
383         if(record.edition()) { unHideMe($('rdetail_ed_lbl')); G.ui.rdetail.edition.appendChild(text(record.edition())); }\r
384         if(record.pubdate()) { unHideMe($('rdetail_pubdate_lbl')); G.ui.rdetail.pubdate.appendChild(text(record.pubdate())); }\r
385         if(record.publisher()) { unHideMe($('rdetail_pub_lbl')); G.ui.rdetail.publisher.appendChild(text(record.publisher())); }\r
386         if(record.physical_description()) { unHideMe($('rdetail_phys_lbl')); $('rdetail_physical_desc').appendChild(text(record.physical_description())); }\r
387         $('rd_reviews_and_more').href="http://contentcafe2.btol.com/ContentCafeClient/ContentCafe.aspx?UserID=KC72927&Password=CC14647&ItemKey="+cleanISBN(record.isbn())+"&Options=Y";\r
388         \r
389         var code = getMarcData(record.doc_id(),"998","d");\r
390         \r
391         if(code) { unHideMe($('rdetail_form_lbl')); G.ui.rdetail.tor.innerHTML = get998dValue(code); }\r
392         if(record.synopsis()) { unHideMe($('rdetail_sum_lbl')); G.ui.rdetail.abstr.appendChild(text(record.synopsis())); }\r
393 //javascript: alert(getMarcData(22531007,"998","d"));\r
394         try{\r
395                 if(record.isbn()) {\r
396                         if(ENABLE_ADDED_CONTENT_ATTRIB_LINKS) {\r
397                                 unHideMe($('rdetail.jacket_attrib_div'));\r
398                                 var href = $('rdetail.jacket_attrib_link').getAttribute('href') +cleanISBN(record.isbn());\r
399                                 $('rdetail.jacket_attrib_link').setAttribute('href', href);\r
400                         }\r
401                         rdetailCheckForGBPreview();\r
402 \r
403                 } else {\r
404                         //hideMe($("rdetail.jacket_attrib_div"));\r
405                         //hideMe($("rdetail_img_link"));\r
406                 }\r
407         } catch(E) {}\r
408 \r
409 \r
410         // see if the record has any external links \r
411         var links = record.online_loc();\r
412         for( var i = 0; links && links.length > 0 && i < links.length; i = i + 3 ) {\r
413                 var href = links[i];\r
414                 // avoid matching "HTTP: The Complete Reference"\r
415                 if( href.match(/https?:\/|ftps?:\/|mailto:/i) ) {\r
416                         unHideMe($('rdetail_online_row'));\r
417                         // MODS can contain a display label (used for the text of the link)\r
418                         // as well as a note about the URL; many legacy systems conflate the\r
419                         // two and generate MARC records that expect the note to be used as\r
420                         // the text of the link, with no display label; here's the canonical\r
421                         // format:\r
422                         //\r
423                         // 856 40 $uhttp://localhost$yDisplay label$zPublic note\r
424                         //\r
425                         // Note that the MARC21slim2MODS XSL concatenates $3 and $y together\r
426                         // (as $y was defined later in MARC21's life as the display label)\r
427                         var displayLabel = '' + links[i+1];\r
428                         var note = '' + links[i+2];\r
429                         if(!displayLabel || displayLabel.match(/https?:\/|ftps?:\/|mailto:/i)) {\r
430                                 if(!note || note.match(/https?:\/|ftps?:\/|mailto:/i)) {\r
431                                         displayLabel = href;\r
432                                 } else {\r
433                                         displayLabel = note;\r
434                                 }\r
435                         }\r
436                         $('rdetail_online').appendChild(elem('a', {href:href,'class':'classic_link'}, displayLabel));\r
437                         if (note && note != displayLabel) {\r
438                                 $('rdetail_online').appendChild(elem('span', {'class':'url_note'}, ' - ' + note));\r
439                         }\r
440                         $('rdetail_online').appendChild(elem('br'));\r
441                 }\r
442         }\r
443 \r
444         // Fill in our unAPI ID, if anyone cares\r
445         var abbrs = document.getElementsByTagName('abbr');\r
446         var span;\r
447         for (var i = 0; i < abbrs.length; i = i + 1) {\r
448                 if (abbrs[i].getAttribute('name') == 'unapi') {\r
449                         span = abbrs[i];\r
450                         break;\r
451                 }\r
452         }\r
453         buildunAPISpan( span, 'biblio-record_entry', record.doc_id() );\r
454 \r
455     $('rdetail_place_hold').onclick = function() {\r
456         var src = location.href;\r
457         if(forceLoginSSL && src.match(/^http:/)) {\r
458             src = src.replace(/^http:/, 'https:');\r
459             if(!src.match(/&place_hold=1/)) {\r
460                 src += '&place_hold=1';\r
461             }\r
462             location.href = src;\r
463         } else {\r
464            holdsDrawEditor({record:record.doc_id(), type:'T'});\r
465         }\r
466     }\r
467 \r
468         var RW = $('rdetail_exp_refworks');\r
469         if (RW && rdetailEnableRefWorks) {\r
470 \r
471                 var here = (findOrgUnit(getLocation())).name();\r
472                 var org_name = here.replace(" ", "+");\r
473                 var cgi = new CGI();\r
474 \r
475                 RW.setAttribute(\r
476                         'href',\r
477                         rdetailRefWorksHost + '/express/expressimport.asp?vendor='\r
478                         + org_name\r
479                         + '&filter=MARC+Format&database=All+MARC+Formats&encoding=65001&url=http%3A%2F%2F'\r
480                         + cgi.server_name + '/opac/extras/supercat/marctxt/record/'\r
481                         + record.doc_id()\r
482                );\r
483 \r
484                 RW.setAttribute('target', 'RefWorksMain');\r
485 \r
486                 unHideMe($('rdetail_exp_refworks_span'));\r
487         }\r
488 \r
489         //$('rdetail_img_link').setAttribute('href', buildISBNSrc(cleanISBN(record.isbn()), 'large'));\r
490         //G.ui.rdetail.image.setAttribute("src", buildISBNSrc(cleanISBN(record.isbn())));\r
491         runEvt("rdetail", "recordDrawn");\r
492         recordsCache.push(record);\r
493 \r
494         rdetailSetExtrasSelector();\r
495 \r
496         var breq = new Request(FETCH_BRE, [getRid()]);\r
497         breq.callback( rdetailCheckDeleted );\r
498         breq.send();\r
499 \r
500         //resultBuildCaches( [ record ] );\r
501         //resultDrawSubjects();\r
502         //resultDrawSeries();\r
503 \r
504         // grab added content \r
505         acCollectData(cleanISBN(record.isbn()), rdetailhandleAC);\r
506         \r
507         var currentISBN = cleanISBN(record.isbn());\r
508         \r
509             // ChiliFresh\r
510     if (chilifresh && chilifresh != '(none)' && currentISBN) {\r
511         $('chilifreshReviewLink').setAttribute('id','isbn_'+currentISBN);\r
512         $('chilifreshReviewResult').setAttribute('id','chili_review_'+currentISBN);\r
513         unHideMe($('rdetail_reviews_link'));\r
514         unHideMe($('rdetail_chilifresh_reviews'));\r
515         try {\r
516             chili_init();\r
517         } catch(E) {\r
518             alert(E + '\n');\r
519             hideMe($('rdetail_reviews_link'));\r
520             hideMe($('rdetail_chilifresh_reviews'));\r
521         }\r
522     }\r
523 \r
524         var it = getCacheValue('showHoldEditor');\r
525         if(it) {\r
526                 setCacheValue('showHoldEditor', null);\r
527                 holdsDrawEditor({record:it.record, type:it.type});\r
528         }\r
529     // Novelist\r
530     if (novelist && currentISBN) {\r
531         unHideMe($('rdetail_novelist_link'));\r
532     }\r
533 }\r
534 \r
535 \r
536 \r
537 function rdetailCheckDeleted(r) {\r
538         var br = r.getResultObject()[0];\r
539         if( isTrue(br.deleted()) ) {\r
540                 hideMe($('rdetail_place_hold'));\r
541                 $('rdetail_more_actions_selector').disabled = true;\r
542                 unHideMe($('rdetail_deleted_exp'));\r
543         }\r
544 }\r
545 \r
546 function rdetailSetExtrasSelector() {\r
547         if(!grabUser()) return;\r
548         unHideMe($('rdetail_more_actions'));\r
549 \r
550         var req = new Request( \r
551                         FETCH_CONTAINERS, G.user.session, G.user.id(), 'biblio', 'bookbag' );\r
552         req.callback(rdetailAddBookbags);\r
553         req.send();\r
554 }\r
555 \r
556 var myListsFetched = false;\r
557 var selectedItem = null;\r
558 function addMyList(id) {\r
559         if(!id) id = record.doc_id();\r
560         //if(!grabUser()) { alert("Please login first"); goTo(buildOPACLink({page:MYOPAC}, false, true)); return; }\r
561         \r
562         var holdsLink = $n($('result_table_template_'+id), 'result_my_list_link');\r
563         if(!holdsLink) holdsLink = $('add_mylist');\r
564         var lbl = $('myListLabel');\r
565         var title = "";\r
566         if(_resultFindRec) title = _resultFindRec(id);\r
567         if(title) title = title.title();\r
568         if(lbl) lbl.innerHTML = title; else lbl.innerHTML = "";\r
569         \r
570         //if(!grabUser()) {\r
571                 isCacheListDrawn = false;\r
572                 for(var i in anonListCache) {\r
573                         if(anonListCache[i] == id) {\r
574                                 anonListCache.splice(i, 1);\r
575                                 setCacheValue('anonListCache', anonListCache);\r
576                                 if(!anonListCache.length) hideMe($('cacheListLink'));\r
577                                 if(holdsLink) {\r
578                                         holdsLink.innerHTML = '';\r
579                                         holdsLink.appendChild(elem('img', {src:'/opac/skin/kcls/graphics/add_mylist.gif'}, null));\r
580                                         holdsLink.title = "Add to my list";\r
581                                 }\r
582                                 return;\r
583                         }\r
584                 }       \r
585 \r
586                 anonListCache.push(id);\r
587                 setCacheValue('anonListCache', anonListCache);\r
588                 unHideMe($('cacheListLink'));\r
589                 if(holdsLink) {\r
590                         holdsLink.innerHTML = '';\r
591                         holdsLink.appendChild(elem('img', {src:'/opac/skin/kcls/graphics/add_mylist_sel.gif'}, null));\r
592                         holdsLink.title = "Remove from my list";\r
593                 }\r
594                 return;\r
595         //}\r
596         \r
597         selectedItem = id;\r
598         var selector = $('mylist_selector');\r
599         \r
600         if(findCurrentPage()==RDETAIL) {\r
601                 unHideMe($('rdetail_more_actions_selector'));\r
602         } else if(findCurrentPage()==RRESULT) {\r
603                 hideResultsPage(true);\r
604                 unHideMe($('mylist_div'));\r
605         }\r
606         if(!myListsFetched) {\r
607                 myListsFetched = true;\r
608                 var req = new Request(FETCH_CONTAINERS, G.user.session, G.user.id(), 'biblio', 'bookbag' );\r
609                 req.callback(showMyLists);\r
610                 req.send();\r
611         }\r
612 }\r
613 \r
614 function saveMyList() {\r
615         if(!selectedItem) return true;\r
616         var newList = $('mylist_new');\r
617         if(!newList) return true;\r
618         \r
619         var selector = $('mylist_selector');\r
620         if(!selector.options.length && !newList.value) { alert('Please choose a name for the new list'); newList.focus(); return false; }\r
621 \r
622         if(newList.value) {\r
623                 var id;\r
624                 var name = newList.value\r
625                 if(id = containerCreate(name)) {\r
626                         selector.options.length=0;\r
627                         if(!selector.options.length) {\r
628                                 unHideMe($('myListSelect'));\r
629                                 var req = new Request(FETCH_CONTAINERS, G.user.session, G.user.id(), 'biblio', 'bookbag' );\r
630                                 req.callback(showMyLists);\r
631                                 req.send();\r
632                         }\r
633                         if(containerCreateItem(id, selectedItem)) {\r
634                                 alert('Item successfully added to list');\r
635                                 newList.value = "";\r
636                         } else { return false; }\r
637                 } else { return false; }\r
638         } else { //save to selected list\r
639                 var selectedID = selector.options[selector.selectedIndex].value;\r
640                 if(containerCreateItem(selectedID, selectedItem)) {\r
641                         alert('Item successfully added to list');\r
642                         newList.value = "";\r
643                 } else { return false; }\r
644         }\r
645         \r
646         if(findCurrentPage()==RDETAIL) {\r
647                 hideMe($('rdetail_more_actions_selector'));\r
648         } else if(findCurrentPage()==RRESULT) {\r
649                 hideResultsPage(false);\r
650         }\r
651         return true;\r
652 }\r
653 \r
654 function showMyLists(r) {\r
655         var containers = r.getResultObject();\r
656         var selector = $('mylist_selector');\r
657 \r
658         for( var i = 0; i != containers.length; i++ ) {\r
659                 var container = containers[i];\r
660                 insertSelectorVal( selector, i, container.name(), container.id(), null, 0 );\r
661         }\r
662         if(!selector.options.length) hideMe($('myListSelect'));\r
663 }\r
664 \r
665 \r
666 function rdetailAddBookbags(r) {\r
667 \r
668         var containers = r.getResultObject();\r
669         var selector = $('rdetail_more_actions_selector');\r
670         var found = false;\r
671         var index = 3;\r
672         doSelectorActions(selector);\r
673 \r
674         for( var i = 0; i != containers.length; i++ ) {\r
675                 found = true;\r
676                 var container = containers[i];\r
677                 insertSelectorVal( selector, index++, container.name(), \r
678                                 "container_" + container.id(), rdetailAddToBookbag,  1 );\r
679         }\r
680 \r
681         nextContainerIndex = index;\r
682 }\r
683 \r
684 var _actions = {};\r
685 function rdetailNewBookbag() {\r
686         var name = prompt($('rdetail_bb_new').innerHTML,"");\r
687         if(!name) return;\r
688 \r
689         var id;\r
690         if( id = containerCreate( name ) ) {\r
691                 alert($('rdetail_bb_success').innerHTML);\r
692                 var selector = $('rdetail_more_actions_selector');\r
693                 insertSelectorVal( selector, nextContainerIndex++, name, \r
694                                 "container_" + id, rdetailAddToBookbag, 1 );\r
695                 setSelector( selector, 'start' );\r
696         }\r
697 }\r
698 \r
699 \r
700 function rdetailAddToBookbag() {\r
701         var selector = $('rdetail_more_actions_selector');\r
702         var id = selector.options[selector.selectedIndex].value;\r
703         setSelector( selector, 'start' );\r
704 \r
705         if( containerCreateItem( id.substring(10), record.doc_id() )) {\r
706                 alert($('rdetail_bb_item_success').innerHTML);\r
707         }\r
708 }\r
709 \r
710 \r
711 var rdetailMarcFetched = false;\r
712 function rdetailShowExtra(type, args) {\r
713 \r
714         hideMe($('rdetail_copy_info_div'));\r
715         hideMe($('rdetail_reviews_div'));\r
716         hideMe($('rdetail_toc_div'));\r
717         hideMe($('rdetail_anotes_div'));\r
718         hideMe($('rdetail_excerpt_div'));\r
719         hideMe($('rdetail_preview_div'));\r
720         hideMe($('rdetail_marc_div'));\r
721         hideMe($('cn_browse'));\r
722         hideMe($('rdetail_cn_browse_div'));\r
723         hideMe($('rdetail_notes_div'));\r
724         hideMe($('rdetail_novelist_div'));\r
725 \r
726         removeCSSClass($('rdetail_copy_info_link'), 'rdetail_extras_selected');\r
727         removeCSSClass($('rdetail_viewcn_link'), 'rdetail_extras_selected');\r
728         removeCSSClass($('rdetail_reviews_link'), 'rdetail_extras_selected');\r
729         removeCSSClass($('rdetail_toc_link'), 'rdetail_extras_selected');\r
730         removeCSSClass($('rdetail_excerpt_link'), 'rdetail_extras_selected');\r
731         removeCSSClass($('rdetail_preview_link'), 'rdetail_extras_selected');\r
732         removeCSSClass($('rdetail_anotes_link'), 'rdetail_extras_selected');\r
733         removeCSSClass($('rdetail_annotation_link'), 'rdetail_extras_selected');\r
734         removeCSSClass($('rdetail_viewmarc_link'), 'rdetail_extras_selected');\r
735         removeCSSClass($('rdetail_novelist_link'), 'rdetail_extras_selected');\r
736 \r
737         switch(type) {\r
738 \r
739                 case "copyinfo": \r
740                         unHideMe($('rdetail_copy_info_div')); \r
741                         addCSSClass($('rdetail_copy_info_link'), 'rdetail_extras_selected');\r
742                         break;\r
743 \r
744                 case "reviews": \r
745                         addCSSClass($('rdetail_reviews_link'), 'rdetail_extras_selected');\r
746                         unHideMe($('rdetail_reviews_div')); \r
747                         break;\r
748 \r
749                 case "excerpt": \r
750                         addCSSClass($('rdetail_excerpt_link'), 'rdetail_extras_selected');\r
751                         unHideMe($('rdetail_excerpt_div'));\r
752                         break;\r
753 \r
754                 case "preview": \r
755                         addCSSClass($('rdetail_preview_link'), 'rdetail_extras_selected');\r
756                         unHideMe($('rdetail_preview_div'));\r
757                         rdetailDisplayGBPreview();\r
758                         break;\r
759 \r
760                 case "anotes": \r
761                         addCSSClass($('rdetail_anotes_link'), 'rdetail_extras_selected');\r
762                         unHideMe($('rdetail_anotes_div'));\r
763                         break;\r
764 \r
765                 case "toc": \r
766                         addCSSClass($('rdetail_toc_link'), 'rdetail_extras_selected');\r
767                         unHideMe($('rdetail_toc_div'));\r
768                         break;\r
769 \r
770                 case "marc": \r
771                         addCSSClass($('rdetail_viewmarc_link'), 'rdetail_extras_selected');\r
772                         unHideMe($('rdetail_marc_div')); \r
773                         if(rdetailMarcFetched) return;\r
774                         unHideMe($('rdetail_extras_loading'));\r
775                         rdetailMarcFetched = true;\r
776                         var req = new Request( FETCH_MARC_HTML, record.doc_id() );\r
777                         req.callback(rdetailViewMarc); \r
778                         req.send();\r
779                         break;\r
780 \r
781                 case "novelist": \r
782                         addCSSClass($('rdetail_novelist_link'), 'rdetail_extras_selected');\r
783                         unHideMe($('rdetail_novelist_div')); \r
784                         break;\r
785 \r
786                 case 'cn':\r
787                         addCSSClass($('rdetail_viewcn_link'), 'rdetail_extras_selected');\r
788                         unHideMe($('rdetail_cn_browse_div'));\r
789                         rdetailShowCNBrowse(defaultCN, getLocation(), null, true);\r
790                         break;\r
791 \r
792         }\r
793 }\r
794 \r
795 function rdetailVolumeDetails(args) {\r
796         var row = $(args.rowid);\r
797         var tbody = row.parentNode;\r
798         cpdBuild( tbody, row, record, args.cn, args.org, args.depth, args.copy_location );\r
799         return;\r
800 }\r
801 \r
802 function rdetailBuildCNList() {\r
803 \r
804         var select = $('cn_browse_selector');\r
805         var index = 0;\r
806         var arr = [];\r
807         for( var cn in callnumberCache ) arr.push( cn );\r
808         arr.sort();\r
809 \r
810         if( arr.length == 0 ) {\r
811                 hideMe($('rdetail_cn_browse_select_div'));\r
812                 return;\r
813         }\r
814 \r
815         for( var i in arr ) {\r
816                 var cn = arr[i];\r
817                 var opt = new Option(cn);\r
818                 select.options[index++] = opt;\r
819         }\r
820         select.onchange = rdetailGatherCN;\r
821 }\r
822 \r
823 function rdetailGatherCN() {\r
824         var cn = getSelectorVal($('cn_browse_selector'));\r
825         rdetailShowCNBrowse( cn, getLocation(), getDepth(), true );\r
826         setSelector( $('cn_browse_selector'), cn );\r
827 }\r
828 \r
829 \r
830 function rdetailShowCNBrowse( cn, loc, depth, fromOnclick ) {\r
831 \r
832         if(!cn) {\r
833                 unHideMe($('cn_browse_none'));\r
834                 hideMe($('rdetail_cn_browse_select_div'));\r
835                 return;\r
836         }\r
837 \r
838         unHideMe($('rdetail_cn_browse_select_div'));\r
839         rdetailBuildCNList();\r
840         setSelector( $('cn_browse_selector'), cn );\r
841         hideMe($('rdetail_copy_info_div'));\r
842         hideMe($('rdetail_reviews_div'));\r
843         hideMe($('rdetail_toc_div'));\r
844         hideMe($('rdetail_marc_div'));\r
845         unHideMe($('rdetail_cn_browse_div'));\r
846         unHideMe($('cn_browse'));\r
847         if( !rdetailLocalOnly && ! fromOnclick ) depth = findOrgDepth(globalOrgTree);\r
848         cnBrowseGo(cn, loc, depth);\r
849 }\r
850 \r
851 function rdetailhandleAC(data) {\r
852 \r
853         if( data.reviews.html ) {\r
854                 $('rdetail_review_container').innerHTML = data.reviews.html;\r
855                 unHideMe($('rdetail_reviews_link'));\r
856         }\r
857 \r
858         if( data.toc.html ) {\r
859                 $('rdetail_toc_div').innerHTML = data.toc.html;\r
860                 unHideMe($('rdetail_toc_link'));\r
861         }\r
862 \r
863         if( data.excerpt.html ) {\r
864                 $('rdetail_excerpt_div').innerHTML = data.excerpt.html;\r
865                 unHideMe($('rdetail_excerpt_link'));\r
866         }\r
867 \r
868         if( data.anotes.html ) {\r
869                 $('rdetail_anotes_div').innerHTML = data.anotes.html;\r
870                 unHideMe($('rdetail_anotes_link'));\r
871         }\r
872 }\r
873 \r
874 function rdetailShowReviews(r) {\r
875         hideMe($('rdetail_extras_loading'));\r
876         var res = r.getResultObject();\r
877         var par = $('rdetail_reviews_div');\r
878         var template = par.removeChild($('rdetail_review_template'));\r
879         if( res && res.length > 0 ) {\r
880                 unHideMe($('rdetail_reviews_link'));\r
881                 for( var i = 0; i != res.length; i++ ) {\r
882                         var rev = res[i];       \r
883                         if( rev.text && rev.info ) {\r
884                                 var node = template.cloneNode(true);\r
885                                 $n(node, 'review_header').appendChild(text(rev.info));\r
886                                 $n(node, 'review_text').appendChild(text(rev.text));\r
887                                 par.appendChild(node);\r
888                         }\r
889                 }\r
890         }\r
891 }\r
892 \r
893 \r
894 function rdetailShowTOC(r) {\r
895         hideMe($('rdetail_extras_loading'));\r
896         var resp = r.getResultObject();\r
897         if(resp) {\r
898                 unHideMe($('rdetail_toc_link'));\r
899                 $('rdetail_toc_div').innerHTML = resp;\r
900         }\r
901 }\r
902 \r
903 function rdetailBuildInfoRows() {\r
904         var req;\r
905         var method = FETCH_COPY_COUNTS_SUMMARY;\r
906         if (rdetailShowCopyLocation)\r
907                 method = FETCH_COPY_LOCATION_COUNTS_SUMMARY;\r
908 \r
909 \r
910         if( rdetailShowLocal ) \r
911                 req = new Request(method, record.doc_id(), 1, 0)\r
912         else\r
913                 req = new Request(method, record.doc_id());\r
914         req.callback(_rdetailBuildInfoRows);\r
915         req.send();\r
916 }\r
917 \r
918 function _rdetailRows(node) {\r
919 \r
920         if( rdetailShowLocal && /*getLocation()*/1 != globalOrgTree.id() ) {\r
921                 var loc = findOrgUnit(1/*getLocation()*/);\r
922                 if( node ) {\r
923                         if( !orgIsMine(node, loc) && !orgIsMine(loc,node) ) return;\r
924                 } else {\r
925                         for( var i = 0; i < globalOrgTree.children().length; i++ ) {\r
926                                 var org = findOrgUnit(globalOrgTree.children()[i]);\r
927                                 if( orgIsMine(org, loc) ) {\r
928                                         node = org;\r
929                                         break;\r
930                                 }\r
931                         }\r
932                 } \r
933         }\r
934 \r
935         if(!node && findOrgType(globalOrgTree.ou_type()).can_have_vols())\r
936                 node = globalOrgTree;\r
937 \r
938 \r
939         /* don't show hidden orgs */\r
940 \r
941         if(node) {\r
942 \r
943                 //if(!isXUL() && !isTrue(node.opac_visible())) return;\r
944                 if(!isXUL() && !isTrue(node.opac_visible())) {\r
945                         // locally suppressed orgs should appear in the copy summary\r
946                         if(!localSuppressedOrgs[node.id()]) {  // indexOf() on user arrays isn't supported on <= IE8\r
947                                 return; \r
948                         }\r
949         }\r
950                 \r
951                 // , 1555:true, 1499:true, 1510:true, 1538:true\r
952 \r
953                 var row = copyRow.cloneNode(true);\r
954                 row.id = "cp_info_" + node.id();\r
955 \r
956                 var libtd = findNodeByName( row, config.names.rdetail.lib_cell );\r
957                 var cntd  = findNodeByName( row, config.names.rdetail.cn_cell );\r
958                 var cpctd = findNodeByName( row, config.names.rdetail.cp_count_cell );\r
959                 var actions = $n(row, 'rdetail_actions_cell');\r
960 \r
961                 var p = libtd.getElementsByTagName('a')[0];\r
962                 libtd.insertBefore(text(node.name()), p);\r
963                 libtd.setAttribute("style", "padding-left: " + ((findOrgDepth(node) - 1)  * 9) + "px;");\r
964 \r
965                 if(!findOrgType(node.ou_type()).can_have_vols()) {\r
966 \r
967                         row.removeChild(cntd);\r
968                         row.removeChild(cpctd);\r
969                         row.removeChild(actions);\r
970                         row.setAttribute('novols', '1');\r
971 \r
972                         libtd.setAttribute("colspan", numStatuses + 3 );\r
973                         libtd.colSpan = numStatuses + 3;\r
974                         addCSSClass(row, 'copy_info_region_row');\r
975                 } \r
976 \r
977                 copyRowParent.appendChild(row);\r
978 \r
979         } else { node = globalOrgTree; }\r
980 \r
981         for( var c in node.children() ) \r
982                 _rdetailRows(node.children()[c]);\r
983 }\r
984 \r
985 function rdetailCNPrint(orgid, cn) {\r
986         var div = cpdBuildPrintWindow( record, orgid);\r
987         var template = div.removeChild($n(div, 'cnrow'));\r
988         var rowNode = $("cp_info_" + orgid);\r
989         cpdStylePopupWindow(div);\r
990         openWindow(div.innerHTML);\r
991 }\r
992 \r
993 var localCNFound = false;\r
994 var ctr = 0;\r
995 function _rdetailBuildInfoRows(r) {\r
996         var showLibCount = 5;\r
997 \r
998         if (rdetailShowCopyLocation)\r
999                 unHideMe( $n( $('rdetail_copy_info_table'), 'rdetail_copylocation_header' ));\r
1000 \r
1001         removeChildren(copyRowParent);\r
1002 \r
1003         _rdetailRows();\r
1004 \r
1005         var summary = r.getResultObject();\r
1006         if(!summary) return;\r
1007         \r
1008         // sort by name - desc\r
1009         if(getOrigLocation()) summary.sort(function(a,b){\r
1010                 if(a[0]==getOrigLocation()) return -1;\r
1011                 if(b[0]==getOrigLocation()) return 1;\r
1012                 return findOrgUnit(a[0]).name()>=findOrgUnit(b[0]).name()?1:-1;\r
1013         }); else summary.sort(function(a,b){\r
1014                 return findOrgUnit(a[0]).name()>=findOrgUnit(b[0]).name()?1:-1;\r
1015         });     \r
1016 \r
1017         var found = false;\r
1018         if(summary.length>showLibCount) unHideMe($('lib_info_more'));\r
1019         for( var i = 0; i < summary.length; i++ ) {\r
1020 \r
1021                 var arr = summary[i];\r
1022                 globalCNCache[arr[1]] = 1;\r
1023                 var thisOrg = findOrgUnit(arr[0]);\r
1024                 var rowNode = $("cp_info_" + thisOrg.id());\r
1025                 if(!rowNode) continue;\r
1026 \r
1027                 if(rowNode.getAttribute("used")) {\r
1028 \r
1029                         if( rowNode.nextSibling ) {\r
1030                                 sib = rowNode.nextSibling;\r
1031                                 o ='cp_info_'+thisOrg.id()+'_';\r
1032                                 /* push the new row on as the last row for this org unit */\r
1033                                 while( sib && sib.id.match(o) ) {\r
1034                                         sib = sib.nextSibling;\r
1035                                 }\r
1036                                 if(sib)\r
1037                                         rowNode = copyRowParent.insertBefore(copyRow.cloneNode(true), sib);\r
1038                                 else\r
1039                                         rowNode = copyRowParent.appendChild(copyRow.cloneNode(true));\r
1040                         } else {\r
1041                                 rowNode = copyRowParent.appendChild(copyRow.cloneNode(true));\r
1042                         }\r
1043 \r
1044                         var n = findNodeByName( rowNode, config.names.rdetail.lib_cell );\r
1045                         n.appendChild(text(thisOrg.name()));\r
1046                         n.setAttribute("style", "padding-left: " + ((findOrgDepth(thisOrg) - 1)  * 9) + "px;");\r
1047                         rowNode.id = "cp_info_" + thisOrg.id() + '_' + (++ctr); \r
1048 \r
1049                 } else {\r
1050                         rowNode.setAttribute("used", "1");\r
1051                 }\r
1052 \r
1053                 var cpc_temp = rowNode.removeChild(\r
1054                                 findNodeByName(rowNode, config.names.rdetail.cp_count_cell));\r
1055 \r
1056                 var statuses = arr[2];\r
1057                 var cl = '';\r
1058                 if (rdetailShowCopyLocation) {\r
1059                         cl = arr[2];\r
1060                         statuses = arr[3];\r
1061                 }\r
1062 \r
1063                 var tehTR = $('rdetails_status_head');\r
1064                 \r
1065                 if(tehTR) {\r
1066                         var par = i<showLibCount?tehTR.parentNode:$('rdetails_status2');\r
1067                         var newRow = elem('tr');\r
1068                         var lib_td = elem('td',{nowrap:"nowrap"});\r
1069                         var stat = statuses[0]?"Available":"Checked Out";\r
1070                         var url = mapLibUrl(arr[0]);\r
1071                         var libLink = elem('a',{href:url},'View Library Info');\r
1072                         if(!url) hideMe(libLink);\r
1073                         stat = statuses[6]?"Due":stat;\r
1074                         lib_td.appendChild(libLink);\r
1075                         \r
1076                         newRow.appendChild(elem('td',{nowrap:"nowrap"},thisOrg.name()));\r
1077                         newRow.appendChild(elem('td',{nowrap:"nowrap"},cl));\r
1078                         newRow.appendChild(lib_td);\r
1079                         newRow.appendChild(elem('td',{nowrap:"nowrap"},stat));\r
1080                         newRow.appendChild(elem('td',{nowrap:"nowrap"},arr[1]));\r
1081                         par.appendChild(newRow);\r
1082                 }\r
1083 \r
1084                 rdetailApplyStatuses(rowNode, cpc_temp, statuses);\r
1085 \r
1086                 var isLocal = false;\r
1087                 if( orgIsMine( findOrgUnit(getLocation()), thisOrg ) ) { \r
1088                         found = true; \r
1089                         isLocal = true; \r
1090                         if(!localCNFound) {\r
1091                                 localCNFound = true;\r
1092                                 defaultCN = arr[1];\r
1093                         }\r
1094                 }\r
1095 \r
1096                 //if(isLocal) unHideMe(rowNode);\r
1097                 unHideMe(rowNode);\r
1098 \r
1099                 rdetailSetPath( thisOrg, isLocal );\r
1100                 rdetailBuildBrowseInfo( rowNode, arr[1], isLocal, thisOrg, cl );\r
1101 \r
1102                 if( i == summary.length - 1 && !defaultCN) defaultCN = arr[1];\r
1103         }\r
1104 \r
1105         if(!found) unHideMe(G.ui.rdetail.cp_info_none);\r
1106 }\r
1107 \r
1108 function rdetailBuildBrowseInfo(row, cn, local, orgNode, cl) {\r
1109         if(local) {\r
1110                 var cache = callnumberCache[cn];\r
1111                 if( cache ) cache.count++;\r
1112                 else callnumberCache[cn] = { count : 1 };\r
1113         }\r
1114 \r
1115         var depth = getDepth();\r
1116         if( !local ) depth = findOrgDepth(globalOrgTree);\r
1117 \r
1118         $n(row, 'rdetail_callnumber_cell').appendChild(text(cn));\r
1119 \r
1120         if (rdetailShowCopyLocation) {\r
1121                 var cl_cell = $n(row, 'rdetail_copylocation_cell');\r
1122                 cl_cell.appendChild(text(cl));\r
1123                 unHideMe(cl_cell);\r
1124         }\r
1125 \r
1126         _debug('setting action clicks for cn ' + cn);\r
1127 \r
1128         var dHref = 'javascript:rdetailVolumeDetails('+\r
1129                         '{copy_location : "'+cl+'", rowid : "'+row.id+'", cn :"'+cn+'", depth:"'+depth+'", org:"'+orgNode.id()+'", local: '+local+'});';\r
1130 \r
1131         var bHref = 'javascript:rdetailShowCNBrowse("' + cn + '", '+orgNode.id()+', "'+depth+'");'; \r
1132 \r
1133         unHideMe( $n(row, 'details') )\r
1134                 $n(row, 'details').setAttribute('href', dHref);\r
1135         unHideMe( $n(row, 'browse') )\r
1136                 $n(row, 'browse').setAttribute('href', bHref);\r
1137 \r
1138         if(isXUL()) {\r
1139                 unHideMe($n(row, 'hold_div'));\r
1140                 $n(row, 'hold').onclick = function() {\r
1141                         var req = new Request(FETCH_VOLUME_BY_INFO, cn, record.doc_id(), orgNode.id());\r
1142                         req.callback(\r
1143                                         function(r) {\r
1144                                         var vol = r.getResultObject();\r
1145                                         holdsDrawEditor({type: 'V', volumeObject : vol});\r
1146                                         });\r
1147                         req.send();\r
1148                 };\r
1149         }\r
1150 }\r
1151 \r
1152 // sets the path to org as 'active' and displays the path if it's local \r
1153 function rdetailSetPath(org, local) {\r
1154         if( findOrgDepth(org) == 0 ) return;\r
1155         var row = $("cp_info_" + org.id());\r
1156         row.setAttribute("hasinfo", "1");\r
1157         unHideMe(row);\r
1158         rdetailSetPath(findOrgUnit(org.parent_ou()), local);\r
1159 }\r
1160 \r
1161 //Append all the statuses for a given summary to the \r
1162 //copy summary table \r
1163 function rdetailApplyStatuses( row, template, statuses ) {\r
1164         for( var j in _statusPositions ) {\r
1165                 var stat = _statusPositions[j];\r
1166                 var val = statuses[stat.id()];\r
1167                 var nn = template.cloneNode(true);\r
1168                 if(val) nn.appendChild(text(val));\r
1169                 else nn.appendChild(text(0));\r
1170                 row.appendChild(nn);\r
1171         }\r
1172 }\r
1173 \r
1174 //Add one td (creating a new column) to the copy summary\r
1175 //table for each opac_visible copy status\r
1176 function rdetailBuildStatusColumns() {\r
1177 \r
1178         rdetailGrabCopyStatuses();\r
1179         var parent = statusRow;\r
1180         var template = parent.removeChild(G.ui.rdetail.cp_status);\r
1181 \r
1182         var i = 0;\r
1183         for( i = 0; i < cp_statuses.length; i++ ) {\r
1184 \r
1185                 var c = cp_statuses[i];\r
1186                 if( c && isTrue(c.opac_visible()) ) {\r
1187                         var name = c.name();\r
1188                         _statusPositions[i] = c;\r
1189                         var node = template.cloneNode(true);\r
1190                         var data = findNodeByName( node, config.names.rdetail.cp_status);\r
1191 \r
1192                         data.appendChild(text(name));\r
1193                         parent.appendChild(node);\r
1194                 }\r
1195         }       \r
1196 \r
1197         numStatuses = 0;\r
1198         for(x in _statusPositions) numStatuses++; \r
1199 }\r
1200 \r
1201 function rdetailGrabCopyStatuses() {\r
1202         if(cp_statuses) return cp_statuses;\r
1203         var req = new Request(FETCH_COPY_STATUSES);\r
1204         req.send(true);\r
1205         cp_statuses = req.result();\r
1206         cp_statuses = cp_statuses.sort(_rdetailSortStatuses);\r
1207 }\r
1208 \r
1209 function _rdetailSortStatuses(a, b) {\r
1210         return parseInt(a.id()) - parseInt(b.id());\r
1211 }\r
1212 \r
1213 /**\r
1214  * Check for a Google Book preview \r
1215  */\r
1216 function rdetailCheckForGBPreview() {\r
1217         if (!rdetailGoogleBookPreview) return;\r
1218         searchForGBPreview( cleanISBN(record.isbn()) );\r
1219 }\r
1220 \r
1221 /**\r
1222  *\r
1223  * @param {DOM object} query The form element containing the\r
1224  *                     input parameters "isbns"\r
1225  */\r
1226 function searchForGBPreview( isbn ) {\r
1227 \r
1228         // Delete any previous Google Booksearch JSON queries.\r
1229         var GBPJsonScript = document.getElementById("GBPJsonScript");\r
1230         if (GBPJsonScript) {\r
1231                 GBPJsonScript.parentNode.removeChild(GBPJsonScript);\r
1232         }\r
1233 \r
1234         // Add a script element with the src as the user's Google Booksearch query. \r
1235         // JSON output is specified by including the alt=json-in-script argument\r
1236         // and the callback function is also specified as a URI argument.\r
1237         var GBPScriptElement = document.createElement("script");\r
1238 \r
1239         GBPScriptElement.setAttribute("id", "GBPJsonScript");\r
1240         GBPScriptElement.setAttribute("src",\r
1241                         "http://books.google.com/books?bibkeys=" + \r
1242                         isbn + "&jscmd=viewapi&callback=GBPreviewCallback");\r
1243         GBPScriptElement.setAttribute("type", "text/javascript");\r
1244 \r
1245         // make the request to Google booksearch\r
1246         document.documentElement.firstChild.appendChild(GBPScriptElement);\r
1247 }\r
1248 \r
1249 /**\r
1250  * This function is the call-back function for the JSON scripts which \r
1251  * executes a Google book search response.\r
1252  *\r
1253  * XXX I18N of text needed\r
1254  *\r
1255  * @param {JSON} booksInfo is the JSON object pulled from the Google books service.\r
1256  */\r
1257 function GBPreviewCallback(GBPBookInfo) {\r
1258         var GBPreviewDiv = document.getElementById("rdetail_preview_div");\r
1259         var GBPBook;\r
1260 \r
1261         for ( i in GBPBookInfo ) {\r
1262                 GBPBook = GBPBookInfo[i];\r
1263         }\r
1264 \r
1265         if ( !GBPBook ) {\r
1266                 return;\r
1267         }\r
1268 \r
1269         if ( GBPBook.preview != "noview" ) {\r
1270                 if ( GBPBook.preview == 'full' ) {\r
1271                         setText( $('rdetail_preview_link'), $('rdetail_preview_full_text').innerHTML );\r
1272                         $('rdetail_preview_link_a').title = $('rdetail_preview_title').innerHTML;      \r
1273                 }\r
1274 \r
1275                 // Add a button below the book cover image to load the preview.\r
1276                 GBPBadge = document.createElement( 'img' );\r
1277                 GBPBadge.src = 'http://books.google.com/intl/en/googlebooks/images/gbs_preview_button1.gif';\r
1278                 GBPBadge.title = $('rdetail_preview_badge').innerHTML;\r
1279                 GBPBadge.style.border = 0;\r
1280                 GBPBadgelink = document.createElement( 'a' );\r
1281                 GBPBadgelink.href = 'javascript:rdetailShowExtra("preview");';\r
1282                 GBPBadgelink.appendChild( GBPBadge );\r
1283                 $('rdetail_image_cell').appendChild( GBPBadgelink );\r
1284                 $('rdetail_preview_div').style.height = 600;\r
1285 \r
1286                 /* Display the "Preview" tab in the Extras section */\r
1287                 unHideMe( $('rdetail_preview_link' ) );\r
1288         }\r
1289 }\r
1290 \r
1291 /**\r
1292  *  This is called when the user clicks on the 'Preview' link.  We assume\r
1293  *  a preview is available from Google if this link was made visible.\r
1294  *\r
1295  * XXX I18N of Google Book Preview language attribute needed\r
1296  */\r
1297 function rdetailDisplayGBPreview() {\r
1298         unHideMe($('rdetail_extras_loading'));\r
1299         GBPreviewPane = $('rdetail_preview_div');\r
1300         if ( GBPreviewPane.getAttribute('loaded') == null ||\r
1301                 GBPreviewPane.getAttribute('loaded') == "false" ) {\r
1302                 google.load("books", "0", {"callback" : rdetailGBPViewerLoadCallback, "language": "en"} );\r
1303                 GBPreviewPane.setAttribute('loaded', 'true');\r
1304         }\r
1305 }\r
1306 \r
1307 function rdetailGBPViewerLoadCallback() {\r
1308         hideMe($('rdetail_extras_loading'));\r
1309         var GBPViewer = new google.books.DefaultViewer(document.getElementById('rdetail_preview_div'));\r
1310         GBPViewer.load('ISBN:' + cleanISBN(record.isbn()) );\r
1311 \r
1312 }\r