Reputation: 193
Trying to create a simple selectize vue component but I'm having issue where whenever I select an option and using v-model within the component, the dropdown automatically closes while removing the v-model the dropdown stays open until the specified max items are reached.
HTML
<div id="app">
<p>With Model: {{ selected }}</p>
<selectize v-model="selected" :options="options" data-max-items="2"></selectize>
<p>Without Model: {{ selected }}</p>
<selectize :options="options" data-max-items="2"></selectize>
</div>
JS
Vue.component('selectize', {
props: ['options', 'value'],
template: '<select><slot></slot></select>',
mounted() {
$(this.$el).selectize({
onInitialize: () => {
this.$el.selectize.setValue(this.value, true)
},
onChange: (value) => {
this.$emit('input', value)
},
...this.mergedSettings,
})
},
computed: {
mergedSettings() {
return $.extend({
options: this.options,
}, $(this.$el).data())
},
},
watch: {
value(value) {
this.$el.selectize.setValue(value, true)
},
},
})
new Vue({
el: "#app",
data: {
options: [
{ value: 1, text: "One" },
{ value: 2, text: "Two" },
{ value: 3, text: "Three" },
{ value: 4, text: "Four" },
],
selected: [],
},
})
I also created a jsfiddle: https://jsfiddle.net/uk0g69s4/19/
Upvotes: 1
Views: 1174
Reputation: 1471
I'm not proud of this solution but it is the better thing I could figure out.
Create a SELF_CHANGED
attribute to check if the change was triggered internally or externally...
Vue.component('selectize', {
props: ['options', 'value'],
data() {
return {
SELF_CHANGED: false
}
},
template: `
<select>
<slot></slot>
</select>
`,
mounted() {
$(this.$el).selectize({
onInitialize: () => {
this.$el.selectize.setValue(this.value, true)
},
onChange: (value) => {
this.SELF_CHANGED = true
this.$emit('input', value)
},
...this.mergedSettings,
})
},
computed: {
mergedSettings() {
return $.extend({
options: this.options,
}, $(this.$el).data())
},
},
watch: {
value(value) {
if (!this.SELF_CHANGED) {
this.$el.selectize.setValue(value, true)
}
this.SELF_CHANGED = false
},
},
})
new Vue({
el: "#app",
data: {
options: [{
value: 1,
text: "One"
},
{
value: 2,
text: "Two"
},
{
value: 3,
text: "Three"
},
{
value: 4,
text: "Four"
},
],
selected: [],
},
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sifter/0.5.3/sifter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microplugin/0.0.3/microplugin.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/js/selectize.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
<p>With Model: {{ selected }}</p>
<selectize v-model="selected" :options="options" data-max-items="2"></selectize>
<p>Without Model: {{ selected }}</p>
<selectize :options="options" data-max-items="2"></selectize>
</div>
Upvotes: 1