Refactor dropdown click handling.

pull/12/head
cagataycivici 2018-12-30 21:50:33 +03:00
parent d26fb8196b
commit 38b174ff64
1 changed files with 24 additions and 27 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<div ref="container" :class="containerClass"> <div ref="container" :class="containerClass" @click="onClick">
<div class="p-hidden-accessible"> <div class="p-hidden-accessible">
<select aria-hidden="true" tabindex="-1"> <select aria-hidden="true" tabindex="-1">
<option v-for="option of visibleOptions" :key="getOptionLabel(option)" :value="getOptionValue(option)">{{getOptionLabel(option)}}</option> <option v-for="option of visibleOptions" :key="getOptionLabel(option)" :value="getOptionValue(option)">{{getOptionLabel(option)}}</option>
@ -9,12 +9,12 @@
<input ref="focusInput" type="text" role="listbox" readonly :disabled="disabled" @focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :tabindex="tabindex"/> <input ref="focusInput" type="text" role="listbox" readonly :disabled="disabled" @focus="onFocus" @blur="onBlur" @keydown="onKeyDown" :tabindex="tabindex"/>
</div> </div>
<input v-if="editable" type="text" class="p-dropdown-label p-inputtext" :disabled="disabled" @focus="onFocus" @blur="onBlur" :placeholder="placeholder" :value="editableInputValue" @input="onEditableInput"> <input v-if="editable" type="text" class="p-dropdown-label p-inputtext" :disabled="disabled" @focus="onFocus" @blur="onBlur" :placeholder="placeholder" :value="editableInputValue" @input="onEditableInput">
<label v-if="!editable" :class="labelClass" @click="onLabelClick">{{label}}</label> <label v-if="!editable" :class="labelClass">{{label}}</label>
<i v-if="showClear && value != null" class="p-dropdown-clear-icon pi pi-times" @click="clear"></i> <i v-if="showClear && value != null" class="p-dropdown-clear-icon pi pi-times" @click="onClearClick"></i>
<div class="p-dropdown-trigger" @click="onDropdownClick"> <div class="p-dropdown-trigger">
<span class="p-dropdown-trigger-icon pi pi-chevron-down p-clickable"></span> <span class="p-dropdown-trigger-icon pi pi-chevron-down p-clickable"></span>
</div> </div>
<transition name="p-input-overlay" @enter="onOverlayEnter"> <transition name="p-input-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave">
<div ref="overlay" class="p-dropdown-panel" v-if="overlayVisible"> <div ref="overlay" class="p-dropdown-panel" v-if="overlayVisible">
<div v-if="filter" class="p-dropdown-filter-container"> <div v-if="filter" class="p-dropdown-filter-container">
<input type="text" v-model="filterValue" autoComplete="off" class="p-dropdown-filter p-inputtext p-component" :placeholder="filterPlaceholder" @keydown="onFilterKeyDown" /> <input type="text" v-model="filterValue" autoComplete="off" class="p-dropdown-filter p-inputtext p-component" :placeholder="filterPlaceholder" @keydown="onFilterKeyDown" />
@ -150,14 +150,14 @@ export default {
case 13: case 13:
case 27: case 27:
if (this.overlayVisible) { if (this.overlayVisible) {
this.hideOverlay(); this.overlayVisible = false;
event.preventDefault(); event.preventDefault();
} }
break; break;
//tab //tab
case 9: case 9:
this.hideOverlay(); this.overlayVisible = false;
break; break;
default: default:
@ -180,7 +180,7 @@ export default {
//enter and escape //enter and escape
case 13: case 13:
case 27: case 27:
this.hideOverlay(); this.overlayVisible = false;
event.preventDefault(); event.preventDefault();
break; break;
@ -240,24 +240,25 @@ export default {
else else
return option; return option;
}, },
onLabelClick() { onClearClick() {
if (!this.overlayVisible) { this.updateModel(event, null);
this.overlayVisible = true;
}
this.$refs.focusInput.focus();
}, },
onDropdownClick() { onClick(event) {
if (!this.overlayVisible) { if (DomHandler.hasClass(event.target, 'p-dropdown-clear-icon')) {
this.overlayVisible = true; return;
}
else if (!this.$refs.overlay || !this.$refs.overlay.contains(event.target)) {
this.overlayVisible = !this.overlayVisible;
this.$refs.focusInput.focus();
} }
this.$refs.focusInput.focus();
}, },
onOptionSelect(event, option) { onOptionSelect(event, option) {
let value = this.getOptionValue(option); let value = this.getOptionValue(option);
this.updateModel(event, value); this.updateModel(event, value);
this.$refs.focusInput.focus();
setTimeout(() => { setTimeout(() => {
this.hideOverlay(); this.overlayVisible = false;
}, 100); }, 100);
}, },
onEditableInput(event) { onEditableInput(event) {
@ -267,12 +268,12 @@ export default {
this.alignOverlay(); this.alignOverlay();
this.bindOutsideClickListener(); this.bindOutsideClickListener();
}, },
onOverlayLeave() {
this.unbindOutsideClickListener();
},
alignOverlay() { alignOverlay() {
DomHandler.relativePosition(this.$refs.overlay, this.$refs.container); DomHandler.relativePosition(this.$refs.overlay, this.$refs.container);
}, },
clear(event) {
this.updateModel(event, null);
},
updateModel(event, value) { updateModel(event, value) {
this.$emit('input', value); this.$emit('input', value);
this.$emit('change', {originalEvent: event, value: value}); this.$emit('change', {originalEvent: event, value: value});
@ -280,8 +281,8 @@ export default {
bindOutsideClickListener() { bindOutsideClickListener() {
if (!this.outsideClickListener) { if (!this.outsideClickListener) {
this.outsideClickListener = (event) => { this.outsideClickListener = (event) => {
if (this.$refs.overlay && !this.$refs.overlay.contains(event.target)) { if (this.overlayVisible && this.$refs.overlay && !this.$refs.container.contains(event.target)) {
this.hideOverlay(); this.overlayVisible = false;
} }
}; };
document.addEventListener('click', this.outsideClickListener); document.addEventListener('click', this.outsideClickListener);
@ -293,10 +294,6 @@ export default {
this.outsideClickListener = null; this.outsideClickListener = null;
} }
}, },
hideOverlay() {
this.overlayVisible = false;
this.unbindOutsideClickListener();
},
search(event) { search(event) {
if (!this.visibleOptions) { if (!this.visibleOptions) {
return; return;