diff --git a/dev/components/form/all.vue b/dev/components/form/all.vue index ff8d5f369c4..d98109cee64 100644 --- a/dev/components/form/all.vue +++ b/dev/components/form/all.vue @@ -217,6 +217,13 @@ + + + + + + +

Selected option: {{ JSON.stringify(option) }}

diff --git a/src/components/autocomplete/QAutocomplete.js b/src/components/autocomplete/QAutocomplete.js index 7a9994d683f..fa8d75cea70 100644 --- a/src/components/autocomplete/QAutocomplete.js +++ b/src/components/autocomplete/QAutocomplete.js @@ -219,8 +219,14 @@ export default { anchorClick: false }, on: { - show: () => this.$emit('show'), - hide: () => this.$emit('hide') + show: () => { + this.__input.selectionOpen = true + this.$emit('show') + }, + hide: () => { + this.__input.selectionOpen = false + this.$emit('hide') + } } }, [ h(QList, { diff --git a/src/components/chips-input/QChipsInput.vue b/src/components/chips-input/QChipsInput.vue index e9de3dfcd5f..a4a9f260252 100644 --- a/src/components/chips-input/QChipsInput.vue +++ b/src/components/chips-input/QChipsInput.vue @@ -60,8 +60,15 @@ /> + + + + @@ -79,13 +88,15 @@ import InputMixin from '../../mixins/input' import { QInputFrame } from '../input-frame' import { QChip } from '../chip' import { getEventKey, stopAndPrevent } from '../../utils/event' +import { QSpinner } from '../spinner' export default { name: 'QChipsInput', mixins: [FrameMixin, InputMixin], components: { QInputFrame, - QChip + QChip, + QSpinner }, props: { value: { @@ -100,12 +111,36 @@ export default { data () { return { input: '', - model: this.value + model: this.value, + watcher: null, + shadow: { + val: this.input, + set: this.add, + loading: false, + selectionOpen: false, + watched: 0, + isDark: () => this.dark, + hasFocus: () => document.activeElement === this.$refs.input, + register: () => { + this.shadow.watched += 1 + this.__watcherRegister() + }, + unregister: () => { + this.shadow.watched = Math.max(0, this.shadow.watched - 1) + this.__watcherUnregister() + }, + getEl: () => this.$refs.input + } } }, watch: { value (v) { - this.model = this.value + this.model = v + } + }, + provide () { + return { + __input: this.shadow } }, computed: { @@ -114,6 +149,9 @@ export default { ? this.model.length : 0 }, + isLoading () { + return this.loading || (this.shadow.watched && this.shadow.loading) + }, computedAddIcon () { return this.addIcon || this.$q.icon.chipsInput.add }, @@ -151,7 +189,7 @@ export default { clearTimeout(this.timer) this.focus() - if (!this.editable || !value) { + if (this.isLoading || !this.editable || !value) { return } if (this.model.includes(value)) { @@ -177,6 +215,9 @@ export default { __handleKeyDown (e) { switch (getEventKey(e)) { case 13: // ENTER key + if (this.shadow.selectionOpen) { + return + } stopAndPrevent(e) return this.add() case 8: // Backspace key @@ -190,7 +231,30 @@ export default { }, __onClick () { this.focus() + }, + __watcher (value) { + if (this.shadow.watched) { + this.shadow.val = value + } + }, + __watcherRegister () { + if (!this.watcher) { + this.watcher = this.$watch('input', this.__watcher) + } + }, + __watcherUnregister (forceUnregister) { + if ( + this.watcher && + (forceUnregister || !this.shadow.watched) + ) { + this.watcher() + this.watcher = null + this.shadow.selectionOpen = false + } } + }, + beforeDestroy () { + this.__watcherUnregister(true) } } diff --git a/src/components/input/QInput.vue b/src/components/input/QInput.vue index 78f4d6f4a4b..662627f339c 100644 --- a/src/components/input/QInput.vue +++ b/src/components/input/QInput.vue @@ -213,7 +213,7 @@ export default { return this.type === 'textarea' }, isLoading () { - return this.loading || this.shadow.loading + return this.loading || (this.shadow.watched && this.shadow.loading) }, keyboardToggle () { return this.$q.platform.is.mobile &&