Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attach click-event to element in .select2-result

I'm looking for a way to attach a click-event to a select2-result-item. I've gone ahead and formatted both result and selection via

function format(state) {
    if (!state.id) return state.text; // optgroup
    return state.text + " <i class='info'>link</i>";
}

to add an "info"-icon I'm now trying to attach a simple click-event to the .info-element but can't get this to work:

$('.info').on('click', function(event){
    event.preventDefault();
    alert("CLICK");
    $('#log').text( "clicked" );
});

Any help? Anyone with a similar problem? Is this possible at all?

I prepared a jsFiddle at: http://jsfiddle.net/s2dqh/3/

like image 654
brckmann Avatar asked Mar 26 '13 11:03

brckmann


10 Answers

Because Select2 lib prevent any click events on popover list you can't bind events to .info directly. But you can redefine onSelect method and place there any code you want.

See example: http://jsfiddle.net/f8q2by55/

Update for multiple selects: http://jsfiddle.net/6jaodjzq/

like image 78
ant_Ti Avatar answered Oct 08 '22 13:10

ant_Ti


This is similar in concept to netme's but the select2 event is wrong(maybe version difference), and you need to use stopPropagation to prevent item from being selected:

http://jsfiddle.net/ZhfMg/

$('#mySelect2').on('select2-open', function() { 
    $('.select2-results .info').on('mouseup', function(e) { 
        e.stopPropagation();
        console.log('clicked');
    }); 
});

If used with x-editable. What this does is when the x-editable goes into edit mode(shown event), that's when a select2 exists and you can wire to it's open function.

$('#myXEditable').on('shown', function () {
    $(this).data('editable').input.$input.on('select2-open', function() { 
        $('.select2-results .info').on('mouseup', function(e) { 
            e.stopPropagation();
            console.log('clicked');
        }); 
    });
});
like image 29
AaronLS Avatar answered Oct 08 '22 14:10

AaronLS


For versions of Select2 before 4.0.0 (so 3.5.x and below), you should refer to this answer about binding to onSelect.

In newer versions of Select2, events are no longer killed within the results so you can just bind to the mouseup/mousedown events like you normally would. You should avoid binding to the click event because by default browsers will not trigger it.

$(".select2").select2({
  templateResult: function (data) {
    if (data.id == null) {
      return data.text;
    }
    
    var $option = $("<spam></span>");
    var $preview = $("<a target='_blank'> (preview)</a>");
    $preview.prop("href", data.id);
    $preview.on('mouseup', function (evt) {
      // Select2 will remove the dropdown on `mouseup`, which will prevent any `click` events from being triggered
      // So we need to block the propagation of the `mouseup` event
      evt.stopPropagation();
    });
    
    $preview.on('click', function (evt) {
      console.log('the link was clicked');
    });
    
    $option.text(data.text);
    $option.append($preview);
    
    return $option;
  }
});
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>

<select class="select2" style="width: 200px;">
  <option value="https://google.com">Google</option>
  <option value="https://mail.google.com">GMail</option>
</select>

In this example we stop the propagation of the mouseup event so the browser will trigger the click event. If you are not working with actual links, but instead need to just catch a click event, you should just hook into the mouseup event.

like image 21
Kevin Brown-Silva Avatar answered Oct 08 '22 13:10

Kevin Brown-Silva


use default select2select event trigger instead of using other jquery events

$('#mySelect2').on('select2:select', function (e) {
    var data = e.params.data;
    console.log(data);
});

for more details refer below link https://select2.org/programmatic-control/events

like image 40
Balakrishnan Bsk Avatar answered Oct 08 '22 15:10

Balakrishnan Bsk


None of the answers above worked for me for select2 4.0.0, so here's what I ended up doing:

$(document).on('mouseup', '.select2-container--open .select2-results__option', function (e) {
    // Act on the element
}

Specifically, I wanted to only act on the previously-selected item:

$(document).on('mouseup', '.select2-container--open .select2-results__option[aria-selected=true]', function (e) {
    // Do something on the previously-selected item
}
like image 27
Aegix Avatar answered Oct 08 '22 13:10

Aegix


A simpler approach according to docs.

$('#mySelect2').on('select2:select', function (e) {
    var data = e.params.data;
    console.log(data);
});

Surprised not to see any answer for this.

like image 32
HalfWebDev Avatar answered Oct 08 '22 14:10

HalfWebDev


I think Select2's handling of the mouseup event prevents the .info element from getting a click event. Having the .info element capture the mouseup event and prevent it from propagating seems to fix that.

function format(state, container) {
    if (!state.id) return state.text; // optgroup
    container.append(state.text);
    $('<i class="info">link</i>')
        .appendTo(container)
        .mouseup(function(e) {
            e.stopPropagation();            
        })
        .click(function(e) {
            e.preventDefault();
            alert('CLICK');
        });
}

This can also be done to support a link in the selected item, but there it is the mousedown event that needs to be captured.

jsfiddle

like image 44
John S Avatar answered Oct 08 '22 13:10

John S


Just add 'open' listener and set up another 'mouseup' listener for the '' tag:

$("#select").on('open', function() { 
    $('.select2-results i').on('mouseup', function() { 
       alert('aaa');
    }); 
});

Here is the link to my solution: http://jsfiddle.net/EW8t7/

like image 29
Mikhail Chernykh Avatar answered Oct 08 '22 15:10

Mikhail Chernykh


the thing seems to be that the tgas will be deleted right after the box is closed. Therefore the click event cannot be fired.

I've changed a few things + the event that will be listened on. It's now a mousedown...

function format(state) {
    if (!state.id) return state.text; // optgroup
    return state.text + " <a class='info'>link</a>";
}

$("select").select2({
    formatResult: format,
    formatSelection: format,
    escapeMarkup: function(m) { return m; }
}).on('select2-open',function(){
    console.log($('.info'))
    $('.info').on('mousedown', function(event){
        console.log("click")
        $('#log').text( "clicked" );
        event.preventDefault();
    });
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.js"></script>

<select>
  <option>red</option>
  <option>green</option>
  <option>blue</option>
</select>

<div id="log"></div>
like image 23
Christian Avatar answered Oct 08 '22 13:10

Christian


Just ran into this problem with select2 v4.0.3 and ended up using the 'select2:selecting' event. Here's essentially how I did it:

var $select2 = $savedReportsList.select2({ [stuff] });

$select2.on('select2:selecting', function(e) {
  var args = e.params.args;
  if ($(args.originalEvent.target).hasClass('[something]')) {
    if (confirm('Are you sure?')) {
       window.location = '[somewhere]' + '/' + args.data.id;
    }
    return false; // stops propogation (so select2:select never fires)
  });
});
like image 35
etipton Avatar answered Oct 08 '22 15:10

etipton