Skip to content

Commit 939bdc9

Browse files
Rebased ufModal with new jQuery plugin template.
1 parent be6741f commit 939bdc9

2 files changed

Lines changed: 100 additions & 140 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
- Implement reflow and column selector for tables (#670)
55
- Overhauled ufAlerts, improving efficiency, reliability, and fixed a discovered edge case that caused `render` to never complete. (part of #646)
66
- ufAlerts will only auto-scroll when outside the viewport (even if only partially). Can be overriden with `scrollWhenVisible: true`. (#714)
7-
- Rebased ufCollection, and ufForm with new jQuery plugin template. (part of #646)
7+
- Rebased ufCollection, ufForm, and ufModal with new jQuery plugin template. (part of #646)
88
- Misc UI update
99
- Added Twig blocks
1010
- Fix issue with duplicate query logs when using multiple databases

app/sprinkles/core/assets/local/core/js/uf-modal.js

Lines changed: 99 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -3,190 +3,150 @@
33
*
44
*
55
* UserFrosting https://www.userfrosting.com
6-
* @author Alexander Weissman https://alexanderweissman.com
6+
* @author Alexander Weissman <https://alexanderweissman.com>
77
*/
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
3429
this.modal = null;
3530

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-
4731
// 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();
5034
}
5135

5236
// Fetch and render the form
5337
$.ajax({
5438
type: "GET",
55-
url: base.options.sourceUrl,
56-
data: base.options.ajaxParams,
39+
url: this.settings.sourceUrl,
40+
data: this.settings.ajaxParams,
5741
cache: false
5842
})
59-
.then(
43+
.then($.proxy(
6044
// Fetch successful
6145
function (data) {
6246
// 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);
6549

66-
base.modal.modal('show');
50+
this.modal.modal('show');
6751

6852
// 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);
7256

73-
base.$T.trigger('renderSuccess.ufModal');
57+
this.$element.trigger('renderSuccess.ufModal');
7458
return data;
75-
},
59+
}, this),
60+
$.proxy(
7661
// Fetch failed
7762
function (data) {
7863
// Error messages
7964
if ((typeof site !== "undefined") && site.debug.ajax && data.responseText) {
80-
base.$T.trigger('renderError.ufModal');
65+
this.$element.trigger('renderError.ufModal');
8166
document.write(data.responseText);
8267
document.close();
8368
} else {
84-
if (base.options.DEBUG) {
69+
if (this.settings.DEBUG) {
8570
console.log("Error (" + data.status + "): " + data.responseText );
8671
}
8772
// 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();
9176
} else {
92-
base.options.msgTarget.ufAlerts('clear');
77+
this.settings.msgTarget.ufAlerts('clear');
9378
}
9479

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));
9984
}
10085

101-
base.destroy();
86+
this.destroy();
10287

10388
return data;
104-
}
89+
}, this)
10590
);
106-
};
10791

108-
Plugin.prototype.destroy = function () {
109-
var base = this;
110-
var $el = base.$T;
92+
return this;
93+
}
11194

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+
}
114111

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);
119114

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;
122117

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);
126120

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;
139122
}
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;
162136
}
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 {
189148
$.error( 'Method ' + methodOrOptions + ' does not exist.' );
190149
}
191150
};
192-
})(jQuery);
151+
})(jQuery, window, document);
152+

0 commit comments

Comments
 (0)