VueJS Select2 directive doesn't fire @change event
Asked Answered
P

4

8

As title says, I registered Select2 directive for VueJS 1.0.15 using example from their page. I want to catch @change event but it doesn't work.

HTML:

<select v-select="item.service" :selected="item.service" @change="serviceChange(item)">
  <option value="1">test 1</option>
  <option value="2">test 2</option>
</select>

JS:

Vue.directive('select', {
    twoWay: true,
    params: ['selected'],
    bind: function () {
        var self = this
        $(this.el)
            .select2({
                minimumResultsForSearch: Infinity
            })
            .val(this.params.selected)
            .on('change', function () {
                console.log('changed');
                self.set(this.value);
            })
    },
    update: function (value) {
        $(this.el).val(value).trigger('change')
    },
    unbind: function () {
        $(this.el).off().select2('destroy')
    }
});

var Checkout = new Vue({
      el: '.Checkout',
      methods: {
      serviceChange: function (item) {
          console.log(item);
      },
    }
});
Pitchford answered 22/1, 2016 at 13:33 Comment(1)
It might be easier to help you debug this if you set up a jsfiddle for it.Becharm
P
8

Expanded on Alberto Garcia answer.

var selectDropDown = $(".select-drop-down").select2();

selectDropDown.on('select2:select', function (e) {
    var event = new Event('change');
    e.target.dispatchEvent(event);
});
Perm answered 15/9, 2016 at 21:28 Comment(1)
Thank you for your solution! I am using a multi-select, so I also had to trigger the change event on select2:unselect, like this: selectDropDown.on("select2:select select2:unselect", function (e) {Auston
C
0

Yeah, I encountered this problem. Haven't figured out the solution yet, but this is my current work-a-round using watch:

In your VueJS:

watch: {

    /**
     * Watch changes on the select2 input
     *
     * @param integer personId
     */
    'person': function (personId) {
        var personName = $("#person").select2('data')[0].text
        this.doSomethingWithPerson(personId, personName)
    }
},

Then in your HTML:

<select
        id="person"
        v-select2="person"
        class="form-control"
        data-options="{{ $peopleJSON }}"
        data-placeholder="Choose a person"
>
</select>

Note: In the above HTML, {{ $peopleJSON }} is just how I insert my server-side JSON using Blade template engine. Not really pertinent to the question.

Cori answered 17/2, 2016 at 17:10 Comment(0)
A
0

I recently had a problem trying to bind a select2 result to a vuejs data model object, and I came with a workaround, it might help you:

https://jsfiddle.net/alberto1el/7rpko644/

var search = $(".search").select2({
  ajax: {
    url: "/echo/json",
    dataType: 'json',
    delay: 250,
    data: function (params) {
      return {
        q: params.term
      };
    },
    processResults: function (data, params) {
      var mockResults = [{id: 1,text: "Option 1"}, {id: 2,text: "Option 2"}, {id: 3,text: "Option 3"}];
      return {results: mockResults};
    },
    cache: true
  },
  escapeMarkup: function (markup) { return markup; },
  minimumInputLength: 1
});

search.on("select2:select", function (e){
    $('.result_search').val( $(this).val() ).trigger( 'change' );
});

var vm = new Vue({
  el: "#app",
  data: {
    busqueda_result : ''
  }
});

I know you are using a directive but maybe it helps you

Antares answered 23/3, 2016 at 16:4 Comment(0)
P
-1

shouldn't you use $emit?

update: function (value) {
    $(this.el).val(value);
    this.$emit('change');
}
Povertystricken answered 12/2, 2016 at 15:14 Comment(3)
This doesn't seem to work. I don't think $emit is available in the directive's context.Alain
you're basically dirty checking with watchPovertystricken
you're right, $emit does not exist in the directive contextPovertystricken

© 2022 - 2024 — McMap. All rights reserved.