Skip to content

Instantly share code, notes, and snippets.

@CristianHG2
Created July 17, 2018 19:35
Show Gist options
  • Save CristianHG2/1f73c4f5487a0b6b87949db5edacff7e to your computer and use it in GitHub Desktop.
Save CristianHG2/1f73c4f5487a0b6b87949db5edacff7e to your computer and use it in GitHub Desktop.
Vue component with an integration of Selectize.js' tagging feature, reactive to v-model
<template>
<input type="text" class="selectize-tag-input">
</template>
<script>
if (!$().selectize) {
require('selectize') // This script requires selectize
}
export default
{
name : 'tags-field',
props : ["value", "onAdd"], // The onAdd property must be a function and is used to verify if a new tag being added is valid, returning false will not allow the field to be added
watch : {
value : function() // Here is where we work around the non-reactiveness of Selectize
{
this.$el.value = this.value;
this.$el.setAttribute('value', this.value);
this.syncWatcher();
}
},
methods :
{
emitValue()
{
this.$emit('input', this.innerValue);
},
init : function(reinit)
{
var t = this;
this.instance = $(this.$el).selectize({
delimiter: ',',
create: function(input) {
if ( typeof t.onAdd === "function" )
{
if ( t.onAdd(input) !== true ) {
this.$control_input[0].value = '';
this.$control_input[0].setAttribute('value', '');
return false;
}
}
return {
value: input,
text: input
}
}
});
var inputEl = $(this.$el).siblings().children('.selectize-input').children('input')[0];
var t = this;
// After reinitializing, take the user back to the text field if they've typed in it previously
inputEl.addEventListener('focus', function()
{
t.userType = true;
});
if ( reinit === true && this.userType )
{
inputEl.focus();
}
// Restart watcher
this.syncWatcher();
},
reinit : function(reinit)
{
this.instance[0].selectize.destroy();
this.init(reinit);
},
syncWatcher : function()
{
if ( this.watcherInstance !== null )
clearInterval(this.watcherInstance); // We need to clear the interval and redefine the "t" variable to ensure that the watcher is up to date with the instance's new information
var t = this;
this.watcherInstance = setInterval(function()
{
if ( t.$el.getAttribute('value') !== t.innerValue )
{
t.innerValue = t.$el.getAttribute('value');
t.emitValue();
t.reinit(true);
}
}, 100);
}
},
mounted()
{
this.init();
},
data()
{
return {
userType : false,
instance : null,
watcherInstance : null,
innerValue : ''
};
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment