1+ /**
2+ * @name Simple modal
3+ * @author Matt Hinchliffe
4+ * @modified 07/03/2012
5+ * @version 0.6.4
6+ * @requires jQuery 1.7+
7+ * @description A simple modal overlay
8+ * @example
9+ * var $modal = $('body').modal().data('modal');
10+ *
11+ * $.ajax({
12+ * url: [url],
13+ * success: function(data)
14+ * {
15+ * $modal.open(data, callback);
16+ * }
17+ * });
18+ *
19+ * @example
20+ * <div class="modal-wrapper">
21+ * <div class="modal-content" />
22+ * <span class="modal-close" data-toggle="modal">Close</span>
23+ * </div>
24+ * <div class="modal-overlay" data-toggle="modal" />
25+ */
26+
27+ ; ( function ( $ , undefined )
28+ {
29+ "use strict" ;
30+
31+ function Modal ( target , options )
32+ {
33+ this . opts = $ . extend ( { } , {
34+ onopen : undefined ,
35+ onclose : undefined ,
36+ onupdate : undefined ,
37+ width : 640 ,
38+ height : 480 ,
39+ fixed : true ,
40+ overlay : true
41+ } , options ) ;
42+ this . target = target ;
43+
44+ return this ;
45+ }
46+
47+ Modal . prototype = {
48+
49+ isOpen : false ,
50+
51+ isInitialized : false ,
52+
53+ /**
54+ * Instantiate
55+ *
56+ * @description Create the structure on first run
57+ */
58+ _init : function ( )
59+ {
60+ if ( this . isInitialized )
61+ {
62+ return ;
63+ }
64+
65+ // Build modal
66+ this . wrapper = $ ( '<div class="modal-wrapper"><span class="modal-close" data-toggle="modal">Close</span></div>' ) . css ( {
67+ position : 'absolute' ,
68+ width : this . opts . width ,
69+ height : this . opts . height
70+ } ) ;
71+ this . content = $ ( '<div class="modal-content" />' ) . appendTo ( this . wrapper ) ;
72+ this . wrapper . appendTo ( this . target ) ;
73+
74+ // Create overlay
75+ if ( this . opts . overlay )
76+ {
77+ this . overlay = $ ( '<div class="modal-overlay" data-toggle="modal" />' )
78+ . css ( {
79+ position : 'absolute' ,
80+ top : 0 ,
81+ left : 0
82+ } )
83+ . appendTo ( this . target ) ;
84+ }
85+
86+ // Bind events and get dimensions from the window if attached to the body
87+ this . context = this . target . nodeName . toLowerCase ( ) === 'body' ? $ ( window ) : $ ( this . target ) . css ( 'position' , 'relative' ) ;
88+
89+ // Only fix the modal if attached to the body
90+ if ( this . opts . fixed )
91+ {
92+ this . opts . fixed = $ . isWindow ( this . context )
93+ }
94+
95+ this . isInitialized = true ;
96+ } ,
97+
98+ /**
99+ * Align
100+ *
101+ * @description Centre modal window and size overlay to fit
102+ */
103+ align : function ( )
104+ {
105+ var height = this . wrapper . height ( ) ,
106+ width = this . wrapper . width ( ) ,
107+ maxHeight = this . context . height ( ) ,
108+ maxWidth = this . context . width ( ) ,
109+ top = this . context . scrollTop ( ) ;
110+
111+ this . wrapper . css (
112+ {
113+ top : height < maxHeight ? ( ( maxHeight - height ) / 2 ) + top : top ,
114+ left : width < maxWidth ? ( maxWidth - width ) / 2 : 0
115+ } ) ;
116+
117+ if ( this . opts . overlay )
118+ {
119+ this . overlay . css ( {
120+ top : top ,
121+ width : maxWidth ,
122+ height : maxHeight
123+ } ) ;
124+ }
125+ } ,
126+
127+ /**
128+ * Open
129+ *
130+ * @description Open the modal window
131+ * @param {object } content
132+ * @param {function } callback
133+ */
134+ open : function ( content , callback )
135+ {
136+ if ( ! this . isInitialized )
137+ {
138+ this . _init ( ) ;
139+ }
140+ else if ( this . isOpen )
141+ {
142+ return ;
143+ }
144+
145+ var self = this ;
146+
147+ if ( this . opts . fixed )
148+ {
149+ this . context . on ( 'resize.modal scroll.modal' , function ( )
150+ {
151+ self . align ( ) ;
152+ } ) ;
153+ }
154+
155+ this . context . on ( 'click.modal' , '[data-toggle="modal"]' , function ( e )
156+ {
157+ e . preventDefault ( ) ;
158+ self . close ( ) ;
159+ } ) ;
160+
161+ // Add content to window
162+ this . content . html ( content ) ;
163+
164+ // Fade in
165+ this . wrapper
166+ . add ( this . overlay )
167+ . stop ( )
168+ . fadeIn ( ) ;
169+
170+ // Move into position
171+ this . align ( ) ;
172+ this . isOpen = true ;
173+
174+ if ( this . opts . onopen )
175+ {
176+ this . opts [ 'onopen' ] ( ) ;
177+ }
178+ } ,
179+
180+ /**
181+ * Update
182+ *
183+ * @description Change the modal window contents
184+ * @param content
185+ */
186+ update : function ( content )
187+ {
188+ this . content . html ( content ) ;
189+
190+ if ( this . isOpen )
191+ {
192+ this . align ( ) ;
193+
194+ if ( this . opts . onupdate )
195+ {
196+ this . opts [ 'onupdate' ] ( ) ;
197+ }
198+ }
199+ } ,
200+
201+ /**
202+ * Close
203+ *
204+ * @description Close the modal window and clear contents
205+ */
206+ close : function ( )
207+ {
208+ if ( ! this . isInitialized || ! this . isOpen )
209+ {
210+ return ;
211+ }
212+
213+ var self = this ;
214+
215+ // Unbind resize event
216+ if ( this . opts . fixed )
217+ {
218+ this . context . unbind ( '.modal' ) ;
219+ }
220+
221+ // Fade out
222+ this . wrapper
223+ . add ( this . overlay )
224+ . stop ( )
225+ . fadeOut ( function ( )
226+ {
227+ self . content [ 0 ] . innerHTML = '' ;
228+ } ) ;
229+
230+ this . isOpen = false ;
231+
232+ if ( this . opts . onclose )
233+ {
234+ this . opts [ 'onclose' ] ( ) ;
235+ }
236+ }
237+ } ;
238+
239+ // jQuery plugin wrapper
240+ $ . fn . modal = function ( options )
241+ {
242+ return this . each ( function ( )
243+ {
244+ $ . data ( this , 'modal' , new Modal ( this , options ) ) ;
245+ } ) ;
246+ } ;
247+
248+ } ) ( jQuery ) ;
0 commit comments