web-dev-qa-db-fra.com

Jquery Chosen plugin - liste dynamique créée par Ajax

J'essaie de construire mon menu déroulant en utilisant le plugin Choisi pour Sélection multiple . Voici le comportement sur lequel je suis basé:

http://jsfiddle.net/JfLvA/

Donc, au lieu d’avoir 3 <option> harcodées dans ma sélection. Je veux que cette liste soit les valeurs d'un tableau json rempli par une requête ajax. Cela sera déclenché par autocomplete.

Donc, si l’utilisateur tape "car", envoie la lettre via un appel ajax et récupère un tableau comme celui-ci:

[{"id": "2489", "name": "carrie"}, {"id": "2490", "name": "Caroline"}, {"id": "2491", "name": "Carole"}]

Le code:

$(function() {

$(".chzn-select").chosen();
$(".chzn-select-deselect").chosen({allow_single_deselect:true});

$('.chzn-choices input').autocomplete({
   source: function( request, response ) {
      $.ajax({
          url: "/change/name/autocomplete/"+request.term+"/",
          dataType: "json",
          success: function( data ) {
             response( $.map( data, function( item ) {
                $('ul.chzn-results').append('<li class="active-result">' + item.name + '</li>');

          }
       });
    }
});

Résultat:

Je tape "voiture", dans la liste déroulante, je reçois "Aucun résultat pour voiture", puis j'ai tous mes résultats, comme je le souhaite.

1. Pourquoi je reçois le message "Aucun résultat", car je peux voir dans mon tableau JSON et dans ma liste que les résultats me parviennent.

 -----------------------------

Quand je supprime "voiture" et entre "sam". Les résultats pour "sam" sont affichés après les résultats "voiture". (En gros, je vois le résultat pour les deux, au lieu d’avoir le résultat de ma recherche actuelle)

2. Je suppose que je dois effacer le ul sur keyUp? Je pensais que le plugin le faisait déjà

 -----------------------------

Lorsque je clique sur un nom pour le sélectionner et l'ajouter à la sélection, je reçois une erreur javascript dans le fichier Choisi.js

l'article n'est pas défini
"item.selected = true;" ligne 732

le lien vers le plugin: http://harvesthq.github.com/chosen/chosen/chosen.jquery.js

et il n’ajoute rien dans la sélection.

3. Aucune idée pourquoi cela se produit

 -----------------------------

Avez-vous une idée sur ce que je suis en train de faire quelque chose de mal? Je suis complètement coincé ici ...!

Oh et au fait, cela ne me dérange pas de changer la source du plugin, car c'est le seul endroit où je l'utilise ...

37
Lelly

essaye ça:

$('.chzn-choices input').autocomplete({
  source: function( request, response ) {
    $.ajax({
      url: "/change/name/autocomplete/"+request.term+"/",
      dataType: "json",
      beforeSend: function(){$('ul.chzn-results').empty();},
      success: function( data ) {
        response( $.map( data, function( item ) {
          $('ul.chzn-results').append('<li class="active-result">' + item.name + '</li>');
        }));
      }
    });
  }
});
27
Ashirvad

Vous pouvez remplir dynamiquement une liste via AJAX en utilisant l'excellent plug-in Select2. De ma réponse à "Est-il possible d'ajaxer dynamiquement l'ajout d'éléments par le biais du plugin jQuery choisi?" :

Jetez un coup d'oeil au plugin soigné Select2, qui est basé sur Choisi et supporte des sources de données distantes (alias AJAX données) et un défilement infini.

46
Vicky Chijwani

La réponse d'Ashirvad ne fonctionne plus. Notez les changements de nom de classe et utilisez l'option option au lieu de l'élément li . J'ai mis à jour ma réponse pour ne pas utiliser l'événement "success" déconseillé, optant pour .done ()

$('.chosen-search input').autocomplete({
    minLength: 3,
    source: function( request, response ) {
        $.ajax({
            url: "/some/autocomplete/url/"+request.term,
            dataType: "json",
            beforeSend: function(){ $('ul.chosen-results').empty(); $("#CHOSEN_INPUT_FIELDID").empty(); }
        }).done(function( data ) {
                response( $.map( data, function( item ) {
                    $('#CHOSEN_INPUT_FIELDID').append('<option value="blah">' + item.name + '</option>');
                }));

               $("#CHOSEN_INPUT_FIELDID").trigger("chosen:updated");
        });
    }
});
20

Cela pourrait être utile. Vous devez simplement déclencher un événement.

$("#DropDownID").trigger("liszt:updated");

Où "DropDownID" est l'ID de <select>.

Plus d'infos ici: http://harvesthq.github.com/chosen/

11
Nishant Joshi

La réponse choisie est obsolète, il en va de même pour le plugin meltingice/ajax-choisi.

Avec Select2, le plugin a eu beaucoup de bogues, ce qui est impossible à résoudre.

Voici ma réponse à cette question.

J'ai intégré ma solution avec la fonction trigger après le type d'utilisateur . Merci à cette réponse: https://stackoverflow.com/a/5926782/4319179 .

//setup before functions
  var typingTimer;                //timer identifier
  var doneTypingInterval = 2000;  //time in ms (2 seconds)
  var selectID = 'YourSelectId';    //Hold select id
  var selectData = [];           // data for unique id array

  //on keyup, start the countdown
  $('#' + selectID + '_chosen .chosen-choices input').keyup(function(){

      // Change No Result Match text to Searching.
      $('#' + selectID + '_chosen .no-results').html('Searching = "'+ $('#' + selectID + '_chosen .chosen-choices input').val() + '"');


      clearTimeout(typingTimer);  //Refresh Timer on keyup 
      if ($('#' + selectID + '_chosen .chosen-choices input').val()) {

           typingTimer = setTimeout(doneTyping, doneTypingInterval);  //Set timer back if got value on input

      }

  });

  //user is "finished typing," do something
  function doneTyping () {

      var inputData = $('#' + selectID + '_chosen .chosen-choices input').val();  //get input data

      $.ajax({
        url: "YourUrl",
         data: {data: inputData},
        type:'POST',
        dataType: "json",
        beforeSend: function(){
          // Change No Result Match to Getting Data beforesend
          $('#' + selectID + '_chosen .no-results').html('Getting Data = "'+$('#' + selectID + '_chosen .chosen-choices input').val()+'"');
    },
        success: function( data ) { 

          // iterate data before append
          $.map( data, function( item ) {

            // matching data eg: by id or something unique; if data match: <option> not append - else: append <option>
            // This will prevent from select the same thing twice.
            if($.inArray(item.attr_hash,selectData) == -1){

              // if not match then append in select
              $('#' + selectID ).append('<option id="'+item.id+'" data-id = "'+item.id+'">' + item.data + '</option>');

            }            

          });

          // Update chosen again after append <option>
          $('#' + selectID ).trigger("chosen:updated");

        }
      });

  }

  // Chosen event listen on input change eg: after select data / deselect this function will be trigger
  $('#' + selectID ).on('change', function() {

    // get select jquery object
    var domArray = $('#' + selectID ).find('option:selected');

    // empty array data
    selectData = [];

    for (var i = 0, length = domArray.length; i < length; i++ ){

      // Push unique data to array (for matching purpose)
      selectData.Push( $(domArray[i]).data('id') );

    }

    // Replace select <option> to only selected option
    $('#' + selectID ).html(domArray);

    // Update chosen again after replace selected <option>
    $('#' + selectID ).trigger("chosen:updated");

  });
5
Afiq Abdullah

Comme Vicky l'a suggéré, Select2 est livré avec les fonctionnalités AJAX intégrées et ressemble à un excellent plugin. 

Si vous ne voulez pas changer de choix, essayez AJAX-Chosen https://github.com/meltingice/ajax-chosen

1
Deepak Thomas

L'API choisie a beaucoup changé.

Si aucune des solutions proposées ne vous convient, vous pouvez essayer celle-ci: https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify

Voici la fonction:

// USAGE:
// $('#some_input_id').chosen();
// chosen_ajaxify('some_input_id', 'http://some_url.com/contain/');

// REQUEST WILL BE SENT TO THIS URL: http://some_url.com/contain/some_term

// AND THE EXPECTED RESULT (WHICH IS GOING TO BE POPULATED IN CHOSEN) IS IN JSON FORMAT
// CONTAINING AN ARRAY WHICH EACH ELEMENT HAS "value" AND "caption" KEY. EX:
// [{"value":"1", "caption":"Go Frendi Gunawan"}, {"value":"2", "caption":"Kira Yamato"}]

function chosen_ajaxify(id, ajax_url){
    console.log($('.chosen-search input').autocomplete);
    $('div#' + id + '_chosen .chosen-search input').keyup(function(){
        var keyword = $(this).val();
        var keyword_pattern = new RegExp(keyword, 'gi');
        $('div#' + id + '_chosen ul.chosen-results').empty();
        $("#"+id).empty();
        $.ajax({
            url: ajax_url + keyword,
            dataType: "json",
            success: function(response){
                // map, just as in functional programming :). Other way to say "foreach"
                $.map(response, function(item){
                    $('#'+id).append('<option value="' + item.value + '">' + item.caption + '</option>');
                });
                $("#"+id).trigger("chosen:updated");
                $('div#' + id + '_chosen').removeClass('chosen-container-single-nosearch');
                $('div#' + id + '_chosen .chosen-search input').val(keyword);
                $('div#' + id + '_chosen .chosen-search input').removeAttr('readonly');
                $('div#' + id + '_chosen .chosen-search input').focus();
                // put that underscores
                $('div#' + id + '_chosen .active-result').each(function(){
                    var html = $(this).html();
                    $(this).html(html.replace(keyword_pattern, function(matched){
                        return '<em>' + matched + '</em>';
                    }));
                });
            }
        });
    });
}

Voici votre HTML:

<select id="ajax_select"></select>

Et voici votre javasscript:

// This is also how you usually use chosen
$('#ajax_select').chosen({allow_single_deselect:true, width:"200px", search_contains: true});
// And this one is how you add AJAX capability
chosen_ajaxify('ajax_select', 'server.php?keyword=');

Pour plus d'informations, veuillez consulter https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify#how-to-use

1
goFrendiAsgard
var object = $("#lstValue_chosen").find('.chosen-choices').find('input[type="text"]')[0];
var _KeyCode = event.which || event.keyCode;
if (_KeyCode != 37 && _KeyCode != 38 && _KeyCode != 39 && _KeyCode != 40) { 

    if (object.value != "") {
        var SelectedObjvalue = object.value;
        if (SelectedObjvalue.length > 0) {
            var obj = { value: SelectedObjvalue };
            var SelectedListValue = $('#lstValue').val();
            var Uniqueid = $('#uniqueid').val();

            $.ajax({
                url: '/Admin/GetUserListBox?SelectedValue=' + SelectedListValue + '&Uniqueid=' + Uniqueid,
                data: { value: SelectedObjvalue },
                type: 'GET',
                async: false,
                success: function (response) {
                    if (response.length > 0) {
                        $('#lstValue').html('');
                        var options = '';                            
                        $.each(response, function (i, obj) {
                            options += '<option value="' + obj.Value + '">' + obj.Text + '</option>';
                        });
                        $('#lstValue').append(options);
                        $('#lstValue').val(SelectedListValue);
                        $('#lstValue').trigger("chosen:updated");
                        object.value = SelectedObjvalue;
                    }
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    //jAlert("Error. Please, check the data.", " Deactivate User");
                    alert(error.StatusText);
                }
            });
        }
    }
}
0
Pandian

Si vous avez deux sélections ou plus et utilisez la réponse de Steve McLenithan, essayez de remplacer la première ligne par:

$('#CHOSENINPUTFIELDID_chosen > div > div input').autocomplete({

pas supprimer le suffixe: _chosen

0
user2213831