Skip to content

Instantly share code, notes, and snippets.

@craigh411
Last active March 31, 2021 23:28
Show Gist options
  • Select an option

  • Save craigh411/c274a29ca331041fa6f3666756339634 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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