Update vuejs model value using jquery-chosen plugin

rmagnum2002 picture rmagnum2002 · Jul 9, 2015 · Viewed 7.1k times · Source

Trying to use jquery-chosen with vue, the problem is that this plugin hides the actual select that I applied v-model, so when I select a value vue doesn't recognize it as a select change event and model value is not updated.

The value of the select is being changed actually when I select something, I've inspected this with console.log to see the selected value.

http://jsfiddle.net/qfy6s9Lj/3/

I could do vm.$data.city = $('.cs-select').val(), that seems to work, But is there another option? If the value of the select was changed why vue doesn't see this?

Answer

Sean William Washington picture Sean William Washington · Dec 15, 2015

@swift's answer got pretty close, but as @bertrand pointed out, it doesn't work for multiselects. I've worked something out that works with both cases: http://jsfiddle.net/seanwash/sz8s99xx/

I would have just commented but I don't have enough rep to do so.

Vue.directive('chosen', {
    twoWay: true, // note the two-way binding
    bind: function () {
        $(this.el)
            .chosen({
                inherit_select_classes: true,
                width: '30%',
                disable_search_threshold: 999
            })
            .change(function(ev) {
                // two-way set
                // Construct array of selected options
                var i, len, option, ref;
                var values = [];
                ref = this.el.selectedOptions;
                for (i = 0, len = ref.length; i < len; i++) {
                    option = ref[i];
                    values.push(option.value)
                }
                
                this.set(values);
                
            }.bind(this));
    },
    update: function(nv, ov) {
        // note that we have to notify chosen about update
        $(this.el).trigger("chosen:updated");
    }
});

var vm = new Vue({
  data: {
      city: 'Toronto',
      cities: [{text: 'Toronto', value: 'Toronto'}, 
               {text: 'Orleans', value: 'Orleans'}]
  }
}).$mount("#search-results");