src/pyams_skin/resources/js/myams-dialog.js
changeset 433 f8b091800256
child 461 6efc2fc367c1
equal deleted inserted replaced
432:ab61cf51390a 433:f8b091800256
       
     1 /**
       
     2  * MyAMS modal dialogs management
       
     3  */
       
     4 (function($, globals) {
       
     5 
       
     6 	var MyAMS = globals.MyAMS,
       
     7 		ams = MyAMS;
       
     8 
       
     9 	MyAMS.dialog = {
       
    10 
       
    11 		/**
       
    12 		 * List of registered 'shown' callbacks
       
    13 		 */
       
    14 		_shown_callbacks: [],
       
    15 
       
    16 		/**
       
    17 		 * Register a callback which should be called when a dialog is shown
       
    18 		 */
       
    19 		registerShownCallback: function(callback, element) {
       
    20 			var dialog;
       
    21 			if (element) {
       
    22 				dialog = element.objectOrParentWithClass('modal-dialog');
       
    23 			}
       
    24 
       
    25 			var callbacks;
       
    26 			if (dialog && dialog.exists()) {
       
    27 				callbacks = dialog.data('shown-callbacks');
       
    28 				if (callbacks === undefined) {
       
    29 					callbacks = [];
       
    30 					dialog.data('shown-callbacks', callbacks);
       
    31 				}
       
    32 			} else {
       
    33 				callbacks = ams.dialog._shown_callbacks;
       
    34 			}
       
    35 			if (callbacks.indexOf(callback) < 0) {
       
    36 				callbacks.push(callback);
       
    37 			}
       
    38 		},
       
    39 
       
    40 		/**
       
    41 		 * List of registered 'hide' callbacks
       
    42 		 */
       
    43 		_hide_callbacks: [],
       
    44 
       
    45 		/**
       
    46 		 * Register a callback which should be called when a dialog is closed
       
    47 		 */
       
    48 		registerHideCallback: function(callback, element) {
       
    49 			var dialog;
       
    50 			if (element) {
       
    51 				dialog = element.objectOrParentWithClass('modal-dialog');
       
    52 			}
       
    53 
       
    54 			var callbacks;
       
    55 			if (dialog && dialog.exists()) {
       
    56 				callbacks = dialog.data('hide-callbacks');
       
    57 				if (callbacks === undefined) {
       
    58 					callbacks = [];
       
    59 					dialog.data('hide-callbacks', callbacks);
       
    60 				}
       
    61 			} else {
       
    62 				callbacks = ams.dialog._hide_callbacks;
       
    63 			}
       
    64 			if (callbacks.indexOf(callback) < 0) {
       
    65 				callbacks.push(callback);
       
    66 			}
       
    67 		},
       
    68 
       
    69 		/**
       
    70 		 * Modal dialog opener
       
    71 		 */
       
    72 		open: function(source, options, callbacks) {
       
    73 			ams.ajax.check($.fn.modalmanager,
       
    74 						   ams.baseURL + 'ext/bootstrap-modalmanager' + ams.devext + '.js',
       
    75 						   function() {
       
    76 								ams.ajax.check($.fn.modal.defaults,
       
    77 											   ams.baseURL + 'ext/bootstrap-modal' + ams.devext + '.js',
       
    78 								function(first_load) {
       
    79 									if (first_load) {
       
    80 										$(document).off('click.modal');
       
    81 										$.fn.modal.defaults.spinner = $.fn.modalmanager.defaults.spinner =
       
    82 											'<div class="loading-spinner" style="width: 200px; margin-left: -100px;">' +
       
    83 												'<div class="progress progress-striped active">' +
       
    84 													'<div class="progress-bar" style="width: 100%;"></div>' +
       
    85 												'</div>' +
       
    86 											'</div>';
       
    87 									}
       
    88 
       
    89 									var sourceData;
       
    90 									var url;
       
    91 									if (typeof(source) === 'string') {
       
    92 										sourceData = {};
       
    93 										url = source;
       
    94 									} else {
       
    95 										sourceData = source.data();
       
    96 										url = source.attr('href') || sourceData.amsUrl;
       
    97 										var url_getter = ams.getFunctionByName(url);
       
    98 										if (typeof(url_getter) === 'function') {
       
    99 											url = url_getter.call(source);
       
   100 										}
       
   101 									}
       
   102 									if (!url) {
       
   103 										return;
       
   104 									}
       
   105 									$('body').modalmanager('loading');
       
   106 									if (url.indexOf('#') === 0) {
       
   107 										// Inner hidden modal dialog
       
   108 										$(url).modal('show');
       
   109 									} else {
       
   110 										// Remote URL modal dialog
       
   111 										$.ajax({
       
   112 											url: url,
       
   113 											type: 'get',
       
   114 											cache: sourceData.amsAllowCache === undefined ? false : sourceData.amsAllowCache,
       
   115 											data: options,
       
   116 											success: function(data, status, request) {
       
   117 												$('body').modalmanager('removeLoading');
       
   118 												var response = ams.ajax.getResponse(request);
       
   119 												var dataType = response.contentType;
       
   120 												var result = response.data;
       
   121 												switch (dataType) {
       
   122 													case 'json':
       
   123 														ams.ajax.handleJSON(result, $($(source).data('ams-json-target') || '#content'));
       
   124 														break;
       
   125 													case 'script':
       
   126 														break;
       
   127 													case 'xml':
       
   128 														break;
       
   129 													case 'html':
       
   130 														/* falls through */
       
   131 													case 'text':
       
   132 														/* falls through */
       
   133 													default:
       
   134 														var content = $(result);
       
   135 														var dialog = $('.modal-dialog', content.wrap('<div></div>').parent());
       
   136 														var dialogData = dialog.data();
       
   137 														var dataOptions = {
       
   138 															backdrop: 'static',
       
   139 															overflow: dialogData.amsModalOverflow || '.modal-viewport',
       
   140 															maxHeight: dialogData.amsModalMaxHeight === undefined ?
       
   141 																	function() {
       
   142 																		return $(window).height() -
       
   143 																					$('.modal-header', content).outerHeight(true) -
       
   144 																					$('footer', content).outerHeight(true) - 85;
       
   145 																	}
       
   146 																	: ams.getFunctionByName(dialogData.amsModalMaxHeight)
       
   147 														};
       
   148 														var settings = $.extend({}, dataOptions, dialogData.amsModalOptions);
       
   149 														settings = ams.executeFunctionByName(dialogData.amsModalInitCallback, dialog, settings) || settings;
       
   150 														if (callbacks) {
       
   151 															if (callbacks.shown) {
       
   152 																ams.dialog.registerShownCallback(callbacks.shown, content);
       
   153 															}
       
   154 															if (callbacks.hide) {
       
   155 																ams.dialog.registerHideCallback(callbacks.hide, content);
       
   156 															}
       
   157 														}
       
   158 														$('<div>').addClass('modal fade')
       
   159 																  .append(content)
       
   160 																  .modal(settings)
       
   161 																  .on('shown', ams.dialog.shown)
       
   162 																  .on('hidden', ams.dialog.hidden);
       
   163 														ams.initContent(content);
       
   164 														if (sourceData.amsLogEvent !== false) {
       
   165 															ams.stats.logPageview(url);
       
   166 														}
       
   167 												}
       
   168 											}
       
   169 										});
       
   170 									}
       
   171 								});
       
   172 						   });
       
   173 		},
       
   174 
       
   175 		/**
       
   176 		 * Modals shown callback
       
   177 		 * This callback is used to initialize modal's viewport size
       
   178 		 */
       
   179 		shown: function(e) {
       
   180 
       
   181 			function resetViewport(ev) {
       
   182 				var top = $('.scrollmarker.top', viewport);
       
   183 				var topPosition = viewport.scrollTop();
       
   184 				if (topPosition > 0) {
       
   185 					top.show();
       
   186 				} else {
       
   187 					top.hide();
       
   188 				}
       
   189 				var bottom = $('.scrollmarker.bottom', viewport);
       
   190 				if (maxHeight + topPosition >= viewport.get(0).scrollHeight) {
       
   191 					bottom.hide();
       
   192 				} else {
       
   193 					bottom.show();
       
   194 				}
       
   195 			}
       
   196 
       
   197 			var modal = e.target;
       
   198 			var viewport = $('.modal-viewport', modal);
       
   199 			if (viewport.exists()) {
       
   200 				var maxHeight = parseInt(viewport.css('max-height'));
       
   201 				var barWidth = $.scrollbarWidth();
       
   202 				if ((viewport.css('overflow') !== 'hidden') &&
       
   203 					(viewport.height() === maxHeight)) {
       
   204 					$('<div></div>').addClass('scrollmarker')
       
   205 						.addClass('top')
       
   206 						.css('top', 0)
       
   207 						.css('width', viewport.width() - barWidth)
       
   208 						.hide()
       
   209 						.appendTo(viewport);
       
   210 					$('<div></div>').addClass('scrollmarker')
       
   211 						.addClass('bottom')
       
   212 						.css('top', maxHeight - 20)
       
   213 						.css('width', viewport.width() - barWidth)
       
   214 						.appendTo(viewport);
       
   215 					viewport.scroll(resetViewport);
       
   216 					viewport.off('resize')
       
   217 						.on('resize', resetViewport);
       
   218 				} else {
       
   219 					$('.scrollmarker', viewport).remove();
       
   220 				}
       
   221 			}
       
   222 
       
   223 			// Check for shown callbacks defined via data API
       
   224 			$('[data-ams-shown-callback]', modal).each(function() {
       
   225 				var callback = ams.getFunctionByName($(this).data('ams-shown-callback'));
       
   226 				if (callback) {
       
   227 					callback.call(modal, this);
       
   228 				}
       
   229 			});
       
   230 			// Call shown callbacks registered for this dialog
       
   231 			var index;
       
   232 			var callbacks = $('.modal-dialog', modal).data('shown-callbacks');
       
   233 			if (callbacks) {
       
   234 				for (index=0; index < callbacks.length; index++) {
       
   235 					callbacks[index].call(modal);
       
   236 				}
       
   237 			}
       
   238 			// Call globally registered shown callbacks
       
   239 			callbacks = ams.dialog._shown_callbacks;
       
   240 			if (callbacks) {
       
   241 				for (index=0; index < callbacks.length; index++) {
       
   242 					callbacks[index].call(modal);
       
   243 				}
       
   244 			}
       
   245 
       
   246 			ams.form.setFocus(modal);
       
   247 		},
       
   248 
       
   249 		/**
       
   250 		 * Close modal dialog associated with given context
       
   251 		 */
       
   252 		close: function(context) {
       
   253 			if (typeof(context) === 'string') {
       
   254 				context = $(context);
       
   255 			}
       
   256 			var modal = context.parents('.modal').data('modal');
       
   257 			if (modal) {
       
   258 				var manager = $('body').data('modalmanager');
       
   259 				if (manager && (manager.getOpenModals().indexOf(modal) >= 0)) {
       
   260 					modal.hide();
       
   261 				}
       
   262 			}
       
   263 		},
       
   264 
       
   265 		/**
       
   266 		 * Modals hidden callback
       
   267 		 * This callback can be used to clean contents added by plug-ins
       
   268 		 */
       
   269 		hidden: function(e) {
       
   270 			var modal = e.target;
       
   271 			// Call registered cleaning callbacks
       
   272 			ams.skin.cleanContainer(modal);
       
   273 			// Check for hidden callbacks defined via data API
       
   274 			$('[data-ams-hidden-callback]', modal).each(function() {
       
   275 				var callback = ams.getFunctionByName($(this).data('ams-hidden-callback'));
       
   276 				if (callback) {
       
   277 					callback.call(modal, this);
       
   278 				}
       
   279 			});
       
   280 			// Call hidden callbacks registered for this dialog
       
   281 			var index;
       
   282 			var callbacks = $('.modal-dialog', modal).data('hide-callbacks');
       
   283 			if (callbacks) {
       
   284 				for (index=0; index < callbacks.length; index++) {
       
   285 					callbacks[index].call(modal);
       
   286 				}
       
   287 			}
       
   288 			// Call globally registered hidden callbacks
       
   289 			callbacks = ams.dialog._hide_callbacks;
       
   290 			if (callbacks) {
       
   291 				for (index=0; index < callbacks.length; index++) {
       
   292 					callbacks[index].call(modal);
       
   293 				}
       
   294 			}
       
   295 		}
       
   296 	};
       
   297 
       
   298 })(jQuery, this);