0

select2 provides some custom events and i want to be able to listen to them, particularly the 'select2-removed' or better yet its custom 'change' event, and I’ve been searching the internet for some example, but with no luck.

here's what I’ve done so far:

HTML:

<input type="hidden" class="form-control" id="tags" ui-select2="modal.tags" data-placeholder="Available Tags" ng-model="form.tags">

JavaScript (Angular)

$scope.form = {tags: []};

postalTags = [
  {
    id: 1,
    text: 'Permanent Address'
  },
  {
    id: 2,
    text: 'Present Address'
  }
];

$scope.modal {
  tags: {
    'data': postalTags,
    'multiple': true
  }
};

// I doubt this is going to work, since i think this is only going to 
// listen on events emitted by $emit and $broadcast.
$scope.$on('select2-removed', function(event) {
    console.log(event);
});

// I can do this, but then i will not know which was removed and added
$scope.$watch('form.tags', function(data) {
  console.log(data);
});

What the user actually is doing here is edit the tags tagged to his/her address, and by edit I mean the user can tag new tags to his/her address or remove previously tagged tags. That's why I need to track which tags where added and which are removed.

UPDATE

I saw a plausible solution on this discussion, but i cant make the provided code to work with mine, so i did some workaround, and this is what i did.

so instead of adding the,

scope.$emit('select2:change', a);

somewhere around here,

elm.select2(opts);

// Set initial value - I'm not sure about this but it seems to need to be there
elm.val(controller.$viewValue)

I put it here,

 if (!isSelect) {
        // Set the view and model value and update the angular template manually for the ajax/multiple select2.
        elm.bind("change", function (e) {

          // custom added.
          scope.$emit('select2:change', e);

          e.stopImmediatePropagation();

then i did the usual on my controller,

$scope.$on('select2:change', function(event, element) {
  if(element.added) console.log(element.added);
  if(element.removed) console.log(element.removed);
}

and works just fine.

But i doubt this is very good idea, and i'm still hoping for a better solution.

Community
  • 1
  • 1
cj cabero
  • 383
  • 10
  • 23
  • 1
    Have a look at the answers http://stackoverflow.com/questions/18968376 – apairet Aug 18 '14 at 07:35
  • Other discussions took place here: http://stackoverflow.com/questions/15622522 – apairet Aug 18 '14 at 07:36
  • @apairet Yeah, already saw those two and the first one really was helpful but it involves me modifying a third party code, which as far as best practices is concern that's not really a good idea. I was hoping for another way. But currently that's what I did to resolve my problem, though just a little bit different, I cant make the given code on the first thread work, so i tried differently, I guess i have to update my question with the plausible solution. Since I'm still hoping for a better solution. – cj cabero Aug 18 '14 at 08:10

1 Answers1

0

I used a directive to encapsulate the select and then in the link function I just retrieve the select element and at the event handler.

Markup:

<select name="id" data-ng-model="tagsSelection" ui-select2="select2Options">
    <option value="{{user.id}}" data-ng-repeat="user in users">{{user.name}}</option>
</select>

Javascript:

link: function (scope, element, attributes) {
    var select = element.find('select')[0];
    $(select).on("change", function(evt) {
        if (evt.added) {
            // Do something
        } else if (evt.removed) {
            // Do something.
        }
    });

    $scope.select2Options = {
        multiple: true
    }
}
tazmaniax
  • 406
  • 1
  • 6
  • 13