Fixed #2114 - Dropdown virtual scroll and lazy load dropdown with selected item
parent
7573966576
commit
65b617f6ae
|
@ -16,7 +16,7 @@
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
<Teleport :to="appendTarget" :disabled="appendDisabled">
|
<Teleport :to="appendTarget" :disabled="appendDisabled">
|
||||||
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
|
<transition name="p-connected-overlay" @enter="onOverlayEnter" @after-enter="onOverlayAfterEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
|
||||||
<div :ref="overlayRef" :class="panelStyleClass" v-if="overlayVisible" @click="onOverlayClick">
|
<div :ref="overlayRef" :class="panelStyleClass" v-if="overlayVisible" @click="onOverlayClick">
|
||||||
<slot name="header" :value="modelValue" :options="visibleOptions"></slot>
|
<slot name="header" :value="modelValue" :options="visibleOptions"></slot>
|
||||||
<div class="p-dropdown-header" v-if="filter">
|
<div class="p-dropdown-header" v-if="filter">
|
||||||
|
@ -437,21 +437,25 @@ export default {
|
||||||
onOverlayEnter(el) {
|
onOverlayEnter(el) {
|
||||||
ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
|
ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay);
|
||||||
this.alignOverlay();
|
this.alignOverlay();
|
||||||
this.bindOutsideClickListener();
|
|
||||||
this.bindScrollListener();
|
|
||||||
this.bindResizeListener();
|
|
||||||
this.scrollValueInView();
|
this.scrollValueInView();
|
||||||
|
|
||||||
if (this.filter) {
|
|
||||||
this.$refs.filterInput.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.virtualScrollerDisabled) {
|
if (!this.virtualScrollerDisabled) {
|
||||||
const selectedIndex = this.getSelectedOptionIndex();
|
const selectedIndex = this.getSelectedOptionIndex();
|
||||||
if (selectedIndex !== -1) {
|
if (selectedIndex !== -1) {
|
||||||
this.virtualScroller.scrollToIndex(selectedIndex);
|
setTimeout(() => {
|
||||||
|
this.virtualScroller && this.virtualScroller.scrollToIndex(selectedIndex)
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onOverlayAfterEnter() {
|
||||||
|
if (this.filter) {
|
||||||
|
this.$refs.filterInput.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.bindOutsideClickListener();
|
||||||
|
this.bindScrollListener();
|
||||||
|
this.bindResizeListener();
|
||||||
|
|
||||||
this.$emit('show');
|
this.$emit('show');
|
||||||
},
|
},
|
||||||
|
|
|
@ -148,23 +148,26 @@ export default {
|
||||||
scrollToIndex(index, behavior = 'auto') {
|
scrollToIndex(index, behavior = 'auto') {
|
||||||
const both = this.isBoth();
|
const both = this.isBoth();
|
||||||
const horizontal = this.isHorizontal();
|
const horizontal = this.isHorizontal();
|
||||||
|
const first = this.first;
|
||||||
|
const { numToleratedItems } = this.calculateNumItems();
|
||||||
|
const itemSize = this.itemSize;
|
||||||
const contentPos = this.getContentPosition();
|
const contentPos = this.getContentPosition();
|
||||||
const calculateFirst = (_index = 0, _numT) => (_index <= _numT ? 0 : _index);
|
const calculateFirst = (_index = 0, _numT) => (_index <= _numT ? 0 : _index);
|
||||||
const calculateCoord = (_first, _size, _cpos) => (_first * _size) + _cpos;
|
const calculateCoord = (_first, _size, _cpos) => (_first * _size) + _cpos;
|
||||||
const scrollTo = (left = 0, top = 0) => this.scrollTo({ left, top, behavior });
|
const scrollTo = (left = 0, top = 0) => this.scrollTo({ left, top, behavior });
|
||||||
|
|
||||||
if (both) {
|
if (both) {
|
||||||
const newFirst = { rows: calculateFirst(index[0], this.d_numToleratedItems[0]), cols: calculateFirst(index[1], this.d_numToleratedItems[1]) };
|
const newFirst = { rows: calculateFirst(index[0], numToleratedItems[0]), cols: calculateFirst(index[1], numToleratedItems[1]) };
|
||||||
if (newFirst.rows !== this.first.rows || newFirst.cols !== this.first.cols) {
|
if (newFirst.rows !== first.rows || newFirst.cols !== first.cols) {
|
||||||
scrollTo(calculateCoord(newFirst.cols, this.itemSize[1], contentPos.left), calculateCoord(newFirst.rows, this.itemSize[0], contentPos.top))
|
scrollTo(calculateCoord(newFirst.cols, itemSize[1], contentPos.left), calculateCoord(newFirst.rows, itemSize[0], contentPos.top))
|
||||||
this.first = newFirst;
|
this.first = newFirst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const newFirst = calculateFirst(index, this.d_numToleratedItems);
|
const newFirst = calculateFirst(index, numToleratedItems);
|
||||||
|
|
||||||
if (newFirst !== this.first) {
|
if (newFirst !== first) {
|
||||||
horizontal ? scrollTo(calculateCoord(newFirst, this.itemSize, contentPos.left), 0) : scrollTo(0, calculateCoord(newFirst, this.itemSize, contentPos.top));
|
horizontal ? scrollTo(calculateCoord(newFirst, itemSize, contentPos.left), 0) : scrollTo(0, calculateCoord(newFirst, itemSize, contentPos.top));
|
||||||
this.first = newFirst;
|
this.first = newFirst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,26 +250,33 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
calculateOptions() {
|
calculateNumItems() {
|
||||||
const both = this.isBoth();
|
const both = this.isBoth();
|
||||||
const horizontal = this.isHorizontal();
|
const horizontal = this.isHorizontal();
|
||||||
|
const itemSize = this.itemSize;
|
||||||
const contentPos = this.getContentPosition();
|
const contentPos = this.getContentPosition();
|
||||||
const contentWidth = this.element ? this.element.offsetWidth - contentPos.left : 0;
|
const contentWidth = this.element ? this.element.offsetWidth - contentPos.left : 0;
|
||||||
const contentHeight = this.element ? this.element.offsetHeight - contentPos.top : 0;
|
const contentHeight = this.element ? this.element.offsetHeight - contentPos.top : 0;
|
||||||
const calculateNumItemsInViewport = (_contentSize, _itemSize) => Math.ceil(_contentSize / (_itemSize || _contentSize));
|
const calculateNumItemsInViewport = (_contentSize, _itemSize) => Math.ceil(_contentSize / (_itemSize || _contentSize));
|
||||||
const calculateNumToleratedItems = (_numItems) => Math.ceil(_numItems / 2);
|
const calculateNumToleratedItems = (_numItems) => Math.ceil(_numItems / 2);
|
||||||
const numItemsInViewport = both ?
|
const numItemsInViewport = both ?
|
||||||
{ rows: calculateNumItemsInViewport(contentHeight, this.itemSize[0]), cols: calculateNumItemsInViewport(contentWidth, this.itemSize[1]) } :
|
{ rows: calculateNumItemsInViewport(contentHeight, itemSize[0]), cols: calculateNumItemsInViewport(contentWidth, itemSize[1]) } :
|
||||||
calculateNumItemsInViewport((horizontal ? contentWidth : contentHeight), this.itemSize);
|
calculateNumItemsInViewport((horizontal ? contentWidth : contentHeight), itemSize);
|
||||||
|
|
||||||
let numToleratedItems = this.d_numToleratedItems || (both ?
|
const numToleratedItems = this.d_numToleratedItems || (both ?
|
||||||
[calculateNumToleratedItems(numItemsInViewport.rows), calculateNumToleratedItems(numItemsInViewport.cols)] :
|
[calculateNumToleratedItems(numItemsInViewport.rows), calculateNumToleratedItems(numItemsInViewport.cols)] :
|
||||||
calculateNumToleratedItems(numItemsInViewport));
|
calculateNumToleratedItems(numItemsInViewport));
|
||||||
|
|
||||||
|
return { numItemsInViewport, numToleratedItems };
|
||||||
|
},
|
||||||
|
calculateOptions() {
|
||||||
|
const both = this.isBoth();
|
||||||
|
const first = this.first;
|
||||||
|
const { numItemsInViewport, numToleratedItems } = this.calculateNumItems();
|
||||||
const calculateLast = (_first, _num, _numT, _isCols) => this.getLast(_first + _num + ((_first < _numT ? 2 : 3) * _numT), _isCols);
|
const calculateLast = (_first, _num, _numT, _isCols) => this.getLast(_first + _num + ((_first < _numT ? 2 : 3) * _numT), _isCols);
|
||||||
const last = both ?
|
const last = both ?
|
||||||
{ rows: calculateLast(this.first.rows, numItemsInViewport.rows, numToleratedItems[0]), cols: calculateLast(this.first.cols, numItemsInViewport.cols, numToleratedItems[1], true) } :
|
{ rows: calculateLast(first.rows, numItemsInViewport.rows, numToleratedItems[0]), cols: calculateLast(first.cols, numItemsInViewport.cols, numToleratedItems[1], true) } :
|
||||||
calculateLast(this.first, numItemsInViewport, numToleratedItems);
|
calculateLast(first, numItemsInViewport, numToleratedItems);
|
||||||
|
|
||||||
this.last = last;
|
this.last = last;
|
||||||
this.numItemsInViewport = numItemsInViewport;
|
this.numItemsInViewport = numItemsInViewport;
|
||||||
|
@ -280,7 +290,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.lazy) {
|
if (this.lazy) {
|
||||||
this.$emit('lazy-load', { first: this.first, last });
|
this.$emit('lazy-load', { first, last });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getLast(last = 0, isCols) {
|
getLast(last = 0, isCols) {
|
||||||
|
|
Loading…
Reference in New Issue