RGweb
RGweb

Reputation: 109

Bootstrap selectpicker VueJS directive

I'm trying to build a custom directive for Bootstrap that makes a <select> input into a "selectpicker" from Bootstrap selectpicker Also I would like this directive to use the default options functionality of VueJS for filling the options on a <select> So the html would be something like this:

<select v-selectpicker="myValue" options="myOptions"></select>

Now I can create the directive perfectly and use the bind method to call the selectpicker() method on the element. The problem seems to be the fact that the options are set after the call to selectpicker(). So somehow I need to either wait until the options are set, or I have to do another call to selectpicker(refresh) when the options are set.

Does anyone know if this is possible?

Upvotes: 4

Views: 8627

Answers (5)

John Ole Njue
John Ole Njue

Reputation: 91

Vue.directive('selectpicker',{
inserted:function(el) {     
    jQuery(el).selectpicker({
        title: 'Choose...',
        liveSearch:true,
        dataHeader:"Type in to filter",
        style: 'btn btn-default btn-round',
        size: 10
    }).selectpicker('render');

},
componentUpdated:function(el, binding) {
    jQuery(el).selectpicker('val', binding.value);
    jQuery(el).selectpicker('refresh');
}

});

Usage :

<select class="form-control" v-model="causeOfLoss" v-selectpicker="causeOfLoss"> ... </select>

Upvotes: 1

morphey83
morphey83

Reputation: 111

this will be useful for those who are looking for the ability to use bootstrap-select and vue.js (v2.5)

Directive:

Vue.directive('selectpicker',
{
    inserted(el) {
        $(el).selectpicker(
            {/*options*/},
        });
    },

    update(el, binding) {        
        $(el).selectpicker('val', binding.value);
    },

    componentUpdated(el) {
        $(el).selectpicker('refresh');
    },

    unbindel() {
        $(el).selectpicker('destroy');
    }
});

html:

<select 
    class="selectpicker form-control" 
    v-selectpicker="mySelectedModel" 
    v-model="mySelectedModel">
    <!-- options -->
</select>

Upvotes: 0

forkiven
forkiven

Reputation: 51

The answer provided only works if you're serving your options from the server. Trying to init Bootstrap-select using Vue data as options always has it getting called before the options are rendered.

My solution was to use a component and pass in the options / select name and callback function as props that way I can be sure they are all loaded.

HTML

<select-picker :name.sync="itemsPerPage" :options.sync="itemsPerPageOptions" :function="changeItemsPerPage"></select-picker>    

JS - Selectpicker Component

Vue.component('select-picker', {
template:'<select v-model="name" class="themed-select" @change="function">' +
'<option v-bind:value="option.value" v-for="option in options">{{ option.label }}</option>' +
'</select>',
name: 'selectpicker',
props: ['options', 'name', 'function'],
updated: function() {
    console.log(this);
    $(this.$el).selectpicker({
        iconBase: 'fa',
        tickIcon: 'fa-check'
    });
}
});

Upvotes: 5

Łukasz Kuczmaja
Łukasz Kuczmaja

Reputation: 1227

I've changed a little solution of mocheaz. It already sets initial value if select tag is placed dynamically:

require('bootstrap-select');

Vue.directive('selectpicker',
{
    twoWay: true,

    bind()
    {
        $(this.el).selectpicker();

        $(this.el).on('change', function(e) {
            this.set($(this.el).val());
        }.bind(this));
    },

    update(newValue)
    {
        $(this.el).val(newValue);
        $(this.el).selectpicker('val', newValue);
    },

    unbind()
    {
        $(this.el).selectpicker('destroy');
    }
});

Upvotes: 1

mocheaz
mocheaz

Reputation: 29

I did this and it worked for me.

Vue.directive('selectpicker', {
    twoWay: true,
    bind: function() {
        $(this.el).on("change", function(e) {
            this.set($(this.el).val());
        }.bind(this));
    },
    update: function(nv, ov) {
        $(this.el).trigger("change");
    }
});

Upvotes: 0

Related Questions