Search code examples
javascriptjqueryvue.jsjquery-select2vue-resource

Select2 and Vue Directive


I am integrating a jQuery select2 plugin by wrapping it inside a custom directive.

export default {

    data() {
        return {
            selected: null,
            options: []
        }
    },

    ready() {
    this.fetchUsers()
}

    methods: {
        fetchUsers: function () {
            this.$http({
                url: '/api/users/get-all',
                method: 'GET'
            }).then(function (response) {
                this.$set('options', response.data)
            }, function (response) {
                // error callback
            });
        }
    },

    directives: {
        select: {
            twoWay: true,
            priority: 1000,

            params: ['options'],

            bind: function () {
                var self = this;

                $(this.el)
                        .select2({
                            theme: "bootstrap",
                            closeOnSelect: true,
                            minimumInputLength: 3,
                            data: this.params.options
                        })
                        .on('change', function () {
                            self.set(this.value)
                        })
            },
            update: function (value) {
                $(this.el).val(value).trigger('change')
            },
            unbind: function () {
                $(this.el).off().select2('destroy')
            }
        }
    }

}

and HTML:

<select v-select="selected" :options="options"></select>

I try to get all users and set to options in fetchUsers function, but seem fetchUsers function was executed after select2 directive so the options variable always be empty.

So how can I get all users through ajax (vue-resource) and after that populate to select2?


Solution

  • I had a similar issue with select2, and had to use paramwatchers to check when options was updated:

    select: {
        twoWay: true,
        priority: 1000,
    
        params: ['options'],
    
        paramswatchers: {
             "options": function (val, oldVal) {
                 $(this.el).select2({
                     data: val
                 })
             }
        }
    
        bind: function () {
            var self = this;
    
            $(this.el).select2({
                theme: "bootstrap",
                closeOnSelect: true,
                minimumInputLength: 3,
                data: this.params.options
            })
            .on('change', function () {
                self.set(this.value)
            })
        },
        update: function (value) {
            $(this.el).val(value).trigger('change')
        },
        unbind: function () {
            $(this.el).off().select2('destroy')
        }
    }
    

    Source: https://vuejs.org/guide/custom-directive.html#params