Files
jandl-taskmanager-app/app/src/plugins/tm@modal/_mixins/vuetify-fix-focus.ts
T

73 lines
2.0 KiB
TypeScript

export default {
// Mixin to fix autofocus on v-input in modals where date selects are used
data() {
return {
preventInputFocus: false,
savedScrollPosition: null,
};
},
methods: {
setFocusEvent() {
const inputs = document.querySelectorAll('.v-autocomplete input');
inputs.forEach((input) => {
input.addEventListener('focus', this.onInputFocus);
});
},
onDateFocus($event) {
if ($event == undefined) {
this.preventInputFocus = true;
}
},
onDateOpen($event) {
// $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) {
const target = $event.target;
// 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') {
const scrollBefore = document.querySelector(
'.v-dialog .modal-content',
)?.scrollTop;
// Blur the focused element
setTimeout(() => {
target.blur();
const modalContent = document.querySelector(
'.v-dialog .modal-content',
);
if (modalContent && this.savedScrollPosition !== null) {
modalContent.scrollTop = this.savedScrollPosition;
const scrollAfter = modalContent.scrollTop;
}
}, 0);
}
}
},
},
};