mirror of https://github.com/abpframework/abp.git
6 changed files with 306 additions and 38 deletions
@ -0,0 +1,204 @@ |
|||
/** |
|||
* TODO: Document & prepare typescript definitions |
|||
*/ |
|||
var abp = abp || {}; |
|||
(function ($) { |
|||
|
|||
abp.modals = abp.modals || {}; |
|||
|
|||
abp.ModalManager = (function () { |
|||
|
|||
var _normalizeOptions = function (options) { |
|||
if (!options.modalId) { |
|||
options.modalId = 'Modal_' + (Math.floor((Math.random() * 1000000))) + new Date().getTime(); |
|||
} |
|||
} |
|||
|
|||
function _removeContainer(modalId) { |
|||
var _containerId = modalId + 'Container'; |
|||
var _containerSelector = '#' + _containerId; |
|||
|
|||
var $container = $(_containerSelector); |
|||
if ($container.length) { |
|||
$container.remove(); |
|||
} |
|||
}; |
|||
|
|||
function _createContainer(modalId) { |
|||
_removeContainer(modalId); |
|||
|
|||
var _containerId = modalId + 'Container'; |
|||
return $('<div id="' + _containerId + '"></div>') |
|||
.append( |
|||
'<div id="' + modalId + '" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">' + |
|||
' <div class="modal-dialog" role="document">' + |
|||
' <div class="modal-content"></div>' + |
|||
' </div>' + |
|||
'</div>' |
|||
).appendTo('body'); |
|||
} |
|||
|
|||
return function (options) { |
|||
|
|||
_normalizeOptions(options); |
|||
|
|||
var _options = options; |
|||
var _$modal = null; |
|||
var _$form = null; |
|||
var _modalId = options.modalId; |
|||
var _modalSelector = '#' + _modalId; |
|||
var _modalObject = null; |
|||
|
|||
var _publicApi = null; |
|||
var _args = null; |
|||
var _getResultCallback = null; |
|||
|
|||
var _onCloseCallbacks = []; |
|||
|
|||
function _saveModal() { |
|||
if (_modalObject && _modalObject.save) { |
|||
_modalObject.save(); |
|||
} else if (_$form) { |
|||
_$form.submit(); |
|||
} |
|||
} |
|||
|
|||
function _initAndShowModal() { |
|||
_$modal = $(_modalSelector); |
|||
|
|||
_$form = _$modal.find('form'); |
|||
if (!_$form.length) { |
|||
_$form = null; |
|||
} else if (_options.ajaxForm !== false) { //TODO: This option should be set by the modal or modal class!
|
|||
_$form.ajaxForm(function() { |
|||
_$modal.modal('hide'); |
|||
}); |
|||
} |
|||
|
|||
_$modal.modal({ |
|||
backdrop: 'static' |
|||
}); |
|||
|
|||
_$modal.on('hidden.bs.modal', function () { |
|||
_removeContainer(_modalId); |
|||
|
|||
for (var i = 0; i < _onCloseCallbacks.length; i++) { |
|||
_onCloseCallbacks[i](); |
|||
} |
|||
}); |
|||
|
|||
_$modal.on('shown.bs.modal', function () { |
|||
_$modal.find('input:not([type=hidden]):first').focus(); |
|||
}); |
|||
|
|||
var modalClass = abp.modals[options.modalClass]; |
|||
if (modalClass) { |
|||
_modalObject = new modalClass(); |
|||
if (_modalObject.init) { |
|||
_modalObject.init(_publicApi, _args); |
|||
} |
|||
} |
|||
|
|||
_$modal.find('button[type=submit]').click(function () { |
|||
_saveModal(); |
|||
}); |
|||
|
|||
_$modal.find('.modal-body').keydown(function (e) { |
|||
if (e.which === 13) { |
|||
if (e.target.tagName.toLocaleLowerCase() === "textarea") { |
|||
e.stopPropagation(); |
|||
} else { |
|||
e.preventDefault(); |
|||
_saveModal(); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
_$modal.modal('show'); |
|||
}; |
|||
|
|||
var _open = function (args, getResultCallback) { |
|||
|
|||
_args = args || {}; |
|||
_getResultCallback = getResultCallback; |
|||
|
|||
_createContainer(_modalId) |
|||
.find('.modal-content') |
|||
.load(options.viewUrl, $.param(_args), function (response, status, xhr) { |
|||
if (status == "error") { |
|||
//abp.message.warn(abp.localization.abpWeb('InternalServerError'));
|
|||
//TODO: ERROR!
|
|||
return; |
|||
}; |
|||
|
|||
if (options.scriptUrl) { |
|||
abp.ResourceLoader.loadScript(options.scriptUrl, function() { |
|||
_initAndShowModal(); |
|||
}); |
|||
} else { |
|||
_initAndShowModal(); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
var _close = function() { |
|||
if (!_$modal) { |
|||
return; |
|||
} |
|||
|
|||
_$modal.modal('hide'); |
|||
}; |
|||
|
|||
var _onClose = function (onCloseCallback) { |
|||
_onCloseCallbacks.push(onCloseCallback); |
|||
} |
|||
|
|||
function _setBusy(isBusy) { |
|||
if (!_$modal) { |
|||
return; |
|||
} |
|||
|
|||
_$modal.find('.modal-footer button').buttonBusy(isBusy); |
|||
} |
|||
|
|||
_publicApi = { |
|||
|
|||
open: _open, |
|||
|
|||
reopen: function() { |
|||
_open(_args); |
|||
}, |
|||
|
|||
close: _close, |
|||
|
|||
getModalId: function () { |
|||
return _modalId; |
|||
}, |
|||
|
|||
getModal: function () { |
|||
return _$modal; |
|||
}, |
|||
|
|||
getArgs: function () { |
|||
return _args; |
|||
}, |
|||
|
|||
getOptions: function() { |
|||
return _options; |
|||
}, |
|||
|
|||
setBusy: _setBusy, |
|||
|
|||
setResult: function() { |
|||
_getResultCallback && _getResultCallback.apply(_publicApi, arguments); |
|||
}, |
|||
|
|||
onClose: _onClose |
|||
} |
|||
|
|||
return _publicApi; |
|||
|
|||
}; |
|||
})(); |
|||
|
|||
})(jQuery); |
|||
@ -0,0 +1,87 @@ |
|||
/** |
|||
* abp.ResourceLoader can be used to load scripts when needed. |
|||
* It ensures that every script is only loaded once. |
|||
*/ |
|||
var abp = abp || {}; |
|||
(function ($) { |
|||
|
|||
/* UrlStates enum */ |
|||
var UrlStates = { |
|||
LOADING: 'LOADING', |
|||
LOADED: 'LOADED', |
|||
FAILED: 'FAILED' |
|||
}; |
|||
|
|||
/* UrlInfo class */ |
|||
function UrlInfo() { |
|||
this.state = UrlStates.LOADING; |
|||
this.loadCallbacks = []; |
|||
this.failCallbacks = []; |
|||
} |
|||
|
|||
UrlInfo.prototype.succeed = function () { |
|||
this.state = UrlStates.LOADED; |
|||
for (var i = 0; i < this.loadCallbacks.length; i++) { |
|||
this.loadCallbacks[i](); |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.failed = function () { |
|||
this.state = UrlStates.FAILED; |
|||
for (var i = 0; i < this.failCallbacks.length; i++) { |
|||
this.failCallbacks[i](); |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.handleCallbacks = function (loadCallback, failCallback) { |
|||
switch (this.state) { |
|||
case UrlStates.LOADED: |
|||
loadCallback && loadCallback(); |
|||
break; |
|||
case UrlStates.FAILED: |
|||
failCallback && failCallback(); |
|||
break; |
|||
case UrlStates.LOADING: |
|||
this.addCallbacks(loadCallback, failCallback); |
|||
break; |
|||
} |
|||
}; |
|||
|
|||
UrlInfo.prototype.addCallbacks = function (loadCallback, failCallback) { |
|||
loadCallback && this.loadCallbacks.push(loadCallback); |
|||
failCallback && this.failCallbacks.push(failCallback); |
|||
}; |
|||
|
|||
/* ResourceLoader API */ |
|||
|
|||
abp.ResourceLoader = (function () { |
|||
|
|||
var _urlInfos = {}; |
|||
|
|||
var _loadScript = function (url, loadCallback, failCallback) { |
|||
|
|||
var urlInfo = _urlInfos[url]; |
|||
|
|||
if (urlInfo) { |
|||
urlInfo.handleCallbacks(loadCallback, failCallback); |
|||
return; |
|||
} |
|||
|
|||
_urlInfos[url] = urlInfo = new UrlInfo(); |
|||
urlInfo.addCallbacks(loadCallback, failCallback); |
|||
|
|||
$.getScript(url) |
|||
.done(function (script, textStatus) { |
|||
urlInfo.succeed(); |
|||
}) |
|||
.fail(function (jqxhr, settings, exception) { |
|||
urlInfo.failed(); |
|||
}); |
|||
}; |
|||
|
|||
return { |
|||
loadScript: _loadScript |
|||
} |
|||
})(); |
|||
|
|||
})(jQuery); |
|||
Loading…
Reference in new issue