forked from instructure/canvas-lms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathModuleSequenceFooter.coffee
More file actions
183 lines (154 loc) · 6.85 KB
/
Copy pathModuleSequenceFooter.coffee
File metadata and controls
183 lines (154 loc) · 6.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
define [
'jquery'
'jst/jquery/ModuleSequenceFooter'
'underscore'
'i18n!sequence_footer'
'str/htmlEscape'
'jquery.ajaxJSON'
], (jQuery, template, _, I18n, htmlEscape) ->
# Summary
# Creates a new ModuleSequenceFooter so clicking to see the next item in a module
# can be done easily.
#
# Required options:
# assetType : string
# assetID : integer
#
# ie:
# $('#footerDiv').moduleSequenceFooter({
# assetType: 'Assignment'
# assetID: 1
# courseID: 25
# })
#
# You can optionaly set options on the prototype for all instances of this plugin by default
# by doing:
#
# $.fn.moduleSequenceFooter.options = {
# assetType: 'Assigbnment'
# assetID: 1
# courseID: 25
# }
((($, window, document, template) ->
msfInstanceCounter = 0
$.fn.moduleSequenceFooter = (options={}) ->
# You must pass in a assetType and assetId or we throw an error.
unless options.assetType and options.assetID
throw 'Option must be set with assetType and assetID'
return
@msfAnimation = (enabled) =>
@find('.module-sequence-padding, .module-sequence-footer').toggleClass('no-animation', !enabled)
# After fetching, @msfInstance will have the following
# @hide: bool
# @previous: Object
# @next : Object
@msfInstance = new $.fn.moduleSequenceFooter.MSFClass options
@msfInstance.fetch().done =>
if @msfInstance.hide
@hide()
return
@html template(
instanceNumber: @msfInstance.instanceNumber
previous: @msfInstance.previous
next: @msfInstance.next
)
@msfAnimation(options.animation) if options?.animation != undefined
@show()
$(window).triggerHandler('resize');
this
$.fn.moduleSequenceFooter.MSFClass = class ModuleSequenceFooter
# Icon class map used to determine which icon class should be placed
# on a tooltip
# @api private
iconClasses:
'ModuleItem' : "icon-module"
'File' : "icon-download"
'Page' : "icon-document"
'Discussion' : "icon-discussion"
'Assignment' : "icon-assignment"
'Quiz' : "icon-quiz"
'ExternalTool' : "icon-link"
'Lti::MessageHandler' : "icon-link"
# Sets up the class variables and generates a url. Fetch should be
# called somewhere else to set up the data.
constructor: (options) ->
@instanceNumber = msfInstanceCounter++
@courseID = options?.courseID || ENV?.course_id
@assetID = options?.assetID
@assetType = options?.assetType
@location = options?.location || document.location
@previous = {}
@next = {}
@url = "/api/v1/courses/#{@courseID}/module_item_sequence"
getQueryParams: (qs) ->
qs = qs.split("+").join(" ")
params = {}
re = /[?&]?([^=]+)=([^&]*)/g
while (tokens = re.exec(qs))
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2])
params
# Retrieve data based on the url, asset_type and asset_id. @success is called after a
# fetch is finished. This will then setup data to be used elsewhere.
# @api public
fetch: ->
params = @getQueryParams(@location.search)
if params.module_item_id
$.ajaxJSON @url, 'GET', {asset_type: 'ModuleItem', asset_id: params.module_item_id, frame_external_urls: true}, @success, null, {}
else
$.ajaxJSON @url, 'GET', {asset_type: @assetType, asset_id: @assetID, frame_external_urls: true}, @success, null, {}
# Determines if the data retrieved should be used to generate a buttom bar or hide it. We
# can only have 1 item in the data set for this to work else we hide the sequence bar.
# # @api private
success: (data) =>
@modules = data.modules
# Currently only supports 1 item in the items array
unless data?.items?.length == 1
@hide = true
return
@item = data.items[0]
# Show the buttons if they aren't null
@buildNextData() if (@next.show = @item.next)
@buildPreviousData() if (@previous.show = @item.prev)
# Each button needs to build a data that the handlebars template can use. For example, data for
# each button could look like this:
# @previous = previous: {
# show: true
# url: http://foobar.baz
# tooltip: <strong>Previous Module:</strong> <br> Going to the fair
# tooltipText: Previous Module: Going to the fair
# }
#
# If the previous item is in another module, then the module ids won't be the same and we need
# to display the module name instead of the item title.
# @api private
buildPreviousData: ->
@previous.url = @item.prev.html_url
if @item.current.module_id == @item.prev.module_id
@previous.tooltip = "<i class='#{htmlEscape @iconClasses[@item.prev.type]}'></i> #{htmlEscape @item.prev.title}"
@previous.tooltipText = I18n.t('prev_module_item_desc', 'Previous: *item*', wrapper: @item.prev.title)
else # module id is different
module = _.find @modules, (m) => m.id == @item.prev.module_id
@previous.tooltip = "<strong style='float:left'>#{htmlEscape I18n.t('prev_module', 'Previous Module:')}</strong> <br> #{htmlEscape module.name}"
@previous.tooltipText = I18n.t('prev_module_desc', 'Previous Module: *module*', wrapper: module.name)
# Each button needs to build a data that the handlebars template can use. For example, data for
# each button could look like this:
# @next = next: {
# show: true
# url: http://foobar.baz
# tooltip: <strong>Next Module:</strong> <br> Going to the fair
# tooltipText: Next Module: Going to the fair
# }
#
# If the next item is in another module, then the module ids won't be the same and we need
# to display the module name instead of the item title.
# @api private
buildNextData: ->
@next.url = @item.next.html_url
if @item.current.module_id == @item.next.module_id
@next.tooltip = "<i class='#{htmlEscape @iconClasses[@item.next.type]}'></i> #{htmlEscape @item.next.title}"
@next.tooltipText = I18n.t('next_module_item_desc', 'Next: *item*', wrapper: @item.next.title)
else # module id is different
module = _.find @modules, (m) => m.id == @item.next.module_id
@next.tooltip = "<strong style='float:left'>#{htmlEscape I18n.t('next_module', 'Next Module:')}</strong> <br> #{htmlEscape module.name}"
@next.tooltipText = I18n.t('next_module_desc', 'Next Module: *module*', wrapper: module.name)
))( jQuery, window, document, template)