Имеется следующая DOM-структура: modalDiv (модальное окно) -> ui-grid -> ui-select
. В модальном окне находится грид, в колонке которого располагается ui-select
.
Проблема 1: в ui-grid
стоит свой overflow
для строки. В связи с этим, внутренние элементы обрезаются высотой строки таблицы. Т.е. если я раскрываю select
, то options обрезаются высотой строки. Для решения этой проблемы я добавляю директиву append-to-body
в ui-select
, которая закрепляет элемент в body
. Но в этой связи позникает следующая проблема.
Проблема 2: поскольку грид находится в модальном окне, а селект закрепляется в body, то при скролле модального окна, селект располагается относительно body и скролится вместе с модалкой (как будто бы он fixed
).
Как можно решить эту проблему? Попробовал вместо ui-select
вставить нативный <select>
, то проблема решается интересным приемом: блокируется скролл до тех пора, пока select
находится в раскрытом состоянии. Но нативный селект не устраивает, т.к. его стилизовать не удобно. Возможно, можно как-то решить проблему по-другому? Если нет, то как можно блокировать скролл (не убирать overflow: hidden, т.к. будет модалка "дрожать") пока селект раскрыт и вновь включать скролл, когда селект закрыт?
Воспроизвел проблему в редакторе. Попробуйте без модалки открыть селект и поскроллить страницу, а затем откройте модалку и повторите действия. Проблема станет очевидной.
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>А теперь попробуйте тут открыть Select и поскролить :(</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()">ОТРЫТЬ МОДАЛКУ</button>
<h3>Здесь Select работает как нужно. Откройте селект и попробуйте проскролить окно: селект находится на месте. Теперь откройте модалку.</h3>
<div ui-grid="main.gridOptions"></div>
</div>
</body>
Можно попробовать написать свою директиву.
Потом манипулировать с селектом так, как надо.
пример:
angular.module('myApp', ['ui.grid', 'ui.select', 'ui.bootstrap']);
angular
.module('myApp')
.directive('uiSelectFix', function() {
return {
link: function(scope, element, attr) {
const cell = element.parent().parent();
// устанавливаем ширину селекта
function setWidth(width) {
const uiWrap = element.parent();
uiWrap.css({
maxWidth: width,
minWidth: width
});
};
// выносим select из ячейки, что бы overflow на него не работал
function init() {
const uiWrap = element.parent();
const row = uiWrap.parent().parent();
uiWrap.css({
position: 'absolute',
right: 0
});
row.append(uiWrap);
};
init();
// Нужно для изменения размера, при ресайзе окна или родительского элемента
scope.$watch(function() {
return getComputedStyle(cell[0]).maxWidth;
}, function(n, o) {
if (n === 0)
return;
setWidth(n);
})
}
};
})
.controller('mainCtrl', ['$uibModal', function($uibModal) {
const vm = this;
var myTemplate = '<ui-select-wrap>\n' +
' <ui-select ui-select-fix class="my-dropdown" ng-model="MODEL_COL_FIELD"\n' +
' >\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>А теперь попробуйте тут открыть Select и поскролить :(</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
};
}]);
<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()">ОТРЫТЬ МОДАЛКУ</button>
<h3>Здесь Select работает как нужно. Откройте селект и попробуйте проскролить окно: селект находится на месте. Теперь откройте модалку.</h3>
<div ui-grid="main.gridOptions"></div>
</div>
</body>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть на картинка на которую нужно наложить форму и выровнять по центру
имеется проблема с выпадающим менюВ частности с КОНТАКТАМИ, оно почему-то ездит при сжимании страницы, а должно быть зафиксированным как...
Вставил картинку, обновляю страницу - фонового изображения нет, почему? Что я не так сделал?
Есть первая страница, на ней два поля ввод и кнопка "Войти", как по нажатию кнопки перейти на другую страницу, и передать в её JavaScript, строки...