Jquery Chosen 插件 - 通过 Ajax 动态填充列表
Posted
技术标签:
【中文标题】Jquery Chosen 插件 - 通过 Ajax 动态填充列表【英文标题】:Jquery Chosen plugin - dynamically populate list by Ajax 【发布时间】:2012-08-16 04:14:51 【问题描述】:我正在尝试使用为 Multiple Select 选择的插件构建我的下拉菜单。 这是我基于的行为:
http://jsfiddle.net/JfLvA/
所以,我的选择中没有 3 个硬编码的
所以,如果用户键入“汽车”,我会通过 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>');
);
);
结果:
我在下拉菜单中输入“汽车”,得到“汽车没有结果”,然后我就得到了我想要的所有结果。
1.为什么我会收到“无结果”消息,因为我可以在我的 json 数组和列表中看到我正在获得结果。
-----------------------------
当我删除“car”并输入“sam”时。 “sam”的结果显示在“car”结果之后。 (基本上,我看到了两者的结果,而不仅仅是我当前搜索的结果)
2。我想清除 keyUp 上的 ul 吗?以为插件已经这样做了
-----------------------------
当我单击一个名称以实际选择它并将其添加到选择中时,我在 selected.js 文件中收到一个 javascript 错误
项目未定义 “item.selected =真;”第732行
插件链接: http://harvesthq.github.com/chosen/chosen/chosen.jquery.js
它没有在选择中添加任何内容。
3.不知道为什么会这样
-----------------------------
你们知道我做错了什么吗?我完全被困在这里......!
哦,顺便说一句,我不介意更改插件源,因为它是我唯一使用它的地方......
【问题讨论】:
在追加.try之前如何做 $('ul.chzn-results').empty() 现在它只返回我搜索的词的结果,但它只返回 1 个结果,即使我的数组中有 10 个 我为此找到的解决方案是添加 $('.ui-autocomplete-input').keyup(function() $('.chzn-results').empty(); );但这仅适用于问题 #2 你不应该操纵chzn-choices
。您应该将从服务器获取的 json 项附加到 chzn-select 字段,然后调用 $(".chzn-select").trigger("liszt:updated");
。
$("#form_field").trigger("chosen:updated");用过这个
【参考方案1】:
您可以使用出色的 Select2 插件通过 AJAX 动态填充列表。 From my answer to "Is there a way to dynamically ajax add elements through jquery chosen plugin?":
看看简洁的 Select2 插件,它基于 Chosen 本身并支持远程数据源(也称为 AJAX 数据)和无限滚动。
【讨论】:
在全力以赴之前测试 select2。仍然存在问题。 @Karlth - 请您说明您遇到的一些问题,这样可以节省我的时间,如果我错过了任何情况 优秀? Select2 在 Github 上有 450 多个未解决的问题,基本上被放弃了,更不用说臃肿的大小了.. 远非优秀。此外,这更多的是评论而不是答案,因为它只包含一个链接,也不是答案.. @vsync,这个答案已经超过 3 年了,所以事情自然发生了变化。随意投反对票。另外,我引用了我的链接答案,所以它不仅仅是一个链接。并且链接到解决 OP 问题的库并不违反准则,您不要认真地期望人们实际复制粘贴库的源代码! 过去的时间与这个答案的无关性无关。 OP 专门要求帮助他使用 Chosen 插件,而您只是提供了另一个插件,而没有回答所问的问题。如果您希望提供替代方案,您应该将其作为评论,而不是作为答案,因为它不是一个。【参考方案2】:试试这个:
$('.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>');
));
);
);
【讨论】:
是的,它以干净的方式解决了我的问题 #2。谢谢!现在,您对#3 发生的事情有什么想法吗?插件本身的javascript错误? 嘿,我认为问题不在于插件.. 此处未定义项目。你能告诉你什么时候使用自动完成,什么时候使用选择 什么意思?我在自动完成 $('.chzn-choices input').autocomplete( 上使用选择并且我在 doc ready $(function() $(".chzn-select").chosen(); 我发布我上面的所有代码。 我不明白为什么这是公认的答案。这真的对你有用吗?所选库抛出以下异常“无法调用未定义的方法'lastIndexOf'”。 新版本有一个'chosen-results'类而不是chzn-results【参考方案3】: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");
);
);
【讨论】:
$("#CHOSEN_INPUT_FIELDID")
- 这是什么字段?我没有带有 ID 的输入字段
这是您选择使用的select
元素的ID。例如,$("#CHOSEN_INPUT_FIELDID").chosen(...)
。至少从这段代码看是这样的。【参考方案4】:
这可能会有所帮助。你只需要触发一个事件。
$("#DropDownID").trigger("liszt:updated");
其中“DropDownID”是<select>
的ID。
更多信息在这里: http://harvesthq.github.com/chosen/
【讨论】:
这个帮助了我。谢谢! 这比顶部的一些解决方案效果更好【参考方案5】:当 DOM 中的 OPTION 元素发生变化时,Chosen 插件不会自动更新其选项列表。你必须向它发送一个事件来触发更新:
预选 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');
【讨论】:
嗨,我目前遇到了这个问题,正在使用 Angular。我尝试了您的解决方案,但无法使其正常工作。 PS:你忘记了手表的结束标签【参考方案6】:选择的答案已经过时,meltice /ajax-chosen 插件也是如此。
使用 Select2 插件有很多我无法解决的错误。
这是我对这个问题的回答。
我在用户输入后将我的解决方案与函数触发器集成在一起。 感谢这个答案:https://***.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");
);
【讨论】:
【参考方案7】:就像 Vicky 建议的那样,Select2 带有内置的 AJAX 功能,看起来像一个很棒的插件。
如果你不想从 Chosen 切换,试试 AJAX-Chosen https://github.com/meltingice/ajax-chosen
【讨论】:
AJAX-Chosen 不再受到支持。【参考方案8】:选择的 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>
这是你的 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=');
更多信息请参考https://github.com/goFrendiAsgard/gofrendi.chosen.ajaxify#how-to-use
【讨论】:
【参考方案9】:如果您有两个或多个选择并使用 Steve McLenithan 的答案,请尝试将第一行替换为:
$('#CHOSENINPUTFIELDID_chosen > div > div input').autocomplete(
不删除后缀:_chosen
【讨论】:
请在代码前使用4个空格将其格式化为代码。【参考方案10】: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);
);
【讨论】:
【参考方案11】:如果你是从 ajax 生成选择标签,在成功函数中添加这个:
$('.chosen').chosen();
或者,如果您在单击添加更多按钮时生成选择标签,则添加:
$('.chosen').chosen();
在函数内部。
【讨论】:
【参考方案12】:@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);
);
);
【讨论】:
以上是关于Jquery Chosen 插件 - 通过 Ajax 动态填充列表的主要内容,如果未能解决你的问题,请参考以下文章