7

I'm trying to place a button into select2 result items (for allowing the user to remove items). I managed to place the buttons, but I didn't manage to handle their click event yet. Somehow the event doesn't get raised. I think it's something like select2 is closing the dropdown before my button's click event would raise, but cannot figure out how I could make it work.

Here is the snippet what I have now.

...    
formatResult: function (item) {
    return item.text + "<button class='btn btn-xs btn-default pull-right select2-result-button' data-id='" + item.id + "'>&times;</button>";
}
...
$(document).on("click", ".select2-result-button", function (e) {
    alert("clicked: " + $(this).data("id"));
    e.preventDefault();
    e.stopPropagation();
    return false;
});

Here is a demo fiddle. I've also tried the mousedown event without success.

Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93
  • An aside, but in your click handler, `return false` is equivalent to `e.preventDefault(); e.stopPropagation()`. – joews Sep 15 '14 at 12:44
  • Yes I know that, I was just so confused that I wanted to be sure I try everything :) – Zoltán Tamási Sep 15 '14 at 13:00
  • But actually when I debugged into the code I realized that the handler doesn't even get called, so it's not realted to how I prevent or not prevent it from bubbling. – Zoltán Tamási Sep 15 '14 at 13:03
  • I would guess it is because the element seizes to exist after selection. I looked at the html while open (the 2 buttons are there) and after selection and the 2 buttons disappear! – hahaha Sep 15 '14 at 13:10
  • @Alexandros Yes, that's right and that is by design, because the drop down (and its content) is created on open, and destroyed on close. The problem seems to be that I'm unable to catch the click on my button before select2 would process the click and close the dropdown. – Zoltán Tamási Sep 15 '14 at 13:15
  • @ZoltánTamási shouldn't the `e.preventDefault(); e.stopPropagation(); return false;` etc be on the ` – hahaha Sep 15 '14 at 13:17
  • 2
    You should have a look to this answer : http://stackoverflow.com/a/15637696/1127669. `select2` prevents any click event on the popover list. But you can redefine the `onSelect` event like this : http://jsfiddle.net/qouo8uog/33/. – Samuel Caillerie Sep 15 '14 at 13:18
  • @SamuelCaillerie Thank you, that actually seems to do the job. I'm gonna try to put together a generic solution (adding some options like "customItemButtons" or so) based on that. If you form an answer from your comment, I'll accept it. – Zoltán Tamási Sep 15 '14 at 13:44

3 Answers3

4

You should have a look to this answer : stackoverflow.com/a/15637696/1127669 : the select2 library prevents any click event on the popover list.

But you can redefine the onSelect event like this : jsfiddle.net/qouo8uog/33.

s2list.onSelect = (function (fn) {
    return function (data, options) {
        var target;

        if (options != null) {
            target = $(options.target);
        }

        // In case where the target is your own button, handle it
        if (target && target.hasClass('select2-result-button')) {
            alert("clicked: " + $(target).data("id"));
        } else {
            return fn.apply(this, arguments);
        }
    }
})(s2list.onSelect);
Community
  • 1
  • 1
Samuel Caillerie
  • 8,259
  • 1
  • 27
  • 33
0

At the end of the day I decided to patch the select2 source code instead of hacking the options. Probably it would be worth a pull request on the github project, but currently I have no time to prepare it.

In both of the onSelect implementations (single and multi) I've placed this code in the front.

onSelect: function (data, options) {

      // @@ implement a way to be able to place buttons in results
      // this will check if there is an event target (in case when selection is invoked by mouse/touch), and if the target is a result button, trigger the result button event on the element, and skip default selecting behaviour
      if (options && options.target && $(options.target).hasClass('select2-result-button')) {
        var evt = $.Event("select2-result-button-click", { choice: data, button: options.target });
        this.opts.element.trigger(evt);
        return;
      }
      ...
}
Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93
0

Just add

closeOnSelect: false

The button will works.