Jquery Chosen plugin - dynamically populate list by Ajax

后端 未结 12 1024
野性不改
野性不改 2020-12-04 11:14

Im trying to build my dropdown menu using the plugin Chosen for Multiple Select . Here\'s to behavior I\'m based on:

http://jsfiddle.net/JfLvA/

相关标签:
12条回答
  • 2020-12-04 11:48

    The chosen answer is outdated, same goes to meltingice /ajax-chosen plugin.

    With Select2 plugin got many bugs which is i can't resolve it.

    Here my answer for this question.

    I integrated my solution with function trigger after user type. Thanks to this answer : 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");
    
      });
    
    0 讨论(0)
  • 2020-12-04 11:54

    The Chosen plugin does not automatically update its list of options when the OPTION elements in the DOM change. You have to send it an event to trigger the update:

    Pre Chosen 1.0: $('.chzn-select').trigger("liszt:updated");

    Chosen 1.0 $('.chosen-select').trigger("chosen:updated");

    If you are dynamically managing the OPTION elements, then you'll have to do this whenever the OPTIONs change. The way you do this will vary - in AngularJS, try something like this:

    $scope.$watch(
      function() {
        return element.find('option').map(function() { return this.value }).get().join();
      }, 
      function() {
        element.trigger('liszt:updated');
      }
     }
    
    0 讨论(0)
  • 2020-12-04 11:54

    Chosen API has changed a lot.

    If non of the solution given works for you, you can try this one: https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify

    Here is the function:

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

    Here is your HTML:

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

    And here is your 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=');
    

    For more information, please refer to https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify#how-to-use

    0 讨论(0)
  • 2020-12-04 11:56

    If you have two or more selects and use Steve McLenithan's answer, try to replace the first line with:

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

    not remove suffix: _chosen

    0 讨论(0)
  • 2020-12-04 11:59

    The solution of @Ashivad mostly fixed my problem, but I needed to make this one-line addition to prevent the input to be erased after the results dropdown is displayed:

    in success callback of the autocomplete added this line after triggering chosen:updated:

    $combosearchChosen.find('input').val(request.term);
    

    Complete listing:

    var $combosearch = $('[data-combosearch]');
    if (!$combosearch.length) {
      return;
    }
    
    var options = $combosearch.data('options');
    console.log('combosearch', $combosearch, options);
    
    $combosearch.chosen({
      no_results_text: "Oops, nothing found!",
      width: "60%"
    });
    
    // actual chosen container
    var $combosearchChosen = $combosearch.next();
    
    $combosearchChosen.find('input').autocomplete({
      source: function( request, response ) {
        $.ajax({
          url: options.remote_source + "&query=" + request.term,
          dataType: "json",
          beforeSend: function(){
            $('ul.chosen-results').empty();
          },
          success: function( data ) {
            response( $.map( data, function( item, index ) {
              $combosearch.append('<option value="' + item.id + '">' + item.label + '</option>');
            }));
            $combosearch.trigger('chosen:updated');
            $combosearchChosen.find('input').val(request.term);
          }
        });
      }
    });
    
    0 讨论(0)
  • 2020-12-04 12:01

    You can dynamically populate a list via AJAX using the excellent Select2 plugin. From my answer to "Is there a way to dynamically ajax add elements through jquery chosen plugin?":

    Take a look at the neat Select2 plugin, which is based on Chosen itself and supports remote data sources (aka AJAX data) and infinite scrolling.

    0 讨论(0)
提交回复
热议问题