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