diff options
Diffstat (limited to 'js/core/modal.js')
-rwxr-xr-x | js/core/modal.js | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/js/core/modal.js b/js/core/modal.js new file mode 100755 index 0000000..74d122d --- /dev/null +++ b/js/core/modal.js | |||
@@ -0,0 +1,393 @@ | |||
1 | /*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ | ||
2 | (function(UI) { | ||
3 | |||
4 | "use strict"; | ||
5 | |||
6 | var active = false, activeCount = 0, $html = UI.$html, body; | ||
7 | |||
8 | UI.$win.on("resize orientationchange", UI.Utils.debounce(function(){ | ||
9 | UI.$('.uk-modal.uk-open').each(function(){ | ||
10 | UI.$(this).data('modal').resize(); | ||
11 | }); | ||
12 | }, 150)); | ||
13 | |||
14 | UI.component('modal', { | ||
15 | |||
16 | defaults: { | ||
17 | keyboard: true, | ||
18 | bgclose: true, | ||
19 | minScrollHeight: 150, | ||
20 | center: false, | ||
21 | modal: true | ||
22 | }, | ||
23 | |||
24 | scrollable: false, | ||
25 | transition: false, | ||
26 | hasTransitioned: true, | ||
27 | |||
28 | init: function() { | ||
29 | |||
30 | if (!body) body = UI.$('body'); | ||
31 | |||
32 | if (!this.element.length) return; | ||
33 | |||
34 | var $this = this; | ||
35 | |||
36 | this.paddingdir = "padding-" + (UI.langdirection == 'left' ? "right":"left"); | ||
37 | this.dialog = this.find(".uk-modal-dialog"); | ||
38 | |||
39 | this.active = false; | ||
40 | |||
41 | // Update ARIA | ||
42 | this.element.attr('aria-hidden', this.element.hasClass("uk-open")); | ||
43 | |||
44 | this.on("click", ".uk-modal-close", function(e) { | ||
45 | e.preventDefault(); | ||
46 | $this.hide(); | ||
47 | }).on("click", function(e) { | ||
48 | |||
49 | var target = UI.$(e.target); | ||
50 | |||
51 | if (target[0] == $this.element[0] && $this.options.bgclose) { | ||
52 | $this.hide(); | ||
53 | } | ||
54 | }); | ||
55 | |||
56 | UI.domObserve(this.element, function(e) { $this.resize(); }); | ||
57 | }, | ||
58 | |||
59 | toggle: function() { | ||
60 | return this[this.isActive() ? "hide" : "show"](); | ||
61 | }, | ||
62 | |||
63 | show: function() { | ||
64 | |||
65 | if (!this.element.length) return; | ||
66 | |||
67 | var $this = this; | ||
68 | |||
69 | if (this.isActive()) return; | ||
70 | |||
71 | if (this.options.modal && active) { | ||
72 | active.hide(true); | ||
73 | } | ||
74 | |||
75 | this.element.removeClass("uk-open").show(); | ||
76 | this.resize(true); | ||
77 | |||
78 | if (this.options.modal) { | ||
79 | active = this; | ||
80 | } | ||
81 | |||
82 | this.active = true; | ||
83 | |||
84 | activeCount++; | ||
85 | |||
86 | if (UI.support.transition) { | ||
87 | this.hasTransitioned = false; | ||
88 | this.element.one(UI.support.transition.end, function(){ | ||
89 | $this.hasTransitioned = true; | ||
90 | }).addClass("uk-open"); | ||
91 | } else { | ||
92 | this.element.addClass("uk-open"); | ||
93 | } | ||
94 | |||
95 | $html.addClass("uk-modal-page").height(); // force browser engine redraw | ||
96 | |||
97 | // Update ARIA | ||
98 | this.element.attr('aria-hidden', 'false'); | ||
99 | |||
100 | this.element.trigger("show.uk.modal"); | ||
101 | |||
102 | UI.Utils.checkDisplay(this.dialog, true); | ||
103 | |||
104 | return this; | ||
105 | }, | ||
106 | |||
107 | hide: function(force) { | ||
108 | |||
109 | if (!force && UI.support.transition && this.hasTransitioned) { | ||
110 | |||
111 | var $this = this; | ||
112 | |||
113 | this.one(UI.support.transition.end, function() { | ||
114 | $this._hide(); | ||
115 | }).removeClass("uk-open"); | ||
116 | |||
117 | } else { | ||
118 | |||
119 | this._hide(); | ||
120 | } | ||
121 | |||
122 | return this; | ||
123 | }, | ||
124 | |||
125 | resize: function(force) { | ||
126 | |||
127 | if (!this.isActive() && !force) return; | ||
128 | |||
129 | var bodywidth = body.width(); | ||
130 | |||
131 | this.scrollbarwidth = window.innerWidth - bodywidth; | ||
132 | |||
133 | body.css(this.paddingdir, this.scrollbarwidth); | ||
134 | |||
135 | this.element.css('overflow-y', this.scrollbarwidth ? 'scroll' : 'auto'); | ||
136 | |||
137 | if (!this.updateScrollable() && this.options.center) { | ||
138 | |||
139 | var dh = this.dialog.outerHeight(), | ||
140 | pad = parseInt(this.dialog.css('margin-top'), 10) + parseInt(this.dialog.css('margin-bottom'), 10); | ||
141 | |||
142 | if ((dh + pad) < window.innerHeight) { | ||
143 | this.dialog.css({'top': (window.innerHeight/2 - dh/2) - pad }); | ||
144 | } else { | ||
145 | this.dialog.css({'top': ''}); | ||
146 | } | ||
147 | } | ||
148 | }, | ||
149 | |||
150 | updateScrollable: function() { | ||
151 | |||
152 | // has scrollable? | ||
153 | var scrollable = this.dialog.find('.uk-overflow-container:visible:first'); | ||
154 | |||
155 | if (scrollable.length) { | ||
156 | |||
157 | scrollable.css('height', 0); | ||
158 | |||
159 | var offset = Math.abs(parseInt(this.dialog.css('margin-top'), 10)), | ||
160 | dh = this.dialog.outerHeight(), | ||
161 | wh = window.innerHeight, | ||
162 | h = wh - 2*(offset < 20 ? 20:offset) - dh; | ||
163 | |||
164 | scrollable.css({ | ||
165 | 'max-height': (h < this.options.minScrollHeight ? '':h), | ||
166 | 'height':'' | ||
167 | }); | ||
168 | |||
169 | return true; | ||
170 | } | ||
171 | |||
172 | return false; | ||
173 | }, | ||
174 | |||
175 | _hide: function() { | ||
176 | |||
177 | this.active = false; | ||
178 | if (activeCount > 0) activeCount--; | ||
179 | else activeCount = 0; | ||
180 | |||
181 | this.element.hide().removeClass('uk-open'); | ||
182 | |||
183 | // Update ARIA | ||
184 | this.element.attr('aria-hidden', 'true'); | ||
185 | |||
186 | if (!activeCount) { | ||
187 | $html.removeClass('uk-modal-page'); | ||
188 | body.css(this.paddingdir, ""); | ||
189 | } | ||
190 | |||
191 | if (active===this) active = false; | ||
192 | |||
193 | this.trigger('hide.uk.modal'); | ||
194 | }, | ||
195 | |||
196 | isActive: function() { | ||
197 | return this.element.hasClass('uk-open'); | ||
198 | } | ||
199 | |||
200 | }); | ||
201 | |||
202 | UI.component('modalTrigger', { | ||
203 | |||
204 | boot: function() { | ||
205 | |||
206 | // init code | ||
207 | UI.$html.on("click.modal.uikit", "[data-uk-modal]", function(e) { | ||
208 | |||
209 | var ele = UI.$(this); | ||
210 | |||
211 | if (ele.is("a")) { | ||
212 | e.preventDefault(); | ||
213 | } | ||
214 | |||
215 | if (!ele.data("modalTrigger")) { | ||
216 | var modal = UI.modalTrigger(ele, UI.Utils.options(ele.attr("data-uk-modal"))); | ||
217 | modal.show(); | ||
218 | } | ||
219 | |||
220 | }); | ||
221 | |||
222 | // close modal on esc button | ||
223 | UI.$html.on('keydown.modal.uikit', function (e) { | ||
224 | |||
225 | if (active && e.keyCode === 27 && active.options.keyboard) { // ESC | ||
226 | e.preventDefault(); | ||
227 | active.hide(); | ||
228 | } | ||
229 | }); | ||
230 | }, | ||
231 | |||
232 | init: function() { | ||
233 | |||
234 | var $this = this; | ||
235 | |||
236 | this.options = UI.$.extend({ | ||
237 | "target": $this.element.is("a") ? $this.element.attr("href") : false | ||
238 | }, this.options); | ||
239 | |||
240 | this.modal = UI.modal(this.options.target, this.options); | ||
241 | |||
242 | this.on("click", function(e) { | ||
243 | e.preventDefault(); | ||
244 | $this.show(); | ||
245 | }); | ||
246 | |||
247 | //methods | ||
248 | this.proxy(this.modal, "show hide isActive"); | ||
249 | } | ||
250 | }); | ||
251 | |||
252 | UI.modal.dialog = function(content, options) { | ||
253 | |||
254 | var modal = UI.modal(UI.$(UI.modal.dialog.template).appendTo("body"), options); | ||
255 | |||
256 | modal.on("hide.uk.modal", function(){ | ||
257 | if (modal.persist) { | ||
258 | modal.persist.appendTo(modal.persist.data("modalPersistParent")); | ||
259 | modal.persist = false; | ||
260 | } | ||
261 | modal.element.remove(); | ||
262 | }); | ||
263 | |||
264 | setContent(content, modal); | ||
265 | |||
266 | return modal; | ||
267 | }; | ||
268 | |||
269 | UI.modal.dialog.template = '<div class="uk-modal"><div class="uk-modal-dialog" style="min-height:0;"></div></div>'; | ||
270 | |||
271 | UI.modal.alert = function(content, options) { | ||
272 | |||
273 | options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options); | ||
274 | |||
275 | var modal = UI.modal.dialog(([ | ||
276 | '<div class="uk-margin uk-modal-content">'+String(content)+'</div>', | ||
277 | '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-button-primary uk-modal-close">'+options.labels.Ok+'</button></div>' | ||
278 | ]).join(""), options); | ||
279 | |||
280 | modal.on('show.uk.modal', function(){ | ||
281 | setTimeout(function(){ | ||
282 | modal.element.find('button:first').focus(); | ||
283 | }, 50); | ||
284 | }); | ||
285 | |||
286 | return modal.show(); | ||
287 | }; | ||
288 | |||
289 | UI.modal.confirm = function(content, onconfirm, oncancel) { | ||
290 | |||
291 | var options = arguments.length > 1 && arguments[arguments.length-1] ? arguments[arguments.length-1] : {}; | ||
292 | |||
293 | onconfirm = UI.$.isFunction(onconfirm) ? onconfirm : function(){}; | ||
294 | oncancel = UI.$.isFunction(oncancel) ? oncancel : function(){}; | ||
295 | options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, UI.$.isFunction(options) ? {}:options); | ||
296 | |||
297 | var modal = UI.modal.dialog(([ | ||
298 | '<div class="uk-margin uk-modal-content">'+String(content)+'</div>', | ||
299 | '<div class="uk-modal-footer uk-text-right"><button class="uk-button js-modal-confirm-cancel">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-confirm">'+options.labels.Ok+'</button></div>' | ||
300 | ]).join(""), options); | ||
301 | |||
302 | modal.element.find(".js-modal-confirm, .js-modal-confirm-cancel").on("click", function(){ | ||
303 | UI.$(this).is('.js-modal-confirm') ? onconfirm() : oncancel(); | ||
304 | modal.hide(); | ||
305 | }); | ||
306 | |||
307 | modal.on('show.uk.modal', function(){ | ||
308 | setTimeout(function(){ | ||
309 | modal.element.find('.js-modal-confirm').focus(); | ||
310 | }, 50); | ||
311 | }); | ||
312 | |||
313 | return modal.show(); | ||
314 | }; | ||
315 | |||
316 | UI.modal.prompt = function(text, value, onsubmit, options) { | ||
317 | |||
318 | onsubmit = UI.$.isFunction(onsubmit) ? onsubmit : function(value){}; | ||
319 | options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options); | ||
320 | |||
321 | var modal = UI.modal.dialog(([ | ||
322 | text ? '<div class="uk-modal-content uk-form">'+String(text)+'</div>':'', | ||
323 | '<div class="uk-margin-small-top uk-modal-content uk-form"><p><input type="text" class="uk-width-1-1"></p></div>', | ||
324 | '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-modal-close">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-ok">'+options.labels.Ok+'</button></div>' | ||
325 | ]).join(""), options), | ||
326 | |||
327 | input = modal.element.find("input[type='text']").val(value || '').on('keyup', function(e){ | ||
328 | if (e.keyCode == 13) { | ||
329 | modal.element.find(".js-modal-ok").trigger('click'); | ||
330 | } | ||
331 | }); | ||
332 | |||
333 | modal.element.find(".js-modal-ok").on("click", function(){ | ||
334 | if (onsubmit(input.val())!==false){ | ||
335 | modal.hide(); | ||
336 | } | ||
337 | }); | ||
338 | |||
339 | modal.on('show.uk.modal', function(){ | ||
340 | setTimeout(function(){ | ||
341 | input.focus(); | ||
342 | }, 50); | ||
343 | }); | ||
344 | |||
345 | return modal.show(); | ||
346 | }; | ||
347 | |||
348 | UI.modal.blockUI = function(content, options) { | ||
349 | |||
350 | var modal = UI.modal.dialog(([ | ||
351 | '<div class="uk-margin uk-modal-content">'+String(content || '<div class="uk-text-center">...</div>')+'</div>' | ||
352 | ]).join(""), UI.$.extend({bgclose:false, keyboard:false, modal:false}, options)); | ||
353 | |||
354 | modal.content = modal.element.find('.uk-modal-content:first'); | ||
355 | |||
356 | return modal.show(); | ||
357 | }; | ||
358 | |||
359 | |||
360 | UI.modal.labels = { | ||
361 | 'Ok': 'Ok', | ||
362 | 'Cancel': 'Cancel' | ||
363 | }; | ||
364 | |||
365 | |||
366 | // helper functions | ||
367 | function setContent(content, modal){ | ||
368 | |||
369 | if(!modal) return; | ||
370 | |||
371 | if (typeof content === 'object') { | ||
372 | |||
373 | // convert DOM object to a jQuery object | ||
374 | content = content instanceof jQuery ? content : UI.$(content); | ||
375 | |||
376 | if(content.parent().length) { | ||
377 | modal.persist = content; | ||
378 | modal.persist.data("modalPersistParent", content.parent()); | ||
379 | } | ||
380 | }else if (typeof content === 'string' || typeof content === 'number') { | ||
381 | // just insert the data as innerHTML | ||
382 | content = UI.$('<div></div>').html(content); | ||
383 | }else { | ||
384 | // unsupported data type! | ||
385 | content = UI.$('<div></div>').html('UIkit.modal Error: Unsupported data type: ' + typeof content); | ||
386 | } | ||
387 | |||
388 | content.appendTo(modal.element.find('.uk-modal-dialog')); | ||
389 | |||
390 | return modal; | ||
391 | } | ||
392 | |||
393 | })(UIkit); | ||