|
1 | 1 | /** |
2 | 2 | * Autosave functionality for exercises. |
3 | 3 | */ |
4 | | -(function(window) { |
| 4 | + (function($, window) { |
5 | 5 | "use strict"; |
6 | 6 |
|
7 | 7 | const pluginName = "aplusAutoSave"; |
8 | | - const defaults = { |
| 8 | + var defaults = { |
9 | 9 | autoSaveIndicatorClasses: "small", |
10 | 10 | autoSaveInterval: 10000, // ms |
11 | 11 | }; |
12 | 12 |
|
13 | 13 | function AplusAutoSave(element, options) { |
14 | 14 | this.dom_element = element; |
15 | | - this.settings = Object.assign({}, defaults, options); |
| 15 | + this.element = $(element); |
| 16 | + this.settings = $.extend({}, defaults, options); |
16 | 17 | this.autoSaveTimeoutHandle = null; |
17 | 18 | this.autoSaveRequest = null; |
18 | 19 | this.autoSaveUrl = null; |
19 | 20 | this.autoSaveIndicator = null; |
20 | 21 | this.init(); |
21 | 22 | } |
22 | 23 |
|
23 | | - AplusAutoSave.prototype = { |
| 24 | + $.extend(AplusAutoSave.prototype, { |
24 | 25 | /** |
25 | 26 | * Initializes the autosave functionality for this form. |
26 | 27 | */ |
27 | 28 | init: function() { |
28 | 29 | const self = this; |
29 | 30 |
|
30 | | - const submitUrl = new URL(self.dom_element.getAttribute("action"), window.location); |
| 31 | + const submitUrl = new URL(self.element.attr("action"), window.location); |
31 | 32 | self.autoSaveUrl = new URL("draft/", submitUrl).href; |
32 | 33 |
|
33 | | - self.autoSaveIndicator = document.createElement("div"); |
34 | | - self.autoSaveIndicator.className = self.settings.autoSaveIndicatorClasses; |
35 | | - self.dom_element.appendChild(self.autoSaveIndicator); |
| 34 | + self.autoSaveIndicator = $("<div></div>") |
| 35 | + .addClass(self.settings.autoSaveIndicatorClasses) |
| 36 | + .appendTo(self.element); |
36 | 37 |
|
37 | | - const timestamp = self.dom_element.dataset.draftTimestamp; |
| 38 | + const timestamp = self.element.data("draft-timestamp"); |
38 | 39 | if (timestamp) { |
39 | 40 | self.setIndicatorSaveDate(new Date(timestamp)); |
40 | 41 | } |
41 | 42 |
|
42 | | - self.dom_element.addEventListener("input", function() { |
| 43 | + self.element.on("input", function() { |
43 | 44 | self.scheduleAutoSave(); |
44 | 45 | }); |
45 | | - self.dom_element.addEventListener("submit", function() { |
| 46 | + self.element.on("submit", function() { |
46 | 47 | // Cancel the autosave (if it was scheduled) when an actual submission |
47 | 48 | // is made. |
48 | 49 | clearTimeout(self.autoSaveTimeoutHandle); |
49 | | - self.autoSaveIndicator.textContent = ""; |
| 50 | + self.autoSaveIndicator.text(""); |
50 | 51 | }); |
51 | 52 | }, |
52 | 53 |
|
|
71 | 72 | // If a save HTTP request is currently active, wait until it's done |
72 | 73 | // before scheduling the next save. |
73 | 74 | if (self.autoSaveRequest) { |
74 | | - self.autoSaveRequest.finally(scheduleAutoSaveInternal); |
| 75 | + self.autoSaveRequest.always(scheduleAutoSaveInternal); |
75 | 76 | } else { |
76 | 77 | scheduleAutoSaveInternal(); |
77 | 78 | } |
|
83 | 84 | */ |
84 | 85 | doAutoSave: function() { |
85 | 86 | const self = this; |
86 | | - self.autoSaveIndicator.textContent = "Saving draft..."; |
87 | | - |
88 | | - self.autoSaveRequest = fetch(self.autoSaveUrl, { |
89 | | - method: "POST", |
90 | | - body: new FormData(self.dom_element), |
91 | | - }).then(function(response) { |
92 | | - if (!response.ok) { |
93 | | - throw new Error("Failed to save draft"); |
94 | | - } |
| 87 | + self.autoSaveIndicator.text(_("Saving draft...")); |
| 88 | + |
| 89 | + self.autoSaveRequest = $.ajax({ |
| 90 | + url: self.autoSaveUrl, |
| 91 | + type: "POST", |
| 92 | + data: new FormData(self.dom_element), |
| 93 | + contentType: false, |
| 94 | + processData: false, |
| 95 | + }).fail(function() { |
| 96 | + self.autoSaveIndicator.text(_("Failed to save draft")); |
| 97 | + }).done(function() { |
95 | 98 | self.setIndicatorSaveDate(new Date()); |
96 | | - }).catch(function() { |
97 | | - self.autoSaveIndicator.textContent = "Failed to save draft"; |
98 | | - }).finally(function() { |
| 99 | + }).always(function() { |
99 | 100 | // Allow new autosave requests. |
100 | 101 | self.autoSaveRequest = null; |
101 | 102 | }); |
|
116 | 117 | language = "en-GB"; |
117 | 118 | } |
118 | 119 | const dateString = date.toLocaleString(language); |
119 | | - this.autoSaveIndicator.textContent = "Draft saved " + dateString; |
| 120 | + this.autoSaveIndicator.text(_("Draft saved") + " " + dateString); |
120 | 121 | }, |
121 | | - }; |
| 122 | + }); |
122 | 123 |
|
123 | | - window[pluginName] = function(element, options) { |
124 | | - if (!element[pluginName]) { |
125 | | - element[pluginName] = new AplusAutoSave(element, options); |
126 | | - } |
| 124 | + $.fn[pluginName] = function(options) { |
| 125 | + return this.each(function() { |
| 126 | + if (!$.data(this, "plugin_" + pluginName)) { |
| 127 | + $.data(this, "plugin_" + pluginName, new AplusAutoSave(this, options)); |
| 128 | + } |
| 129 | + }); |
127 | 130 | }; |
128 | | -})(window); |
| 131 | +})(jQuery, window); |
0 commit comments