RT24863: Suppress OD API on grouped records (metarecords) in search results
[sitka/overdrive-evergreen-opac.git] / src / od_pages_opac.coffee
1 # Define custom jQuery extensions to rewrite content of existing pages
2 # None of the extensions directly use the API, but they depend on od_action which does.
3
4 define [
5         'jquery'
6         'lodash'
7         'od_api'
8         'od_config'
9         'jquery-ui'
10 ], (
11         $
12         _
13         od
14         config
15 ) ->
16
17         $.fn.extend
18
19                 # Append a list of formats from a metadata object to this container
20                 _show_formats: (x) ->
21                         return @ unless x
22
23                         $x =
24                                 if x?.length > 0
25                                         $('<ul>')
26                                                 .css 'padding-left', '20px'
27                                                 .append _.map x, (f) -> $('<li>').append f.name or od.labels f.id or f.id
28                                 else
29                                         $('<span>')
30                                                 .css 'color', 'red'
31                                                 .text 'No available formats'
32
33                         @append $x
34
35
36                 # Return an Overdrive product ID or null from a given DOM context.
37                 # The context can be represented as a jQuery object or as a selector string
38                 _productID: ->
39                         hrefs = []
40                         hrefs.push('a[href*="' + productbaseURL + '"]') for productbaseURL in config.productbaseURLs
41                         href = $(hrefs.join(','), @).attr('href')
42                         /ID=(.+)/.exec(href)?[1]
43
44                 # Modify search result row to show e-holdings (available formats and
45                 # copy status of an e-title) in a result_holdings_table
46                 _results: ->
47                         result = """
48                         <tr name="e_holdings" class="result_table_title_cell">
49                                 <td colspan="2">
50                                         <table class="result_holdings_table">
51                                                 <thead>
52                                                         <tr>
53                                                                 <th>Available Formats</th>
54                                                                 <th>Status</th>
55                                                         </tr>
56                                                 </thead>
57                                                 <tbody>
58                                                         <tr>
59                                                                 <td class="formats"></td>
60                                                                 <td class="status"></td>
61                                                         </tr>
62                                                 </tbody>
63                                         </table>
64                                 </td>
65                         </tr>
66                         """
67                         # For each result row that has an embedded Overdrive product ID
68                         ids = []
69                         for row in @ when id = $(row)._productID()
70
71                                 # skip this row if it is a grouped record (metarecord)
72                                 unless $(row).find("abbr.unapi-id[title*='metabib-metarecord']").length > 0
73
74                                         # Cache the ID so that we don't need to traverse the DOM again
75                                         ids.push id
76
77                                         # Adorn each row with a product ID
78                                         $(row).prop 'id', id
79                                         # Add an empty container of format and availability values
80                                         .find '.results_info_table > tbody'
81                                                 .append result
82                                                 .end()
83                                         # Set up progress bars
84                                         ._results_meta()
85                                         ._results_avail()
86
87                         return ids
88
89                 _results_meta: (meta) ->
90                         status = if arguments.length is 0 then value: false else 'destroy'
91                         @find('.result_holdings_table .formats')
92                                 .progressbar status
93                                 ._show_formats meta?.formats
94                                 .end()
95
96                 _results_avail: (avail) ->
97                         status = if arguments.length is 0 then value: false else 'destroy'
98                         @find('.result_holdings_table .status')
99                                 .progressbar status
100                                 .end()
101
102                         return @ unless avail
103
104                         $x =
105                                 if avail.available is undefined
106                                         $('<span>')
107                                                 .css 'color', 'red'
108                                                 .text 'No longer available'
109                                 else
110                                         tpl = _.template """
111                                         <span><%= n_avail %> of <%= n_owned %> available, <%= n_holds %> holds</span>
112                                         """
113                                         $ tpl
114                                                 n_avail: avail.copiesAvailable
115                                                 n_owned: avail.copiesOwned
116                                                 n_holds:  avail.numberOfHolds
117
118                         @find('.result_holdings_table .status')
119                                 .append $x
120                                 .end()
121
122                 _record: ->
123
124                         # Find the product ID of this record
125                         id = @_productID()
126                         return unless id
127
128                         $record = $ """
129                         <div id="copy_hold_counts"><div id="#{id}">
130                                 <span id="rdetail_copy_counts">
131                                         <h2>Available formats</h2>
132                                         <div class="formats"></div>
133                                 </span>
134                                 <span id="rdetail_hold_counts">
135                                         <h2>Status</h2>
136                                         <div class="status"></div>
137                                 </span>
138                         </div></div>
139                         """
140
141                         $record
142                                 ._record_meta()
143                                 ._record_avail()
144
145                         @after $record
146                         return id
147
148                 _record_meta: (meta) ->
149
150                         status = if arguments.length is 0 then value: false else 'destroy'
151                         @find '.formats'
152                                 .progressbar status
153                                 ._show_formats meta?.formats
154                                 .end()
155
156                 _record_avail: (avail) ->
157
158                         status = if arguments.length is 0 then value: false else 'destroy'
159                         @find '.status'
160                                 .progressbar status
161                                 .end()
162
163                         return @ unless avail
164
165                         $x =
166                                 if avail.available is undefined
167                                         $('<span>')
168                                                 .css 'color', 'red'
169                                                 .text 'No longer available'
170                                 else
171                                         tpl = _.template """
172                                         <span><%= n_avail %> of <%= n_owned %> available, <%= n_holds %> holds</span>
173                                         """
174                                         $ tpl
175                                                 n_avail: avail.copiesAvailable
176                                                 n_owned: avail.copiesOwned
177                                                 n_holds: avail.numberOfHolds
178
179                         @find '.status'
180                                 .append $x
181                                 .end()
182
183                 # Replace a place hold link with another link that is more relevant to
184                 # the availability of the title in a row context.
185                 _replace_place_hold_link: (avail, type_of_interest) ->
186                         return @ unless avail
187                         
188                         if avail.available is undefined
189                                 @find '.place_hold'
190                                         .remove()
191                                         .end()
192
193                         # Find the place hold link that we want to replace
194                         $a = @find '.place_hold > a'
195
196                         # Parse the existing link text string for an indication of the item
197                         # format
198                         item_format = (text = $a.text()).match(/E-book/) or text.match(/E-audiobook/) or 'E-item'
199                         # Parse the existing link title for an item title, or if absent,
200                         # default to item format
201                         item_title = $a.prop('title').match(/on (.+)/)?[1] or item_format
202
203                         # Calculate the new text, title, and href properties, depending on
204                         # whether the user has an interest on the item and whether the item
205                         # is available or not
206                         [text, title, href] = switch type_of_interest
207
208                                 # If the user has already placed a hold on the item,
209                                 # we modify the link to go to the holds list
210                                 when 'hold'
211                                         [
212                                                 'Go to<br>E-items On Hold'
213                                                 'Go to E-items On Hold'
214                                                 '/eg/opac/myopac/holds?e_items'
215                                         ]
216
217                                 # If the user has already checked out the item,
218                                 # we modify the link to go to the checkout list
219                                 when 'checkout'
220                                         [
221                                                 'Go to<br>E-items Checked Out'
222                                                 'Go to E-items Checked Out'
223                                                 '/eg/opac/myopac/circs?e_items'
224                                         ]
225
226                                 # If the user has no prior interest in the item, we modify the
227                                 # link to go to the place hold form with the relevant query
228                                 # parameters.
229                                 else
230                                         params = $.param
231                                                 e_items: 1
232                                                 interested: avail.id
233
234                                         # The new text depends on avail.available and on the format, eg,
235                                         # Place Hold on E-book
236                                         # Place Hold on E-audiobook
237                                         # Check Out E-book
238                                         # Check Out E-audiobook
239                                         verb = if avail.available then 'Check Out' else 'Place Hold on'
240                                         url = if avail.available then '/eg/opac/myopac/circs' else '/eg/opac/myopac/holds'
241                                         [
242                                                 "#{verb}<br>#{item_format}"
243                                                 "#{verb} #{item_title}"
244                                                 "#{url}?#{params}"
245                                         ]
246
247                         # Replacing the link means we have to do three things.
248                         $a
249                         # Change the title and href properties of the link
250                         .prop
251                                 title: title
252                                 href: href
253                         # Change the alt property of the link's image, which we equate to
254                         # the link's title property
255                         .find 'img'
256                                 .prop 'alt', title
257                                 .end()
258                         # Change the contents of the text label, which resides in a
259                         # container with two possible class names, depending on whether we
260                         # are on the results page or the record page
261                         .find '.result_place_hold, .place_hold'
262                                 .replaceWith text
263                                 .end()
264
265                         return @