diff --git a/docs/en/UI/AspNetCore/Modals.md b/docs/en/UI/AspNetCore/Modals.md index 3824c45983..b0a0ba922e 100644 --- a/docs/en/UI/AspNetCore/Modals.md +++ b/docs/en/UI/AspNetCore/Modals.md @@ -9,7 +9,7 @@ While you can continue to use the standard [Bootstrap way](https://getbootstrap. ABP Framework provides the following benefits for such a modal with a form inside it; * **Lazy loads** the modal HTML into the page and **removes** it from the DOM once its closed. This makes easy to consume a reusable modal dialog. Also, every time you open the modal, it will be a fresh new modal, so you don't have to deal with resetting the modal content. -* **Auto-focuses** the first input of the form once the modal has been opened. +* **Auto-focuses** the first input of the form once the modal has been opened. You can also specify it using a `function` or `jquery selector`. * Automatically determines the **form** inside a modal and posts the form via **AJAX** instead of normal page post. * Automatically checks if the form inside the modal **has changed, but not saved**. It warns the user in this case. * Automatically **disables the modal buttons** (save & cancel) until the AJAX operation completes. @@ -429,6 +429,7 @@ Here, the list of all available options; * `viewUrl` (required, `string`): The URL to lazy load the HTML of the modal. * `scriptUrl` (optional, `string`): A URL to lazy load a JavaScript file. It is loaded only once, when the modal first opened. * `modalClass` (optional, `string`): A JavaScript class defined in the `abp.modals` namespace that can be used to execute code related to the modal. +* `focusElement` (optional, `function or string`): Specifies the element that gets focus. ### Functions diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/modal-manager.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/modal-manager.js index 75d080feda..e524881176 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/modal-manager.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/modal-manager.js @@ -96,21 +96,28 @@ $.validator.defaults.ignore = ''; //TODO: Would be better if we can apply only f }); _$modal.on('shown.bs.modal', function () { - //focuses first element if it's a typeable input. - var $firstVisibleInput = _$modal.find('input:not([type=hidden]):first'); + if (!options.focusElement) { + //focuses first element if it's a typeable input. + var $firstVisibleInput = _$modal.find('input:not([type=hidden]):first'); - _onOpenCallbacks.triggerAll(_publicApi); + _onOpenCallbacks.triggerAll(_publicApi); - if ($firstVisibleInput.hasClass("datepicker")) { - return; //don't pop-up date pickers... - } + if ($firstVisibleInput.hasClass("datepicker")) { + return; //don't pop-up date pickers... + } - var focusableInputs = ["text", "password", "email", "number", "search", "tel", "url"]; - if (!focusableInputs.includes($firstVisibleInput.prop("type"))) { - return; - } + var focusableInputs = ["text", "password", "email", "number", "search", "tel", "url"]; + if (!focusableInputs.includes($firstVisibleInput.prop("type"))) { + return; + } - $firstVisibleInput.focus(); + $firstVisibleInput.focus(); + } else if (typeof options.focusElement === 'function') { + var focusElement = options.focusElement(); + focusElement.focus(); + } else if (typeof options.focusElement === 'string') { + $(options.focusElement).focus(); + } }); var modalClass = abp.modals[options.modalClass];