2022-09-22 07:10:08 -04:00
< template >
2023-04-24 21:30:14 -04:00
< div class = "dropdown" : class = "{ 'form-floating': label }" >
< input type = "text" class = "form-control" placeholder = " " @focus ="option_open" @input ="option_filter" v -model = " x_modelValue " @keydown.down ="option_down" @keydown.up ="option_up" @keydown.enter ="option_enter" / >
< ul class = "dropdown-menu shadow" : class = "{ show: (open) && (results.length > 0) }" >
2022-09-22 07:10:08 -04:00
< li class = "loading" v-if ="!items" > Loading results... < / li >
2023-04-24 21:30:14 -04:00
< li v -else v-for ="(result, i) in results" :key="i" @click="option_click(result)" class="dropdown-item" :class="{ 'is-active': i === index }" > {{ result }} < / li >
2022-09-22 07:10:08 -04:00
< / ul >
2023-04-24 21:30:14 -04:00
< label v-if ="label" > {{ label }} < / label >
2022-09-22 07:10:08 -04:00
< / div >
< / template >
< style scoped >
2023-04-24 21:30:14 -04:00
. dropdown - menu {
width : 100 % ;
max - height : 10 rem ;
2022-09-22 07:10:08 -04:00
overflow : auto ;
}
2023-04-24 21:30:14 -04:00
. dropdown - item {
cursor : default ;
2022-09-22 07:10:08 -04:00
}
2023-04-24 21:30:14 -04:00
. dropdown - item . is - active ,
. dropdown - item : hover {
background - color : var ( -- bs - primary ) ;
color : var ( -- bs - body - bg ) ;
2022-09-22 07:10:08 -04:00
}
< / style >
< script >
export default {
props : {
2023-04-24 21:30:14 -04:00
modelValue : {
2022-09-22 07:10:08 -04:00
type : String ,
default : ''
} ,
items : {
type : Array ,
required : false ,
default : ( ) => [ ] ,
2023-04-24 21:30:14 -04:00
} ,
label : String
2022-09-22 07:10:08 -04:00
} ,
2023-04-24 21:30:14 -04:00
emits : [
'update:modelValue'
] ,
2022-09-22 07:10:08 -04:00
data ( ) {
return {
2023-04-24 21:30:14 -04:00
x _modelValue : this . modelValue ,
2022-09-22 07:10:08 -04:00
results : [ ] ,
open : false ,
index : - 1 ,
} ;
} ,
watch : {
2023-04-24 21:30:14 -04:00
modelValue ( val ) {
this . x _modelValue = val ;
2022-09-22 07:10:08 -04:00
} ,
2023-04-24 21:30:14 -04:00
x _modelValue ( val ) {
this . $emit ( 'update:modelValue' , val ) ;
2022-09-22 07:10:08 -04:00
}
} ,
mounted ( ) {
2023-04-24 21:30:14 -04:00
this . x _modelValue = this . modelValue ;
2022-09-22 07:10:08 -04:00
document . addEventListener ( 'click' , this . option _close )
} ,
destroyed ( ) {
document . removeEventListener ( 'click' , this . option _close )
} ,
methods : {
option _open ( ) {
if ( this . items ) {
2023-04-24 21:30:14 -04:00
this . results = this . items ;
this . open = true ;
}
} ,
option _filter ( ) {
if ( this . items ) {
if ( this . x _modelValue ) {
var selection = this . x _modelValue . toLowerCase ( ) ;
this . results = this . items . filter ( ( item ) => item . toLowerCase ( ) . indexOf ( selection ) >= 0 ) ;
} else this . results = this . items ;
2022-09-22 07:10:08 -04:00
this . open = true ;
}
} ,
option _down ( ) {
if ( this . index < this . results . length ) this . index ++ ;
} ,
option _up ( ) {
if ( this . index > 0 ) this . index -- ;
} ,
option _enter ( ) {
2023-04-24 21:30:14 -04:00
this . x _modelValue = this . results [ this . index ] ;
2022-09-22 07:10:08 -04:00
this . open = false ;
this . index = - 1 ;
} ,
option _click ( result ) {
2023-04-24 21:30:14 -04:00
this . x _modelValue = result ;
2022-09-22 07:10:08 -04:00
this . open = false ;
} ,
option _close ( evt ) {
if ( ! this . $el . contains ( evt . target ) ) {
this . open = false ;
this . index = - 1 ;
}
}
}
} ;
< / script >