Существует следующая структура DOM: modalDiv (modal window) -> ui-grid -> ui-select
. В модальном окне есть сетка с ui-select
в столбце.
Проблема 1: ui-grid
имеет свой собственный overflow
для raw
. В связи с этим внутренние элементы обрезаются по высоте строки таблицы. Если я разверну select
, options
будут усечены до высоты raw
. Чтобы решить эту проблему, я добавляю директиву append-to-body
в ui-select, которая фиксирует элемент в body
. Но в связи с этим возникнет следующая проблема.
Проблема 2: поскольку grid
находится в модульном окне, а select
фиксируется в body
, то при прокрутке модального окна выбор будет прокручиваться вместе с модальным (как если бы он были исправлены).
Как решить эту проблему? Я попытался вставить родной <select>
вместо ui-select
, тогда проблема решается интересной техникой: свиток блокируется, пока он не перейдет в развернутое состояние. Но родной выбор не устраивает, потому что его стилизовать не удобно. Возможно, вы можете как-то решить проблему по-другому? Если нет, то как я могу заблокировать прокрутку (не удаляйте overflow: hidden
, потому что модал будет «дрожать»), пока выбор открыт, и повторно включите прокрутку, когда выбор закрыт?
Воспроизведена проблема в редакторе. Попробуйте открыть select
без модального режима, а затем прокрутите окно. Все хорошо. Теперь откройте модальное окно и повторите процедуру снова.
angular.module('myApp', ['ui.grid', 'ui.select', 'ui.bootstrap']);
angular
.module('myApp')
.controller('mainCtrl', ['$uibModal', function ($uibModal) {
const vm = this;
var myTemplate = '<ui-select-wrap>\n' +
' <ui-select class="my-dropdown" ng-model="MODEL_COL_FIELD"\n' +
' append-to-body="true">\n' +
' <ui-select-match>{{ COL_FIELD }}</ui-select-match>\n' +
' <ui-select-choices repeat="item in col.colDef.editDropdownOptionsArray | filter: $select.search">\n' +
' <span>{{ item }}</span>\n' +
' </ui-select-choices>\n' +
' </ui-select>\n' +
'</ui-select-wrap>';
vm.open = function () {
$uibModal.open({
template: '<h3>Now try to open Select and make a scroll :(</h3>' +
'<div ui-grid="$ctrl.gridOptions"></div>',
controller: 'mainCtrl',
controllerAs: '$ctrl',
resolve: {
gridOptions: function () {
return vm.gridOptions;
}
}
});
}
vm.gridOptions = {
columnDefs: [
{ name: 'status', width: '50%' },
{
name: 'name',
cellTemplate: myTemplate,
editDropdownOptionsArray: ['John', 'Bob', 'Alice']
}
],
data: [
{ status: 'New' },
{ status: 'New' }
],
rowHeight: 40
};
}]);
.my-dropdown {
z-index: 1100 !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.6.3/ui-grid.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.6.3/ui-grid.core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/4.6.3/ui-grid.edit.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.20.0/select.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-select/0.20.0/select.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<body ng-app="myApp">
<div ng-controller="mainCtrl as main">
<button ng-click="main.open()">OPEN MODAL</button>
<h3>Here, UI-Select works as it should. Open the select and try to scroll the window: the select is in place. Now open the modal window.</h3>
<div ui-grid="main.gridOptions"></div>
</div>
</body>