0

I've create a new directive to use the jQuery Plug-In Select2 with vue.js as written down on the vue.js example page.

But I don't want to just output the value of the selected option. To store the selections I try to bind my custom method create to the @change event.

Inside the directive, the Select2 will trigger the change event for the select input field while it updates, but nevertheless it still doesn't call my custom method.

Is there some hidden magic? I've tried to read the source code of vue.js but can't find something that puts me in the right direction.

Vue.directive('select', {
  twoWay: true,
  priority: 1000,

  params: ['options'],

  bind: function() {
    var self = this;

    $(this.el)
      .select2({
        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');
  }
});

var vm = new Vue({
  el: '#items',
  data: {
    items: [],
    new_item: '',
    options: [{
      id: 1,
      text: 'First'
    }, {
      id: 2,
      text: 'Second'
    }, {
      id: 3,
      text: 'Third'
    }, {
      id: 4,
      text: 'Fourth'
    }, {
      id: 5,
      text: 'Fifth'
    }]
  },
  methods: {
    create: function() {
      var self = this,
        label = '';

      this.options.map(function(item) {
        if (self.new_item == item.id)
          label = item.text;
      });

      var obj = {
        id: self.new_item,
        name: label
      };

      this.items.push(obj);
      this.new_item = '';
    }
  }
});
select {
  min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<div id="items">
  <ul>
    <li v-for="item in items">{{ item.id }} &ndash; {{ item.name }}</li>
  </ul>
  <select v-select="new_item" @change="create" :options="options">
    <option value="0">--Select--</option>
  </select>
</div>
kindisch
  • 766
  • 1
  • 7
  • 23

1 Answers1

0

Maybe you can add watcher to your new_item variable like this. So you can do something when new_item value change. I myself still searching how to trigger @change after select2 change method, but no clue til now.

Vue.directive('select', {
  twoWay: true,
  priority: 1000,

  params: ['options'],

  bind: function() {
    var self = this;

    $(this.el)
      .select2({
        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');
  }
});

var vm = new Vue({
  el: '#items',
  data: {
    items: [],
    new_item: '',
    options: [{
      id: 1,
      text: 'First'
    }, {
      id: 2,
      text: 'Second'
    }, {
      id: 3,
      text: 'Third'
    }, {
      id: 4,
      text: 'Fourth'
    }, {
      id: 5,
      text: 'Fifth'
    }]
  },
  methods: {
    create: function() {
      var self = this,
        label = '';

      this.options.map(function(item) {
        if (self.new_item == item.id)
          label = item.text;
      });

      var obj = {
        id: self.new_item,
        name: label
      };

      this.items.push(obj);
      this.new_item = '';
    }
  },
  watch:{
    new_item:function(){
       alert(this.new_item);
    }
  }
});
select {
  min-width: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/1.0.24/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<div id="items">
  <ul>
    <li v-for="item in items">{{ item.id }} &ndash; {{ item.name }}</li>
  </ul>
  <select v-select="new_item" @change="create" :options="options">
    <option value="0">--Select--</option>
  </select>
</div>
Jefferson Setiawan
  • 536
  • 1
  • 5
  • 22