mirror of
https://bitbucket.org/studiotem/jandl-taskmanager-app.git
synced 2026-10-21 14:29:34 +00:00
fix(datepicker): improve focus handling and scroll position restoration in modal
This commit is contained in:
1 parent
056b27b016
commit
61fc55d313
3 files changed
+77
-22
No files matched your search
@@ -3,6 +3,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
preventInputFocus: false,
|
||||
savedScrollPosition: null,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -20,18 +21,44 @@ export default {
|
||||
},
|
||||
|
||||
onDateOpen($event) {
|
||||
if ($event == undefined) {
|
||||
// $event should be the element reference (or any truthy value to trigger saving)
|
||||
if ($event) {
|
||||
// Find the scrollable modal container
|
||||
const modalContent = document.querySelector('.v-dialog .modal-content');
|
||||
if (modalContent) {
|
||||
this.savedScrollPosition = modalContent.scrollTop;
|
||||
}
|
||||
|
||||
this.preventInputFocus = true;
|
||||
|
||||
// Reset after datepicker is opened
|
||||
setTimeout(() => {
|
||||
this.preventInputFocus = false;
|
||||
this.savedScrollPosition = null;
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
|
||||
onInputFocus($event) {
|
||||
setTimeout(() => {
|
||||
if (this.preventInputFocus) {
|
||||
$event.target.blur();
|
||||
this.preventInputFocus = false;
|
||||
// If we have a saved scroll position and an unwanted focus happened
|
||||
if (this.preventInputFocus && this.savedScrollPosition !== null) {
|
||||
const target = $event.target;
|
||||
|
||||
// Only intercept text input focus (autocomplete fields)
|
||||
if (target.tagName === 'INPUT' && target.type === 'text') {
|
||||
// Blur the focused element
|
||||
setTimeout(() => {
|
||||
target.blur();
|
||||
|
||||
const modalContent = document.querySelector(
|
||||
'.v-dialog .modal-content',
|
||||
);
|
||||
if (modalContent && this.savedScrollPosition !== null) {
|
||||
modalContent.scrollTop = this.savedScrollPosition;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -57,20 +57,26 @@
|
||||
|
||||
<div class="splitted-inputs">
|
||||
<!-- TODO: Bialko validacie -->
|
||||
<Datepicker
|
||||
v-model="mastertask.deadline"
|
||||
:auto-apply="true"
|
||||
@focus="onDateFocus"
|
||||
:min-date="new Date()"
|
||||
class="modal-input left"
|
||||
format="dd.MM.yyyy"
|
||||
locale="sk"
|
||||
select-text="Vybrať"
|
||||
cancel-text="Zrušiť"
|
||||
placeholder="Dátum"
|
||||
:class="{ error: v$.mastertask.deadline.$errors?.length }"
|
||||
:validations="v$.mastertask.deadline"
|
||||
/>
|
||||
<div
|
||||
@click="handleDatepickerClick"
|
||||
class="datepicker-wrapper left"
|
||||
ref="datepicker-wrapper"
|
||||
>
|
||||
<Datepicker
|
||||
v-model="mastertask.deadline"
|
||||
ref="datepicker"
|
||||
:auto-apply="true"
|
||||
:min-date="new Date()"
|
||||
class="modal-input datepicker-input"
|
||||
format="dd.MM.yyyy"
|
||||
locale="sk"
|
||||
select-text="Vybrať"
|
||||
cancel-text="Zrušiť"
|
||||
placeholder="Dátum"
|
||||
:class="{ error: v$.mastertask.deadline.$errors?.length }"
|
||||
:validations="v$.mastertask.deadline"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<v-text-field
|
||||
class="modal-input right"
|
||||
@@ -454,6 +460,14 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleDatepickerClick() {
|
||||
// Pass the datepicker wrapper element reference to the mixin
|
||||
const scrollTarget = this.$refs['datepicker-wrapper'];
|
||||
this.onDateOpen(scrollTarget);
|
||||
// Open the datepicker
|
||||
this.$refs['datepicker'].openMenu();
|
||||
},
|
||||
|
||||
closeBothModals() {
|
||||
this.$emit('close');
|
||||
this.visible = false;
|
||||
@@ -770,4 +784,11 @@ export default {
|
||||
|
||||
:deep(.v-field__clearable)
|
||||
opacity: 1 !important
|
||||
|
||||
.datepicker-wrapper
|
||||
width: 100%
|
||||
.datepicker-input
|
||||
width: 100% !important
|
||||
height: 100%
|
||||
pointer-events: none
|
||||
</style>
|
||||
@@ -4,14 +4,13 @@
|
||||
<button @click="$emit('removeTimeblock')" class="x-button">x</button>
|
||||
</div>
|
||||
<div
|
||||
@click="openDatepicker('datepicker')"
|
||||
@click="handleDatepickerClick"
|
||||
class="datepicker-wrapper"
|
||||
ref="datepicker-wrapper"
|
||||
>
|
||||
<Datepicker
|
||||
:model-value="timeblock.date"
|
||||
ref="datepicker"
|
||||
@open="onDateOpen"
|
||||
@update:model-value="updateDate"
|
||||
format="dd.MM.yyyy"
|
||||
locale="sk"
|
||||
@@ -104,6 +103,14 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleDatepickerClick() {
|
||||
// Pass the datepicker wrapper element reference to the mixin
|
||||
const scrollTarget = this.$refs['datepicker-wrapper'];
|
||||
this.onDateOpen(scrollTarget);
|
||||
// Open the datepicker
|
||||
this.openDatepicker('datepicker');
|
||||
},
|
||||
|
||||
async openDatepicker(ref) {
|
||||
this.$refs[ref].openMenu();
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user