web-dev-qa-db-fra.com

Attachez un événement de clic à un élément de .select2-result

Je cherche un moyen de joindre un événement de clic à un élément select2-result-... J'ai formaté à la fois le résultat et la sélection via

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

pour ajouter un "info" -icon J'essaie maintenant d'attacher un simple événement click à l'élément .info mais je n'arrive pas à le faire fonctionner:

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

Toute aide? Quelqu'un avec un problème similaire? Est-ce possible?

J'ai préparé un jsFiddle sur: http://jsfiddle.net/s2dqh/3/

25
brckmann

Comme Select2 lib empêche tout événement de clic sur la liste déroulante, vous ne pouvez pas lier directement les événements à .info. Mais vous pouvez redéfinir la méthode onSelect et y placer le code de votre choix.

Voir exemple: http://jsfiddle.net/f8q2by55/

Mise à jour pour sélections multiples: http://jsfiddle.net/6jaodjzq/

34
ant_Ti

Le concept est similaire à celui de netme, mais l'événement select2 est incorrect (peut-être une différence de version) et vous devez utiliser stopPropagation pour empêcher la sélection d'un élément:

http://jsfiddle.net/ZhfMg/

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

Si utilisé avec x-editable. Ce que cela fait, c’est quand x-editable passe en mode édition (événement affiché), c’est quand un select2 existe et que vous pouvez le connecter à sa fonction ouverte.

$('#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');
        }); 
    });
});
9
AaronLS

Pour les versions de Select2 antérieures à la version 4.0.0 (versions 3.5.x et antérieures), vous devez vous référer à cette réponse à propos de la liaison à onSelect .

Dans les versions plus récentes de Select2, les événements ne sont plus supprimés dans les résultats. Par conséquent, vous pouvez simplement vous lier aux événements mouseupmousedown comme vous le feriez normalement. Vous devriez éviter de vous lier à l'événement click} _ par défaut, les navigateurs ne le déclencheront pas.

$(".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>

Dans cet exemple, nous arrêtons la propagation de l'événement mouseup afin que le navigateur déclenche l'événement click. Si vous ne travaillez pas avec des liens réels, mais que vous devez capturer un événement click, vous devez simplement vous connecter à l'événement mouseup.

7
Kevin Brown

Aucune des réponses ci-dessus n'a fonctionné pour moi pour select2 4.0.0, alors voici ce que j'ai fini par faire:

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

Plus précisément, je voulais agir uniquement sur l'élément précédemment sélectionné:

$(document).on('mouseup', '.select2-container--open .select2-results__option[aria-selected=true]', function (e) {
    // Do something on the previously-selected item
}
3
Aegix

Ajoutez simplement un auditeur 'open' et configurez un autre auditeur 'mouseup' pour le tag ''

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

Voici le lien vers ma solution: http://jsfiddle.net/EW8t7/

2
Mikhail Chernykh

Une approche plus simple selon les docs. 

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

Surpris de ne voir aucune réponse à cela. 

2
kushalvm

Je pense que la gestion de l'événement mouseup par Select2 empêche l'élément .info d'obtenir un événement click. Avoir l'élément .info capturer l'événement mouseup et l'empêcher de se propager semble résoudre ce problème.

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');
        });
}

Cela peut également être fait pour prendre en charge un lien dans l'élément sélectionné, mais c'est l'événement mousedown qui doit être capturé.

jsfiddle

1
John S

Je viens de rencontrer ce problème avec select2 v4.0.3 et d’utiliser l’événement 'select2: select'. Voici essentiellement comment je l'ai fait:

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)
  });
});

0
etipton

la chose semble être que le tgas sera supprimé juste après la fermeture de la boîte. Par conséquent, l'événement click ne peut pas être déclenché.

J'ai changé quelques choses + l'événement qui sera écouté. C'est maintenant un 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>

0
Christian

Vous devez dissocier l'événement mouseup de l'élément .select2-results__options. Je le fais dans ma fonction templateResult:

function templateResult(location) {

    var $location = $([html with links]);

    $('.select2-results__options').unbind('mouseup');

    return $location;
}

Si vous souhaitez conserver le comportement par défaut de select2 consistant à sélectionner l'option et à fermer le menu déroulant, vous devez déclencher manuellement ces événements:

$('.select2-results__options').unbind('mouseup');

$('a', $location).on('click', function (e) {
    $('#locations_dropdown').select2('val', location.id);
    $('#locations_dropdown').select2('close');
});

return $location;
0
Jeffrey Barrett