123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- <template lang="pug">
- .searcher
- span.input-icon.fa.fa-search(
- ref='searchSpan'
- @click='onClickOptions'
- )
- input.search-input(
- autofocus
- v-model='search'
- :placeholder='placeholder'
- )
- .dropdown-options(
- ref='dropdownOptions'
- :class="{'input-show': showOptions }"
- )
- ul.input-options
- li.input-option(
- v-for='option in getOptions()'
- :key='option.id'
- @click='onSelectOption(option)'
- )
- h2 {{ option.name }}
- </template>
- <script>
- export default {
- props: {
- placeholder: {
- type: String,
- default: ''
- },
- autofocus: {
- type: Boolean,
- default: false
- },
- items: {
- type: Array,
- default: [],
- required: true
- },
- keys: {
- type: Array,
- default: [],
- required: true
- }
- },
- watch: {
- search(value, lastValue) {
- value = value.trim()
- if (!value && value.length != lastValue.length) {
- this.selectedOption = null
- }
- this.showOptions = !!value && !this.selectedOption
- this.performSearch(value)
- }
- },
- methods: {
- getOptions() {
- return this.results.length == 0 ? this.items : this.results
- },
- performSearch(value) {
- this.results = []
- if (this.selectedOption) {
- return
- }
-
- for (let item of this.items) {
- for (let field in item) {
- if (typeof item[field] !== 'string') {
- continue
- }
- if (this.keys.length !== 0 && this.keys.indexOf(field) === -1) {
- continue
- }
- if (item[field].toLowerCase().indexOf(value.toLowerCase()) !== -1) {
- this.results.push(item)
- break
- }
- }
- }
- },
- hideOptions() {
- this.showOptions = false
- },
- onClickOptions() {
- this.showOptions = !this.showOptions || !!this.search
- },
- onSelectOption(item) {
- this.selectedOption = item
- this.search = item.name
- this.results = []
-
- this.$emit('onSelect', item)
- },
- onClickOutside(e) {
- let searchSpan = this.$refs.searchSpan
- if (!searchSpan) {
- return
- }
- let target = e.target
- if (target === searchSpan) {
- return
- }
- let el = this.$refs.dropdownOptions
- if (el !== target && !el.contains(target)) {
- this.hideOptions()
- }
- }
- },
- created() {
- document.addEventListener('click', this.onClickOutside)
- },
- destroyed() {
- document.removeEventListener('click', this.onClickOutside)
- },
- data() {
- return {
- search: '',
- results: [],
- selectedOption: null,
- showOptions: false
- }
- }
- }
- </script>
- <style lang="sass">
- @import '../../assets/variables'
- .searcher
- width: 100%
- height: 35px
- position: relative
- .input-icon
- position: absolute
- top: 10px
- right: 10px
- font-size: 12pt
- color: $app-dark-color
- &:hover
- cursor: pointer
- .search-input
- width: 100%
- height: 100%
- border-radius: 0
- font-size: 12pt
- font-weight: normal
- padding-right: 35px
- .dropdown-options
- width: 100%
- height: 150px
- display: none
- position: absolute
- background: $app-light-color
- border: 1px solid $app-separator-color
- box-shadow: 0 3px 5px $app-separator-color
- z-index: 10
- top: 35px
- left: 0
- right: 0
- bottom: -325px
- padding: 0
- animation-duration: 500ms
- overflow-y: auto
- &.input-show
- display: block
- .input-options
- padding-left: 0
- .input-option
- height: 35px
- display: block
- text-align: left
- margin-top: 5px
- padding-top: 5px
- font-size: 10pt
- font-weight: normal
- border-bottom: 1px solid $app-border-color
- &:last-child
- margin-bottom: 10px
- &:hover
- border-bottom: 2px solid $app-main-color
- cursor: pointer
- h2
- font-size: 10pt
- font-weight: normal
- margin: 0
- </style>
|