Skip to content

Commit

Permalink
fix default value for options object (vuejs/vue#1032)
Browse files Browse the repository at this point in the history
  • Loading branch information
sackmannb committed Apr 11, 2019
1 parent ec4609c commit 907cdaf
Showing 1 changed file with 178 additions and 169 deletions.
347 changes: 178 additions & 169 deletions src/Suggestions.vue
Original file line number Diff line number Diff line change
@@ -1,199 +1,208 @@
<template>
<div class="v-suggestions">
<input type="text" :class="extendedOptions.inputClass"
v-bind="$attrs"
v-on:keydown="onKeyDown"
v-on:blur="hideItems"
v-on:focus="showItems = true"
v-model="query"
:autocomplete="Math.random()"
:placeholder="extendedOptions.placeholder">
<input
type="text"
:class="extendedOptions.inputClass"
v-bind="$attrs"
v-on:keydown="onKeyDown"
v-on:blur="hideItems"
v-on:focus="showItems = true"
v-model="query"
:autocomplete="Math.random()"
:placeholder="extendedOptions.placeholder"
>
<div class="suggestions">
<ul class="items" v-show="items.length > 0 && showItems === true">
<li class="item"
:key="index"
v-for="(item, index) in items"
@click.prevent="selectItem(index)"
v-bind:class="{ 'is-active': index === activeItemIndex }">
<slot name="item"
:item="item">
{{item}}
</slot>
<li
class="item"
:key="index"
v-for="(item, index) in items"
@click.prevent="selectItem(index)"
v-bind:class="{ 'is-active': index === activeItemIndex }"
>
<slot name="item" :item="item">{{item}}</slot>
</li>
</ul>
</div>
</div>
</template>
<script>
import debounce from 'debounce'
import './Suggestions.css'
import debounce from "debounce";
import "./Suggestions.css";
export default {
inheritAttributes: true,
props: {
options: {
type: Object,
default: {}
},
onInputChange: {
type: Function,
required: true
},
onItemSelected: {
type: Function
},
value: {
type: String,
required: true
}
export default {
inheritAttributes: true,
props: {
options: {
type: Object,
default: () => {}
},
onInputChange: {
type: Function,
required: true
},
data () {
const defaultOptions = {
debounce: 0,
placeholder: '',
inputClass: 'input'
onItemSelected: {
type: Function
},
value: {
type: String,
required: true
}
},
data() {
const defaultOptions = {
debounce: 0,
placeholder: "",
inputClass: "input"
};
const extendedOptions = Object.assign({}, defaultOptions, this.options);
return {
extendedOptions,
query: this.value,
lastSetQuery: null,
items: [],
activeItemIndex: -1,
showItems: false
};
},
beforeMount() {
if (this.extendedOptions.debounce !== 0) {
this.onQueryChanged = debounce(
this.onQueryChanged,
this.extendedOptions.debounce
);
}
},
watch: {
query: function(newValue, oldValue) {
if (newValue === this.lastSetQuery) {
this.lastSetQuery = null;
return;
}
const extendedOptions = Object.assign({}, defaultOptions, this.options)
return {
extendedOptions,
query: this.value,
lastSetQuery: null,
items: [],
activeItemIndex: -1,
showItems: false
this.onQueryChanged(newValue);
this.$emit("input", newValue);
},
value: function(newValue, oldValue) {
this.setInputQuery(newValue);
}
},
methods: {
onItemSelectedDefault(item) {
if (typeof item === "string") {
this.$emit("input", item);
this.setInputQuery(item);
this.showItems = false;
// console.log('change value')
}
},
beforeMount () {
if (this.extendedOptions.debounce !== 0) {
this.onQueryChanged = debounce(this.onQueryChanged, this.extendedOptions.debounce)
hideItems() {
setTimeout(() => {
this.showItems = false;
}, 300);
},
showResults() {
this.showItems = true;
},
setInputQuery(value) {
this.lastSetQuery = value;
this.query = value;
},
onKeyDown(e) {
this.$emit("keyDown", e.keyCode);
switch (e.keyCode) {
case 40:
this.highlightItem("down");
e.preventDefault();
break;
case 38:
this.highlightItem("up");
e.preventDefault();
break;
case 13:
this.selectItem();
e.preventDefault();
break;
case 27:
this.showItems = false;
e.preventDefault();
break;
default:
return true;
}
},
watch: {
'query': function (newValue, oldValue) {
if (newValue === this.lastSetQuery) {
this.lastSetQuery = null
return
selectItem(index) {
let item = null;
if (typeof index === "undefined") {
if (this.activeItemIndex === -1) {
return;
}
this.onQueryChanged(newValue)
this.$emit('input', newValue)
},
'value': function (newValue, oldValue) {
this.setInputQuery(newValue)
item = this.items[this.activeItemIndex];
} else {
item = this.items[index];
}
if (!item) {
return;
}
if (this.onItemSelected) {
this.onItemSelected(item);
} else {
this.onItemSelectedDefault(item);
}
this.hideItems();
},
methods: {
onItemSelectedDefault (item) {
if (typeof item === 'string') {
this.$emit('input', item)
this.setInputQuery(item)
this.showItems = false
// console.log('change value')
}
},
hideItems () {
setTimeout(() => {
this.showItems = false
}, 300)
},
showResults () {
this.showItems = true
},
setInputQuery (value) {
this.lastSetQuery = value
this.query = value
},
onKeyDown (e) {
this.$emit('keyDown', e.keyCode)
switch (e.keyCode) {
case 40:
this.highlightItem('down')
e.preventDefault()
break
case 38:
this.highlightItem('up')
e.preventDefault()
break
case 13:
this.selectItem()
e.preventDefault()
break
case 27:
this.showItems = false
e.preventDefault()
break
default:
return true
}
},
selectItem (index) {
let item = null
if (typeof index === 'undefined') {
if (this.activeItemIndex === -1) {
return
}
item = this.items[this.activeItemIndex]
} else {
item = this.items[index]
}
if (!item) {
return
}
if (this.onItemSelected) {
this.onItemSelected(item)
highlightItem(direction) {
if (this.items.length === 0) {
return;
}
let selectedIndex = this.items.findIndex((item, index) => {
return index === this.activeItemIndex;
});
if (selectedIndex === -1) {
// nothing selected
if (direction === "down") {
selectedIndex = 0;
} else {
this.onItemSelectedDefault(item)
}
this.hideItems()
},
highlightItem (direction) {
if (this.items.length === 0) {
return
selectedIndex = this.items.length - 1;
}
let selectedIndex = this.items.findIndex((item, index) => {
return index === this.activeItemIndex
})
if (selectedIndex === -1) {
// nothing selected
if (direction === 'down') {
selectedIndex = 0
} else {
selectedIndex = this.items.length - 1
} else {
this.activeIndexItem = 0;
if (direction === "down") {
selectedIndex++;
if (selectedIndex === this.items.length) {
selectedIndex = 0;
}
} else {
this.activeIndexItem = 0
if (direction === 'down') {
selectedIndex++
if (selectedIndex === this.items.length) {
selectedIndex = 0
}
} else {
selectedIndex--
if (selectedIndex < 0) {
selectedIndex = this.items.length - 1
}
selectedIndex--;
if (selectedIndex < 0) {
selectedIndex = this.items.length - 1;
}
}
this.activeItemIndex = selectedIndex
},
setItems (items) {
this.items = items
this.activeItemIndex = -1
this.showItems = true
},
onQueryChanged (value) {
const result = this.onInputChange(value)
this.items = []
if (typeof result === 'undefined' || typeof result === 'boolean' || result === null) {
return
}
if (result instanceof Array) {
this.setItems(result)
} else if (typeof result.then === 'function') {
result.then(items => {
this.setItems(items)
})
}
}
this.activeItemIndex = selectedIndex;
},
setItems(items) {
this.items = items;
this.activeItemIndex = -1;
this.showItems = true;
},
onQueryChanged(value) {
const result = this.onInputChange(value);
this.items = [];
if (
typeof result === "undefined" ||
typeof result === "boolean" ||
result === null
) {
return;
}
if (result instanceof Array) {
this.setItems(result);
} else if (typeof result.then === "function") {
result.then(items => {
this.setItems(items);
});
}
}
}
};
</script>

0 comments on commit 907cdaf

Please sign in to comment.