我正在使用jQuery UI的自动完成功能与可能创建的功能略有不同。
基本上我想保留所有相同的功能,唯一的区别是当出现意见框时,我没有在用户做出选择时隐藏的建议框,我也不希望选择填充.autocomplete附加到的输入框。
所以,我一直在阅读jQuery UI文档,看来有一种方法可以禁用Select:和Close:事件,但我发现他们解释它的方式非常混乱,因此,这这就是为什么我在这里寻求帮助。
我的jQuery
$( "#comment" ).autocomplete({
source: "comments.php",
minLength: 4,
// Attempt to remove click/select functionality - may be a better way to do this
select: function( event, ui ) {
return false;
},
// Attempt to add custom Class to the open Suggestion box - may be a better way
open : function (event, ui) {
$(this).addClass("suggestion-box");
},
// Attempt to cancel the Close event, so when someone makes a selection, the box does not close
close : function (event, ui) {
return false;
}
});
官方jQuery UI文档
从菜单中选择项目时触发; ui.item指的是所选项目。 select的默认操作是将文本字段的值替换为 选定的项目。取消此事件会阻止更新值,但不会更新 阻止菜单关闭。
代码示例
Supply a callback function to handle the select event as an init option.
$( ".selector" ).autocomplete({
select: function(event, ui) { ... }
});
Bind to the select event by type: autocompleteselect.
$( ".selector" ).bind( "autocompleteselect", function(event, ui) {
...
});
混乱
令我困惑的是,他们似乎建议删除.autocomplete并替换为.bind(“autocompleteselect”) - 这将完全禁用自动完成功能?
非常感谢您提供任何帮助。
答案 0 :(得分:19)
从安德鲁斯解决方案中汲取灵感,我找到了一种方法,可以在选择时保持自动完成的开放性,同时减少对核心功能的影响:
var selected; //flag indicating a selection has taken place
var $input = $("input").autocomplete({
source: ['Hello', 'Goodbye', 'Foo', 'Bar'],
select: function( event, ui ) {
selected = true;
}
});
//Override close method - see link below for details
(function(){
var originalCloseMethod = $input.data("autocomplete").close;
$input.data("autocomplete").close = function(event) {
if (!selected){
//close requested by someone else, let it pass
originalCloseMethod.apply( this, arguments );
}
selected = false;
};
})();
所以想法是在适当时使用中性闭合方法,如选择标志所示。在全球名称空间中选择了标志可能不是最好的主意,但这是为了让其他人改进: - )。
答案 1 :(得分:12)
使用.bind()
的第二种语法只是将事件处理程序附加到jQueryUI的自定义事件的另一种方法。这与在窗口小部件选项中定义事件处理程序(使用select: function(event, ui) { }
)
想象一下,如果您在页面上有多个自动完成小部件,并且您希望在其中任何一个引发“select”事件时执行相同的功能,例如:
$(".autocomplete").bind("autocompleteselect", function(event, ui) {
/* Will occur when any element with an autocomplete widget fires the
* autocomplete select event.
*/
});
至于取消select
事件,你就是正确的。但是,取消close
事件有点困难;看起来从事件处理程序返回false将不起作用(菜单实际关闭后会触发close
)。您可以执行一些hackery并将select
函数替换为您自己的函数:
var $input = $("input").autocomplete({
source: ['Hello', 'Goodbye', 'Foo', 'Bar']
});
$input.data("autocomplete").menu.options.selected = function(event, ui) {
var item = ui.item.data( "item.autocomplete" );
$input.focus();
};
以下是一个有效的例子:http://jsfiddle.net/ZGmyp/
我不确定覆盖事件的后果是什么,但在简单的例子中看起来并没有发生任何疯狂的事情。我会说这是对小部件的一种不自然的使用,因此可能会产生意想不到的后果。
答案 2 :(得分:2)
我尝试了其他人在这里提出的各种想法但没有成功。
我正在使用Jquery 2.1.4和UI 1.11.4,这就是我如何使用它:
<强>使用Javascript:强>
<script>
var lookup_selectable = false;
var lookup_term = '';
$(function() {
$( "#lookup" ).autocomplete({
source: "lookup_processor.php",
minLength: 3,
renderItem: function( ul, item ) {
// This function is called for each item returned from the 'source:'
// It is up to you to ensure that a list item element is returned.
// do whatever logic on the item data to determine if it should not be slectable..
//Example:
// The backend "source" has handled the logic of what is selectable or not
// and has set a 'selectable' parameter that we can use
if(item.selectable){
// return the item unchanged from autocompletes default behavior
return $("<li></li>").data("item.autocomplete", item).append("<a>" + item.label + "</a>").appendTo(ul);
}else{
// this item is not selectable so lets apply a class named 'item-disabled' to give a visual queue.
// We are also wrapping the label in a span instead of an anchor just to show that the item is still clickable, darn!
return $('<li class="ui-menu-item item-disabled"></li>').data("item.autocomplete", item).append('<span>'+item.label+'</span>').appendTo(ul);
}
},
select: function( event, ui ) {
// This item was clicked ..
// save the item.clickable value to our own external variable
// Note: We have to do this because the item object is not available in the 'close' function :-(
lookup_selectable = ui.item.selectable; // the item object is available inside the ui parameter
// store the current search term
lookup_term = $('#lookup').val();
// do any additional stuff based on the item selected, if needed...
},
close: function(event, ui){
// This function fires after select: and after autocomplete has already "closed" everything. This is why event.preventDefault() won't work.
// ** ui is an empty object here so we have to use our own variable to check if the selected item is "selectable" or not..
if (! lookup_selectable){
// We need to undo what autocomplete has already done..
$('#lookup').val(lookup_term); // Restore the search term value
$('#'+event.currentTarget.id).show(); // Keep the selection window open
// ta-da! To the end user, nothing changes when clicking on an item that was not selectable.
}
}
});
});
</script>
<强> CSS:强>
<style>
li.ui-menu-item.item-disabled {
text-decoration: none;
line-height: 1.5;
color: #ccc;
}
</style>
Backend Source&#34; lookup_processor.php&#34;:
<?php
$search_results = array();
// ..do whatever to get the data for each item
$item_data = getting_item_data();
foreach ($item_data as $data){
// The id, label, and value keys are the typical keys that autocomplete expects, but you can add ass many others as you want..
// For our example we are setting the 'selectable' key to true or false based on some simple example logic
$search_results[] = array(
'id'=>$data['id'],
'label'=>$data['label'],
'value'=>$data['value'],
'selectable'=>$data['some_thing_to_check']>0?true:false, // This is the parameter our 'select:' function is looking for
'send_it_all_if_you_want'=>json_encode($data)); // this is just an example of how you can send back anything you want
);
}
// send the results back to autocomplete
echo json_encode($search_results);
exit;
?>
答案 3 :(得分:1)
我为此做了一个略有不同的路线,并扩展了安德鲁的fiddle
目的是我总是希望在某个输入具有焦点的同时显示自动完成 - 允许多个选择。
$("#myInput").autocomplete({
source: ["Test", "This", "Doesnt", "Close"],
minLength: 0,
select: function (event, ui) {
// Add your own custom login to manipulate ui.item.label and add what you need the input field (and ui.item.value if required.)
// We've customised how we want the select to "work" so prevent the default
// of auto clearing the input.
event.preventDefault();
},
close : function(event)
{
// We're closing the autocomplete - check if the input still has focus...
if ($("#myInput").is(":focus"))
{
// Prevent the auto complete from closing.
event.preventDefault();
// Make sure we're reshowing the autcomplete - since the input would have momentarily
// lost focus when we selected an item.
$("#myInput").autocomplete("search", "")
}
}
});
$("#myInput").focus(function () {
// We're not taking any filtering into account for this example.
$(this).autocomplete("search", "")
});
答案 4 :(得分:0)
使用$ input.data(“autocomplete”)。menu.options.selected = function(){} 选择不同项后导致值不保持(我们的实现需要追加到最后。可能只需添加e.preventDefault()或在追加代码之前返回false)。所以我在关闭事件中做了一个转换。 放置外部变量和编写自己的方法的例子比较好,但也不喜欢它。我首先尝试手动调用方法,并在需要手动关闭autocomplte时传递参数。 (在我们的实现中,客户要求列表在单击项目时打开,但在鼠标离开文本框容器时关闭。
所以我只是将自动完成附加到文本框的元素容器并附加了mouseenter和mouseleave。为了确定它是否应该关闭,我使用了jQuery(this).data(“canClose”)自定义变量。基本上,它所做的只是在变量为'false'时使用搜索方法重新打开自动完成。
以下是最终代码:
element.autocomplete({
minLength:0,
source: source,
appendTo: element.parent(),
close: function () {
if (!jQuery(this).data("canClose")) {
jQuery(this).autocomplete('search', '');
}
return false;
}
});
element.mouseenter(function () {
element.data("canClose", false);
jQuery(this).autocomplete('search', '');
});
element.parent().mouseleave(function () {
element.data("canClose", true);
element.delay(2000).autocomplete("close");
});
如果您需要执行追加而不是替换值,请在构造函数中添加select处理程序:
select: function (event, ui) {
var text = element.text().trim();
if (text.length > 0 && !text.endsWith(",")) {
text += ", ";
}
jQuery(this).text((text + ui.item.label));
jQuery(this).focus();
return false;
}