Javascript Jquery 选择插件 - 通过 Ajax 动态填充列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12044330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:58:42  来源:igfitidea点击:

Jquery Chosen plugin - dynamically populate list by Ajax

javascriptjqueryjquery-pluginsjquery-chosen

提问by Lelly

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

我正在尝试使用为Multiple Select 选择的插件构建我的下拉菜单。这是我基于的行为:

http://jsfiddle.net/JfLvA/

http://jsfiddle.net/JfLvA/

So, instead of having 3 harcoded < option > in my select. I want this list to be the values of a json array populated by an ajax request. This will be triggered by autocomplete.

所以,我的选择中没有 3 个硬编码的 <option>。我希望这个列表是由 ajax 请求填充的 json 数组的值。这将由自动完成触发。

So, if the user type "car", im sending the letter via an ajax call, and im getting back an array like that:

因此,如果用户输入“car”,我会通过 ajax 调用发送信件,然后我会返回一个这样的数组:

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

[{"id":"2489","name":"carrie"},{"id":"2490","name":"Caroline"},{"id":"2491","name": “卡罗尔”}]

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

          }
       });
    }
});

Result:

结果:

I type "car", in the dropdown Im getting "No result for car" and then I have all my results, as I want.

我输入“汽车”,在下拉菜单中我得到“汽车没有结果”,然后我得到了我想要的所有结果。

1. Why I'm I getting the "No result" message, cause I can see in my json array and inside my list that I'm getting results.

1. 为什么我收到“无结果”消息,因为我可以在我的 json 数组和我的列表中看到我得到了结果。

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

When I delete "car" and enter "sam". The results for "sam" are showing after the "car" results. (Basically, I see the result for both, instead of just having the result of my current search)

当我删除“汽车”并输入“山姆”时。“sam”的结果显示在“car”结果之后。(基本上,我看到了两者的结果,而不仅仅是我当前搜索的结果)

2. Im I suppose to clear the ul on keyUp?? Thought the plugin was doing that already

2.我想清除keyUp上的ul??以为插件已经这样做了

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

When I click on a name to actually select it and add it into the select, Im getting a javascript error inside the chosen.js file

当我单击一个名称以实际选择它并将其添加到选择中时,我在 selected.js 文件中收到了一个 javascript 错误

item is undefined
"item.selected = true;" line 732

项目未定义
“item.selected = true;” 第 732 行

the link to the plugin: http://harvesthq.github.com/chosen/chosen/chosen.jquery.js

插件链接:http: //harvesthq.github.com/chosen/chosen/chosen.jquery.js

and it's not adding anything inside the select.

它没有在选择中添加任何内容。

3. No idea why this is happening

3. 不知道为什么会这样

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

Do you guys have any idea on what I'm I doing something wrong? I'm completly stuck here...!

你们知道我做错了什么吗?我完全被困在这里......!

Oh and by the way, I dont mind changing the plugin source, as it's the only place where I'm using it....

哦,顺便说一句,我不介意更改插件源,因为它是我使用它的唯一地方....

采纳答案by Ashirvad

try this:

尝试这个:

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

回答by Vicky Chijwani

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

您可以使用优秀的Select2插件通过 AJAX 动态填充列表。从我对“有没有办法通过 jquery 选择的插件动态 ajax 添加元素?”的回答

Take a look at the neat Select2plugin, which is based on Chosenitself and supports remote data sources (aka AJAX data) and infinite scrolling.

看看整洁的Select2插件,它基于Chosen本身并支持远程数据源(又名 AJAX 数据)和无限滚动

回答by Steve McLenithan

Ashirvad's answer no longer works. Note the class name changes and using the optionelement instead of the lielement. I've updated my answer to not use the deprecated "success" event, instead opting for .done():

Ashirvad 的回答不再有效。请注意类名更改并使用option元素而不是li元素。我已经更新了我的答案,不使用已弃用的“成功”事件,而是选择 .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");
        });
    }
});

回答by Nishant Joshi

This might be helpful. You have to just trigger an event.

这可能会有所帮助。你只需要触发一个事件。

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

Where "DropDownID" is ID of <select>.

其中“DropDownID”是<select>.

More info here: http://harvesthq.github.com/chosen/

更多信息在这里:http: //harvesthq.github.com/chosen/

回答by Luke Stone

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:

当 DOM 中的 OPTION 元素更改时,Chosen 插件不会自动更新其选项列表。你必须向它发送一个事件来触发更新:

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

预选 1.0: $('.chzn-select').trigger("liszt:updated");

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

选择 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:

如果您正在动态管理 OPTION 元素,那么无论何时 OPTION 更改,您都必须执行此操作。你这样做的方式会有所不同 - 在 AngularJS 中,尝试这样的事情:

$scope.$watch(
  function() {
    return element.find('option').map(function() { return this.value }).get().join();
  }, 
  function() {
    element.trigger('liszt:updated');
  }
 }

回答by Afiq Abdullah

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

选择的答案已过时,同样适用于meltice /ajax-chosen 插件。

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

Select2 插件有很多错误,这是我无法解决的。

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.

我在用户输入后将我的解决方案与功能触发器集成在一起。感谢这个答案: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");

  });

回答by Deepak Thomas

Like Vicky suggested, Select2 comes with the AJAX features inbuilt and looks like a great plugin.

就像 Vicky 建议的那样,Select2 带有内置的 AJAX 功能,看起来像一个很棒的插件。

If you dont want to switch from Chosen, try AJAX-Chosen https://github.com/meltingice/ajax-chosen

如果您不想从 Chosen 切换,请尝试 AJAX-Chosen https://github.com/meltingice/ajax-chosen

回答by goFrendiAsgard

Chosen API has changed a lot.

选择的 API 发生了很大变化。

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

如果给出的解决方案都不适合你,你可以试试这个: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:

这是您的 HTML:

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

And here is your javasscript:

这是你的javascript:

// 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

更多信息请参考https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify#how-to-use

回答by user2213831

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

如果您有两个或多个选择并使用 Steve McLenithan 的答案,请尝试将第一行替换为:

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

not remove suffix: _chosen

不删除后缀: _chosen

回答by Pandian

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