From 46e54a796763118e5d3b0184d5ee9e8117e15a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 7 Dec 2017 16:20:06 +0300 Subject: [PATCH] Added ResourceLoader and ModalManager. --- .../Pages/Identity/Users/EditModal.cshtml | 2 +- .../Pages/Identity/Users/Index.cshtml | 13 +- .../Volo.Abp.Identity.Web.csproj | 2 + .../modules/identity/helpers/ModalManager.js | 204 ++++++++++++++++++ .../identity/helpers/ResourceLoader.js | 87 ++++++++ .../modules/identity/views/users/index.js | 36 +--- 6 files changed, 306 insertions(+), 38 deletions(-) create mode 100644 src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ModalManager.js create mode 100644 src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ResourceLoader.js diff --git a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml index b0c0d09689..ca45284272 100644 --- a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml +++ b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/EditModal.cshtml @@ -67,5 +67,5 @@ \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml index 730d00e773..e8b587b78a 100644 --- a/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml +++ b/src/Volo.Abp.Identity.Web/Pages/Identity/Users/Index.cshtml @@ -4,14 +4,14 @@ @using Volo.Abp.Identity.Web.Areas.Identity.Localization.Resource @inject IHtmlLocalizer L @section styles { - } @section scripts { - + + } @@ -42,13 +42,4 @@ - - - - \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj b/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj index 5ed0b6c706..b54e531061 100644 --- a/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj +++ b/src/Volo.Abp.Identity.Web/Volo.Abp.Identity.Web.csproj @@ -22,6 +22,8 @@ + + diff --git a/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ModalManager.js b/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ModalManager.js new file mode 100644 index 0000000000..d9579cfdac --- /dev/null +++ b/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ModalManager.js @@ -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 $('
') + .append( + '' + ).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); \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ResourceLoader.js b/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ResourceLoader.js new file mode 100644 index 0000000000..3ec24d4ee9 --- /dev/null +++ b/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/helpers/ResourceLoader.js @@ -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); \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/views/users/index.js b/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/views/users/index.js index 063e8c94ec..fb2b2e5231 100644 --- a/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/views/users/index.js +++ b/src/Volo.Abp.Identity.Web/wwwroot/modules/identity/views/users/index.js @@ -3,6 +3,11 @@ var _identityUserAppService = volo.abp.identity.identityUser; + var _editModal = new abp.ModalManager({ + viewUrl: abp.appPath + 'Identity/Users/EditModal'//, + //scriptUrl: abp.appPath + 'view-resources/Areas/AppAreaName/Views/Users/_CreateOrEditModal.js' + }); + var _$wrapper = $('#IdentityUsersWrapper'); var _$table = _$wrapper.find('table'); @@ -45,12 +50,9 @@ //Update user command _$table.on('click', '.update-user', function () { - var id = $(this).data('id'); - - $('#createUpdateUserModal') - .modal('show') - .find('.modal-content') - .load(abp.appPath + 'Identity/Users/EditModal?id=' + id); + _editModal.open({ + id: $(this).data('id') + }); }); //Delete user command @@ -100,25 +102,7 @@ }); }); - $('#createUpdateUserModal').on('click', '#btnUpdateUserSave', function () { - var $updateUserForm = $('#updateUserForm'); - - //TODO: Use ajaxform instead! - - //$updateUserForm.ajaxForm(function () { - // $('#createUpdateUserModal').modal('hide'); - // _dataTable.ajax.reload(); - //}); - - //$updateUserForm.submit(); - - $.ajax({ - url: $updateUserForm.attr('action'), - method: "POST", - data: $updateUserForm.serialize() - }).then(function () { - $('#createUpdateUserModal').modal('hide'); - _dataTable.ajax.reload(); - }); + _editModal.onClose(function() { //TODO: Only refresh if saved! + _dataTable.ajax.reload(); }); }); \ No newline at end of file