Jquery Selected plugin - 由 Ajax 动态填充列表

Jquery Chosen plugin - dynamically populate list by Ajax

本文关键字:动态 填充 列表 Ajax Selected plugin Jquery      更新时间:2023-09-26

我试图使用插件构建我的下拉菜单 选择多选 .以下是我所基于的行为:

http://jsfiddle.net/JfLvA/

因此,我的选择中没有 3 个 harcoded <选项>。我希望此列表是由 ajax 请求填充的 json 数组的值。这将由自动完成触发。

因此,如果用户键入"car",我通过ajax调用发送信件,然后返回这样的数组:

[{"id":"2489","name":"carrie"},{"id":"2490","name":">

Caroline"},{"id":"2491","name":"Carole"}]

代码:

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

结果:

我输入"car",

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

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

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

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

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

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

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

项未定义
"item.selected = true;" 第 732 行

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

而且它不会在选择中添加任何内容。

3. 不知道为什么会这样

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

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

哦,顺便说一句,

我不介意更改插件源代码,因为它是我使用它的唯一地方......

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

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

试试这个:

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

Ashirvad 的答案不再有效。请注意类名更改并使用选项元素而不是 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");
        });
    }
});

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

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

其中"DropDownID"是<select>的ID。

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

DOM 中的 OPTION 元素更改时,所选插件不会自动更新其选项列表。 您必须向其发送事件才能触发更新:

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

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

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

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

选择的答案已经过时了,同样适用于 meltingice/ajax 选择的插件。

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

这是我对这个问题的回答。

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

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

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

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

如果给出的解决方案不适合您,您可以尝试以下解决方案:https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify

这是函数:

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

这是您的 HTML:

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

这是你的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=');

欲了解更多信息,请参阅 https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify#how-to-use

@Ashivad的解决方案基本上解决了我的问题,但我需要进行这一行添加以防止在显示结果下拉列表后删除输入:

自动完成success回调中,在触发chosen:updated后添加了以下行:

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

完整列表:

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

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

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

不删除后缀:_chosen

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

如果要从 ajax 生成选择标记,请在成功函数中添加以下内容:

$('.chosen').chosen();

或者,如果您在单击添加更多按钮时生成选择标签,则添加:

$('.chosen').chosen();

在函数内。