Skip to content

Instantly share code, notes, and snippets.

@craigh411
Last active March 31, 2021 23:28
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save craigh411/c274a29ca331041fa6f3666756339634 to your computer and use it in GitHub Desktop.
Save craigh411/c274a29ca331041fa6f3666756339634 to your computer and use it in GitHub Desktop.
Vue.js component for Select2

#Vue.js component for Select2

A select2 component for vue.js. Quickly create select2 components, load data via ajax and retrieve selected values and newly created tags.

#Usage

Download and register the component:

Vue.component(
    'select2',
    require('./components/select2.vue')
);

Then use your favourite bundler (browserify, webpack etc) to update your bundle.

##HTML

In your HTML simply add:

<select2></select2>

##Props

The following props are vailable:

###:options

Prop for sending select2 options, maps directly to select2 (see: https://select2.github.io)

<select2 :options="{tags: 'true'}"></select2>

Note: The select2 "data" option is bound via vue.js not select2, so acts the same as loading data via ajax.

###data-url

The URL for retrieving the data to populate your select2 select box (Expects `JSON)

<select2 data-url="my/select2/data"></select2>

###dispatch-id

The dispatch id for the component. This is only needed if you have multiple select2 boxes on one page so you can identify which componant sent the dispatch.

<select2 dispatch-id="states"></select2>
<select2 dispatch-id="countries"></select2>

You can then pick the id with the second paramater of each event:

events: {
    'select2-selected' : function(selected, dispatchId){
	console.log('Item selected for ' + dispatchId);
    },
    'select2-tag-created' : function(tags, dispatchId){
	console.log('New tag created for ' + dispatchId);
    }

##Dispatchers

There are two dispatchers:

###select2-selected

Supplies a list of all selected list items (excluding created tags).

###select2-tag-created

Supplies a list of all newly created tags.

##Example Parent ViewModel

var vm = new Vue({
    el: 'body',
    data: {
    	'selected' : [],
    	'createdTags': []
    },
    events: {
    	'select2-selected' : function(selected){
		  // Set the selected list
		  this.$set('selected', selected);
    	},
    	'select2-tag-created' : function(tags){
		  // Set the created tags list
		  this.$set('createdTags', tags);
    	}
    }
});
<style scoped>
select {
width: 100%;
}
</style>
<template>
<div>
<select multiple="muiltiple" class="{{class}}">
<option v-for="item in list" :value="item.id">{{ item.text }}</option>
</select>
</div>
</template>
<script type="text/javascript">
export default {
props: ['options', 'data-url', 'class', 'dispatch-id'],
ready: function() {
var options = $.extend({}, this.options);
this.bind(options);
console.log(this.dispatchId);
},
methods: {
bind(options) {
var self = this;
var data = options.data;
// Map any select2 "data" params to the list data array, so vue can bind the list data.
if (data) {
this.$set('list', data);
options.data = undefined;
}
$(this.$el).find('select').select2(options).on('change', function() {
// Notify the listeners that the values have changed
self.notify($(this).val());
});
// Populate the list via ajax if "data-url" prop has been defined.
if (this.dataUrl !== undefined) {
this.getList(this.dataUrl);
}
},
getList(url) {
var self = this;
this.$http.get(url)
.then(response => {
self.$set('list', JSON.parse(response.data));
});
},
flattenArray(key) {
var list = this.list;
var flattened = [];
for (let i = 0; i < list.length; i++) {
let value = list[i][key];
flattened[i] = value.toString();
}
return flattened;
},
filterSelected(filterArray) {
var ids = this.flattenArray('id');
// Return all selected values that were pre-loaded (i.e. are in this.list).
return ids.filter(x => filterArray.indexOf(x) >= 0);
},
filterCreated(filterArray) {
var ids = this.flattenArray('id');
// Return all tags that have been created (i.e. are not in this.list)
return filterArray.filter(x => ids.indexOf(x) < 0);
},
notify(value) {
this.notifySelected(value);
this.notifyTagCreated(value);
},
notifySelected(value) {
this.$dispatch('select2-selected', this.filterSelected(value), this.dispatchId);
},
notifyTagCreated(tags) {
this.$dispatch('select2-tag-created', this.filterCreated(tags), this.dispatchId);
}
},
data() {
return {
list: []
}
}
}
</script>
@s0By
Copy link

s0By commented Sep 14, 2018

What about paged results?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment