mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-03-07 05:03:26 +08:00
Fix issue when toggling repository items search fields [SCI-8874] (#5855)
* Fix issue when toggling repository items search fields [SCI-8874] * Refactor outside click directive and make it available for all components [SCI-8874]
This commit is contained in:
parent
556c1de182
commit
2680b317e5
3 changed files with 50 additions and 8 deletions
35
app/javascript/packs/vue/directives/outside_click.js
Normal file
35
app/javascript/packs/vue/directives/outside_click.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Use this to register outside-click directive on a Vue component
|
||||
// eslint-disable-next-line max-len
|
||||
// eg v-click-outside="{handler: 'handlerToTrigger', exclude: [refs to ignore on click (eg 'searchInput', 'searchInputBtn')]}"
|
||||
// eslint-enable-next-line max-len
|
||||
|
||||
let handleOutsideClick;
|
||||
|
||||
export default {
|
||||
bind(el, binding, vnode) {
|
||||
const { handler, exclude } = binding.value;
|
||||
|
||||
handleOutsideClick = (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
let clickedOnExcludedEl = false;
|
||||
exclude.forEach(refName => {
|
||||
if (!clickedOnExcludedEl) {
|
||||
const excludedEl = vnode.context.$refs[refName];
|
||||
clickedOnExcludedEl = excludedEl?.contains(e.target);
|
||||
}
|
||||
});
|
||||
|
||||
if (!el.contains(e.target) && !clickedOnExcludedEl) {
|
||||
vnode.context[handler]();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('click', handleOutsideClick);
|
||||
document.addEventListener('touchstart', handleOutsideClick);
|
||||
},
|
||||
unbind() {
|
||||
document.removeEventListener('click', handleOutsideClick);
|
||||
document.removeEventListener('touchstart', handleOutsideClick);
|
||||
}
|
||||
};
|
|
@ -1,9 +1,11 @@
|
|||
import TurbolinksAdapter from 'vue-turbolinks';
|
||||
import Vue from 'vue/dist/vue.esm';
|
||||
import RepositorySearchContainer from '../../vue/repository_search/container.vue';
|
||||
import outsideClick from './directives/outside_click';
|
||||
|
||||
Vue.use(TurbolinksAdapter);
|
||||
Vue.prototype.i18n = window.I18n;
|
||||
Vue.directive('click-outside', outsideClick);
|
||||
|
||||
window.initRepositorySearch = () => {
|
||||
window.RepositorySearchComponent = new Vue({
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<template>
|
||||
<div class="flex items-center mr-3 flex-nowrap">
|
||||
<button v-if="!searchOpened" class="btn btn-light btn-lg btn-black icon-btn" :title="i18n.t('repositories.show.search_button_tooltip')" @click="openSearch">
|
||||
<div
|
||||
class="flex items-center mr-3 flex-nowrap relative"
|
||||
v-click-outside="{handler: 'closeSearchInputs', exclude: ['searchInput', 'searchInputBtn', 'barcodeSearchInput', 'barcodeSearchInputBtn']}"
|
||||
>
|
||||
<button :class="{hidden: searchOpened}" ref='searchInputBtn' class="btn btn-light btn-lg btn-black icon-btn" :title="i18n.t('repositories.show.search_button_tooltip')" @click="openSearch">
|
||||
<i class="sn-icon sn-icon-search"></i>
|
||||
</button>
|
||||
<div v-if="searchOpened || barcodeSearchOpened" class="w-52 flex">
|
||||
|
@ -11,7 +14,6 @@
|
|||
type="text"
|
||||
:placeholder="i18n.t('repositories.show.filter_inventory_items')"
|
||||
@keyup="setValue"
|
||||
@blur="closeSearch"
|
||||
/>
|
||||
<i class="sn-icon sn-icon-search !mr-2.5"></i>
|
||||
</div>
|
||||
|
@ -21,13 +23,12 @@
|
|||
class="sci-input-field"
|
||||
type="text"
|
||||
:placeholder="i18n.t('repositories.show.filter_inventory_items_with_ean')"
|
||||
@change="setBarcodeValue"
|
||||
@blur="closeBarcodeSearch"
|
||||
@keyup="setBarcodeValue"
|
||||
/>
|
||||
<i class='sn-icon sn-icon-barcode barcode-scanner !mr-2.5'></i>
|
||||
</div>
|
||||
</div>
|
||||
<button v-if="!barcodeSearchOpened" class="btn btn-light btn-lg btn-black icon-btn ml-2" :title="i18n.t('repositories.show.ean_search_button_tooltip')" @click="openBarcodeSearch">
|
||||
<button :class="{hidden: barcodeSearchOpened}" ref='barcodeSearchInputBtn' class="btn btn-light btn-lg btn-black icon-btn ml-2" :title="i18n.t('repositories.show.ean_search_button_tooltip')" @click="openBarcodeSearch">
|
||||
<i class='sn-icon sn-icon-barcode barcode-scanner'></i>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -66,7 +67,7 @@ export default {
|
|||
},
|
||||
openBarcodeSearch() {
|
||||
this.clearValues();
|
||||
this.closeSearch();
|
||||
this.searchOpened = false;
|
||||
this.barcodeSearchOpened = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.barcodeSearchInput.focus();
|
||||
|
@ -74,7 +75,7 @@ export default {
|
|||
},
|
||||
openSearch() {
|
||||
this.clearValues();
|
||||
this.closeBarcodeSearch();
|
||||
this.barcodeSearchOpened = false;
|
||||
this.searchOpened = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs.searchInput.focus();
|
||||
|
@ -103,6 +104,10 @@ export default {
|
|||
this.barcodeValue = '';
|
||||
if (this.$refs.searchInput) this.$refs.searchInput.value = '';
|
||||
if (this.$refs.barcodeSearchInput) this.$refs.barcodeSearchInput.value = '';
|
||||
},
|
||||
closeSearchInputs() {
|
||||
this.closeSearch();
|
||||
this.closeBarcodeSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue