|
3 | 3 | * |
4 | 4 | * |
5 | 5 | * UserFrosting https://www.userfrosting.com |
6 | | - * @author Alexander Weissman https://alexanderweissman.com |
| 6 | + * @author Alexander Weissman <https://alexanderweissman.com> |
7 | 7 | */ |
8 | | -(function( $ ) |
9 | | -{ |
10 | | - /** |
11 | | - * The plugin namespace, ie for $('.selector').ufModal(options) |
12 | | - * |
13 | | - * Also the id for storing the object state via $('.selector').data() |
14 | | - */ |
15 | | - var PLUGIN_NS = 'ufModal'; |
16 | | - |
17 | | - var Plugin = function ( target, options ) |
18 | | - { |
19 | | - |
20 | | - this.$T = $(target); |
21 | | - |
22 | | - /** #### OPTIONS #### */ |
23 | | - this.options= $.extend( |
24 | | - true, // deep extend |
25 | | - { |
26 | | - sourceUrl : "", |
27 | | - ajaxParams: {}, |
28 | | - msgTarget : null, |
29 | | - DEBUG: false |
30 | | - }, |
31 | | - options |
32 | | - ); |
33 | | - |
| 8 | +;(function($, window, document, undefined) { |
| 9 | + "use strict"; |
| 10 | + |
| 11 | + // Define plugin name and defaults. |
| 12 | + var pluginName = "ufModal", |
| 13 | + defaults = { |
| 14 | + sourceUrl : "", |
| 15 | + ajaxParams: {}, |
| 16 | + msgTarget : null, |
| 17 | + DEBUG : false |
| 18 | + }; |
| 19 | + |
| 20 | + // Constructor |
| 21 | + function Plugin (element, options) { |
| 22 | + this.element = element[0]; |
| 23 | + this.$element = $(this.element); |
| 24 | + this.settings = $.extend(true, {}, defaults, options); |
| 25 | + this._defaults = defaults; |
| 26 | + this._name = pluginName; |
| 27 | + |
| 28 | + // Plugin initalisation |
34 | 29 | this.modal = null; |
35 | 30 |
|
36 | | - this._init( target ); |
37 | | - |
38 | | - return this; |
39 | | - }; |
40 | | - |
41 | | - /** #### INITIALISER #### */ |
42 | | - Plugin.prototype._init = function ( target ) |
43 | | - { |
44 | | - var base = this; |
45 | | - var $el = $(target); |
46 | | - |
47 | 31 | // Delete any existing modals attached to the element (should have been deleted already anyway) |
48 | | - if ($el.find(".modal").length) { |
49 | | - $el.find(".modal").remove(); |
| 32 | + if (this.$element.find(".modal").length) { |
| 33 | + this.$element.find(".modal").remove(); |
50 | 34 | } |
51 | 35 |
|
52 | 36 | // Fetch and render the form |
53 | 37 | $.ajax({ |
54 | 38 | type: "GET", |
55 | | - url: base.options.sourceUrl, |
56 | | - data: base.options.ajaxParams, |
| 39 | + url: this.settings.sourceUrl, |
| 40 | + data: this.settings.ajaxParams, |
57 | 41 | cache: false |
58 | 42 | }) |
59 | | - .then( |
| 43 | + .then($.proxy( |
60 | 44 | // Fetch successful |
61 | 45 | function (data) { |
62 | 46 | // Append the form as a modal dialog to the body |
63 | | - base.modal = $(data); |
64 | | - $el.append(base.modal); |
| 47 | + this.modal = $(data); |
| 48 | + this.$element.append(this.modal); |
65 | 49 |
|
66 | | - base.modal.modal('show'); |
| 50 | + this.modal.modal('show'); |
67 | 51 |
|
68 | 52 | // Bind modal to be deleted when closed |
69 | | - base.modal.on("hidden.bs.modal", function () { |
70 | | - base.destroy(); |
71 | | - }); |
| 53 | + this.modal.on("hidden.bs.modal", $.proxy(function () { |
| 54 | + this.destroy(); |
| 55 | + }), this); |
72 | 56 |
|
73 | | - base.$T.trigger('renderSuccess.ufModal'); |
| 57 | + this.$element.trigger('renderSuccess.ufModal'); |
74 | 58 | return data; |
75 | | - }, |
| 59 | + }, this), |
| 60 | + $.proxy( |
76 | 61 | // Fetch failed |
77 | 62 | function (data) { |
78 | 63 | // Error messages |
79 | 64 | if ((typeof site !== "undefined") && site.debug.ajax && data.responseText) { |
80 | | - base.$T.trigger('renderError.ufModal'); |
| 65 | + this.$element.trigger('renderError.ufModal'); |
81 | 66 | document.write(data.responseText); |
82 | 67 | document.close(); |
83 | 68 | } else { |
84 | | - if (base.options.DEBUG) { |
| 69 | + if (this.settings.DEBUG) { |
85 | 70 | console.log("Error (" + data.status + "): " + data.responseText ); |
86 | 71 | } |
87 | 72 | // Display errors on failure |
88 | | - // TODO: ufAlerts widget should have a 'destroy' method |
89 | | - if (!base.options.msgTarget.data('ufAlerts')) { |
90 | | - base.options.msgTarget.ufAlerts(); |
| 73 | + // TODO: ufAlerts widget should have a 'destroy' method (UPDATE: It does) |
| 74 | + if (!this.settings.msgTarget.data('ufAlerts')) { |
| 75 | + this.settings.msgTarget.ufAlerts(); |
91 | 76 | } else { |
92 | | - base.options.msgTarget.ufAlerts('clear'); |
| 77 | + this.settings.msgTarget.ufAlerts('clear'); |
93 | 78 | } |
94 | 79 |
|
95 | | - base.options.msgTarget.ufAlerts('fetch').ufAlerts('render'); |
96 | | - base.options.msgTarget.on("render.ufAlerts", function () { |
97 | | - base.$T.trigger('renderError.ufModal'); |
98 | | - }); |
| 80 | + this.settings.msgTarget.ufAlerts('fetch').ufAlerts('render'); |
| 81 | + this.settings.msgTarget.on("render.ufAlerts", $.proxy(function () { |
| 82 | + this.$element.trigger('renderError.ufModal'); |
| 83 | + }, this)); |
99 | 84 | } |
100 | 85 |
|
101 | | - base.destroy(); |
| 86 | + this.destroy(); |
102 | 87 |
|
103 | 88 | return data; |
104 | | - } |
| 89 | + }, this) |
105 | 90 | ); |
106 | | - }; |
107 | 91 |
|
108 | | - Plugin.prototype.destroy = function () { |
109 | | - var base = this; |
110 | | - var $el = base.$T; |
| 92 | + return this; |
| 93 | + } |
111 | 94 |
|
112 | | - // Delete the plugin object |
113 | | - base.delete; |
| 95 | + // Functions |
| 96 | + $.extend(Plugin.prototype, { |
| 97 | + /** |
| 98 | + * Returns underlying model |
| 99 | + */ |
| 100 | + getModal: function() { |
| 101 | + return this.modal; |
| 102 | + }, |
| 103 | + /** |
| 104 | + * Destroys instance |
| 105 | + */ |
| 106 | + destroy: function() { |
| 107 | + // Remove the modal from the selector |
| 108 | + if (this.modal) { |
| 109 | + this.modal.remove(); |
| 110 | + } |
114 | 111 |
|
115 | | - // Remove the modal from the selector |
116 | | - if (base.modal) { |
117 | | - base.modal.remove(); |
118 | | - } |
| 112 | + // Unbind any bound events |
| 113 | + this.$element.off('.' + this.pluginName); |
119 | 114 |
|
120 | | - // Unbind any modal events bound to the selector |
121 | | - $el.off('.ufModal'); |
| 115 | + // Grab jQuery wrapped element before plugin destruction |
| 116 | + var $element = this.$element; |
122 | 117 |
|
123 | | - // Remove plugin name from selector's data-* attribute |
124 | | - $el.removeData(PLUGIN_NS); |
125 | | - }; |
| 118 | + // Remove plugin from element |
| 119 | + this.$element.removeData(this.pluginName); |
126 | 120 |
|
127 | | - Plugin.prototype.getModal = function () { |
128 | | - return this.modal; |
129 | | - }; |
130 | | - |
131 | | - /** |
132 | | - * EZ Logging/Warning (technically private but saving an '_' is worth it imo) |
133 | | - */ |
134 | | - Plugin.prototype.DLOG = function () |
135 | | - { |
136 | | - if (!this.DEBUG) return; |
137 | | - for (var i in arguments) { |
138 | | - console.log( PLUGIN_NS + ': ', arguments[i] ); |
| 121 | + return $element; |
139 | 122 | } |
140 | | - } |
141 | | - Plugin.prototype.DWARN = function () |
142 | | - { |
143 | | - this.DEBUG && console.warn( arguments ); |
144 | | - } |
145 | | - |
146 | | - |
147 | | -/*################################################################################### |
148 | | - * JQUERY HOOK |
149 | | - ###################################################################################*/ |
150 | | - |
151 | | - /** |
152 | | - * Generic jQuery plugin instantiation method call logic |
153 | | - * |
154 | | - * Method options are stored via jQuery's data() method in the relevant element(s) |
155 | | - * Notice, myActionMethod mustn't start with an underscore (_) as this is used to |
156 | | - * indicate private methods on the PLUGIN class. |
157 | | - */ |
158 | | - $.fn[ PLUGIN_NS ] = function( methodOrOptions ) |
159 | | - { |
160 | | - if (!$(this).length) { |
161 | | - return $(this); |
| 123 | + }); |
| 124 | + |
| 125 | + // Handles instantiation and access to non-private methods. |
| 126 | + $.fn[pluginName] = function(methodOrOptions) { |
| 127 | + // Grab plugin instance |
| 128 | + var instance = $(this).data(pluginName); |
| 129 | + // If undefined or object, initalise plugin. |
| 130 | + if (methodOrOptions === undefined || typeof methodOrOptions === 'object') { |
| 131 | + // Only initalise if not previously done. |
| 132 | + if (!instance) { |
| 133 | + $(this).data(pluginName, new Plugin(this, methodOrOptions)); |
| 134 | + } |
| 135 | + return this; |
162 | 136 | } |
163 | | - var instance = $(this).data(PLUGIN_NS); |
164 | | - |
165 | | - // CASE: action method (public method on PLUGIN class) |
166 | | - if ( instance |
167 | | - && methodOrOptions.indexOf('_') != 0 |
168 | | - && instance[ methodOrOptions ] |
169 | | - && typeof( instance[ methodOrOptions ] ) == 'function' ) { |
170 | | - |
171 | | - return instance[ methodOrOptions ]( Array.prototype.slice.call( arguments, 1 ) ); |
172 | | - |
173 | | - |
174 | | - // CASE: argument is options object or empty = initialise |
175 | | - } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { |
176 | | - |
177 | | - instance = new Plugin( $(this), methodOrOptions ); // ok to overwrite if this is a re-init |
178 | | - $(this).data( PLUGIN_NS, instance ); |
179 | | - return $(this); |
180 | | - |
181 | | - // CASE: method called before init |
182 | | - } else if ( !instance ) { |
183 | | - $.error( 'Plugin must be initialised before using method: ' + methodOrOptions ); |
184 | | - |
185 | | - // CASE: invalid method |
186 | | - } else if ( methodOrOptions.indexOf('_') == 0 ) { |
187 | | - $.error( 'Method ' + methodOrOptions + ' is private!' ); |
188 | | - } else { |
| 137 | + // Otherwise ensure first parameter is a valid string, and is the name of an actual function. |
| 138 | + else if (typeof methodOrOptions === 'string' && typeof instance[methodOrOptions] === 'function') { |
| 139 | + // Ensure not a private function |
| 140 | + if (methodOrOptions.indexOf('_') !== 0) { |
| 141 | + return instance[methodOrOptions]( Array.prototype.slice.call(arguments, 1)); |
| 142 | + } |
| 143 | + else { |
| 144 | + $.error( 'Method ' + methodOrOptions + ' is private!' ); |
| 145 | + } |
| 146 | + } |
| 147 | + else { |
189 | 148 | $.error( 'Method ' + methodOrOptions + ' does not exist.' ); |
190 | 149 | } |
191 | 150 | }; |
192 | | -})(jQuery); |
| 151 | +})(jQuery, window, document); |
| 152 | + |
0 commit comments