autcomplete field in streamer
This commit is contained in:
		@ -31,6 +31,11 @@ $body-background-color: $light;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.float-right { float: right }
 | 
			
		||||
.float-left { float: left }
 | 
			
		||||
.overflow-hidden { overflow: hidden }
 | 
			
		||||
.overflow-hidden.is-fullwidth { max-width: 100%; }
 | 
			
		||||
 | 
			
		||||
//-- navbar
 | 
			
		||||
.navbar + .container {
 | 
			
		||||
    margin-top: 1em;
 | 
			
		||||
 | 
			
		||||
@ -1,19 +1,32 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <div :class="dropdownClass">
 | 
			
		||||
        <div class="dropdown-trigger is-fullwidth">
 | 
			
		||||
            <div class="control is-expanded">
 | 
			
		||||
                <input type="hidden" :name="name"
 | 
			
		||||
                    :value="selectedValue" />
 | 
			
		||||
            <input type="hidden" :name="name"
 | 
			
		||||
                :value="selectedValue" />
 | 
			
		||||
            <div v-show="!selected" class="control is-expanded">
 | 
			
		||||
                <input type="text" :placeholder="placeholder"
 | 
			
		||||
                    ref="input" class="input is-fullwidth"
 | 
			
		||||
                    @keyup="onKeyUp" @focus="active=true" @click="active=true"/>
 | 
			
		||||
                    @keydown.capture="onKeyPress"
 | 
			
		||||
                    @keyup="onKeyUp" @focus="this.cursor < 0 && move(0)"/>
 | 
			
		||||
            </div>
 | 
			
		||||
            <button v-if="selected" class="button is-normal is-fullwidth has-text-left is-inline-block overflow-hidden"
 | 
			
		||||
                    @click="select(-1, false, true)">
 | 
			
		||||
                <span class="icon is-small ml-1">
 | 
			
		||||
                    <i class="fa fa-pen"></i>
 | 
			
		||||
                </span>
 | 
			
		||||
                <span class="is-inline-block" v-if="selected">
 | 
			
		||||
                    <slot name="button" :index="selectedIndex" :item="selected"
 | 
			
		||||
                        :value-field="valueField" :labelField="labelField">
 | 
			
		||||
                    {{ selected.data[labelField] }}
 | 
			
		||||
                    </slot>
 | 
			
		||||
                </span>
 | 
			
		||||
            </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="dropdown-menu is-fullwidth">
 | 
			
		||||
            <div class="dropdown-content" style="overflow: hidden">
 | 
			
		||||
                <a v-for="(item, index) in items" :key="item.id"
 | 
			
		||||
                    :class="['dropdown-item', index === this.selectedIndex ? 'is-active':'']"
 | 
			
		||||
                    @click="select(index); active=false" :title="item.data[labelField]">
 | 
			
		||||
                    :class="['dropdown-item', (index == this.cursor) ? 'is-active':'']"
 | 
			
		||||
                    @click.capture.prevent="select(index, false, false)" :title="item.data[labelField]">
 | 
			
		||||
                    <slot name="item" :index="index" :item="item" :value-field="valueField"
 | 
			
		||||
                        :labelField="labelField">
 | 
			
		||||
                    {{ item.data[labelField] }}
 | 
			
		||||
@ -40,10 +53,10 @@ export default {
 | 
			
		||||
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            active: false,
 | 
			
		||||
            value: '',
 | 
			
		||||
            items: [],
 | 
			
		||||
            selectedIndex: -1,
 | 
			
		||||
            cursor: -1,
 | 
			
		||||
            isFetching: false,
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
@ -69,13 +82,19 @@ export default {
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        dropdownClass() {
 | 
			
		||||
            const active = this.active && this.items.length;
 | 
			
		||||
            const active = this.cursor > -1 && this.items.length;
 | 
			
		||||
            return ['dropdown', active ? 'is-active':'']
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    methods: {
 | 
			
		||||
        select(index, relative) {
 | 
			
		||||
        move(index=-1, relative=false) {
 | 
			
		||||
            if(relative)
 | 
			
		||||
                index += this.cursor
 | 
			
		||||
            this.cursor = Math.max(-1, Math.min(index, this.items.length-1))
 | 
			
		||||
        },
 | 
			
		||||
    
 | 
			
		||||
        select(index=-1, relative=false, active=null) {
 | 
			
		||||
            if(relative)
 | 
			
		||||
                index += this.selectedIndex
 | 
			
		||||
            else if(index == this.selectedIndex)
 | 
			
		||||
@ -86,28 +105,39 @@ export default {
 | 
			
		||||
                this.$refs.input.value = this.selectedLabel
 | 
			
		||||
                this.$refs.input.focus()
 | 
			
		||||
            }
 | 
			
		||||
            this.$emit('select', index, this.selected, this.selectedValue)
 | 
			
		||||
            if(this.selectedIndex < 0)
 | 
			
		||||
                this.$emit('unselect')
 | 
			
		||||
            else
 | 
			
		||||
                this.$emit('select', index, this.selected, this.selectedValue)
 | 
			
		||||
 | 
			
		||||
            if(active!==null)
 | 
			
		||||
                active && this.move(0) || this.move(-1)
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onKeyPress: function(event) {
 | 
			
		||||
            switch(event.keyCode) {
 | 
			
		||||
                case 13: this.select(this.cursor, false, false)
 | 
			
		||||
                         break
 | 
			
		||||
                case 27: this.select()
 | 
			
		||||
                         break
 | 
			
		||||
                case 38: this.move(-1, true)
 | 
			
		||||
                         break
 | 
			
		||||
                case 40: this.move(1, true)
 | 
			
		||||
                         break
 | 
			
		||||
                default: return
 | 
			
		||||
            }
 | 
			
		||||
            event.preventDefault()
 | 
			
		||||
            event.stopPropagation()
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        onKeyUp: function(event) {
 | 
			
		||||
            this.active = true
 | 
			
		||||
            switch(event.keyCode) {
 | 
			
		||||
                case 27: this.active = false
 | 
			
		||||
                         return
 | 
			
		||||
                case 38: this.select(-1, true)
 | 
			
		||||
                         return
 | 
			
		||||
                case 40: this.select(1, true)
 | 
			
		||||
                         return
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            const value = event.target.value
 | 
			
		||||
            if(value === this.value)
 | 
			
		||||
                return
 | 
			
		||||
 | 
			
		||||
            this.value = value;
 | 
			
		||||
            if(!value)
 | 
			
		||||
                return this.select(null)
 | 
			
		||||
                return this.selected && this.select(-1)
 | 
			
		||||
 | 
			
		||||
            this.fetch(value)
 | 
			
		||||
        },
 | 
			
		||||
@ -120,7 +150,7 @@ export default {
 | 
			
		||||
            return this.model.fetch(this.url.replace('${query}', query), {many:true})
 | 
			
		||||
                .then(items => { this.items = items || []
 | 
			
		||||
                                 this.isFetching = false
 | 
			
		||||
                                 this.active = items.length > 0
 | 
			
		||||
                                 this.move(0)
 | 
			
		||||
                                 return items },
 | 
			
		||||
                      data => {this.isFetching = false; Promise.reject(data)})
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user