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