Vue - Combo Component
Made with std Inputbox over Select combo. Optionlist not alterable limitation.
by Ben Clayton
HTML
<script src="https://unpkg.com/vue"></script>
=== Vue JS - Component Example ====
<div id="mycombo">
<combo-widget :context='$data' property='myvalue' :list='list'></combo-widget>
<br/> Non constrained Combo value:<b> {{myvalue}}</b>
<br/> Combo List Offered: <b>{{list}}</b>
</div>
<script id="tmpl-combo-widget" type="text/x-template">
<div class="combo-widget">
<select class="cwselect" v-model="context[property]">
<option v-for="opt in list" :value="opt">{{opt}}</option>
</select>
<div class="cwplaceholder txt" ><span class="pstart">{{pstart}}</span><span class="pend">{{pend}}</span></div>
<input class="cwselectinput txt" type="text" v-model="context[property]" v-on:change="change" />
{{placeholder}}
</div>
</script>
CSS
.combo-widget {
position:relative;
}
.combo-widget .cwselect {
position: relative;
width: 230px;
height: 26px;
}
.combo-widget .txt {
font-family: "Times New Roman", Times, serif;
font-size:14px;
}
.combo-widget .cwselectinput {
position: absolute;
z-index: 3;
width: 200px;
height: 22px;
top:0px;
left:0px;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
border: 1px solid #C0C0C0;
border-right: 0;
background-color: rgba(0,0,0,0);
}
.combo-widget .cwplaceholder {
position: absolute;
z-index: 2;
width: 200px;
height: 22px;
top:4.3px;
left:2px;
color:gray;
background-color: rgb(248, 248, 248);
}
.combo-widget .pstart {
color:white;
}
.combo-widget .pend {
position:relative;
color:gray;
top:1px;
}
input:focus,
select:focus {
outline: none !important;
}
JavaScript
Vue.component('combo-widget', {
template: "#tmpl-combo-widget",
props: {
"context": {
type: Object, // expect object like { name: "Size", value: "Large" }
required: true
},
"property": {
type: String, // expect string like "name" or "value"
required: true
},
"list": {
type: Array // expect ["Video","Music","Audio"]
}
},
data: function() {
return {}
},
methods: {
change: function(e) {
var v = e.target.value;
var i = this.list.map(function(x){return x.toLowerCase()}).indexOf(v.toLowerCase());
if(i>-1){
Vue.set(this.context,this.property,this.list[i]);
} else {
this.list.push(v);
}
}
},
computed: {
pstart: function() {
return "T";//this.context[this.property];
},
pend: function() {
return "hree";//this.context[this.property];
}
},
created() {
//console.log('list:',this.list);
}
});
//---------------------------------------------------------
new Vue({
el: '#mycombo',
data: {
myvalue: "Three",
list: ["One", "Two", "Three"]
}
});