Jquery UI自动完成组合框按钮单击事件

问题描述:

我遇到与jquery ui autocomplete when using it to create a combobox奇怪的行为。每当我点击滚动条滚动结果列表,然后点击我的组合框按钮关闭结果,结果列表关闭,然后再次打开。我期望它关闭菜单。Jquery UI自动完成组合框按钮单击事件

步骤摄制

  1. open jsfiddle demo
  2. 类型的 'i' 在自动完成或点击下拉按钮。
  3. 点击垂直滚动的滚动效果下拉按钮
  4. 点击

脚本创建按钮

this.button = $("<button type='button'>&nbsp;</button>") 
    .attr({ "tabIndex": -1, "title": "Show all items" }) 
    .insertAfter(input) 
    .button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }) 
    .removeClass("ui-corner-all") 
    .addClass("ui-corner-right ui-button-icon") 
    .click(function() { 

     // when i put breakpoint here, and my focus is not on input, 
     // then this if steatment is false???? 

     if (input.autocomplete("widget").is(":visible")) { 
      input.autocomplete("close"); 
      return; 
     } 

     // work around a bug (likely same cause as #5265) 
     $(this).blur(); 

     // pass empty string as value to search for, displaying all results 
     input.autocomplete("search", ""); 
     input.focus(); 
}); 

CSS(强制长期结果滚动菜单)

.ui-autocomplete { 
    max-height: 100px; 
    overflow-y: auto; 
    /* prevent horizontal scrollbar */ 
    overflow-x: hidden; 
    /* add padding to account for vertical scrollbar */ 
    padding-right: 20px; 
} 
/* IE 6 doesn't support max-height 
* we use height instead, but this forces the menu to always be this tall 
*/ 
* html .ui-autocomplete { 
    height: 100px; 
} 

即使将焦点转移到小部件本身而不是输入元素,我的解决方案可能会关闭小部件?

任何想法如何修改此代码,使其行为如此?

+0

你能提供的HTML,也许是的jsfiddle?然后,将会更容易得到它。 – 2012-04-23 07:15:34

+0

我不明白你在这里试图达到什么.. [jsfiddle](http://jsfiddle.net/vR9s2/2/) – 2012-04-23 21:14:27

+0

你实际上试图解决什么问题? – 2012-04-24 02:42:30

根据与该automplete插件的各种点击鼠标事件的问题,我想出了这个:jsFiddle example

的jQuery:

var input = $('#txtComplete'); 

var data = []; 
var isOpen = false; 

function _init() { 
    for (var idx = 0; idx <= 100; idx++) { 
     data.push('item: ' + idx); 
    }; 
    input.autocomplete({ 
     source: data, 
     minLength: 0, 
     open: function(event, ui) { 
      isOpen = true; 
     }, 
     select: function(event, ui) { 
      isOpen = false; 
     } 
    }); 
} 

function afterInit() { 
    var button = $("<button type='button'>&nbsp;</button>").attr("tabIndex", -1).attr("title", "Show all items").insertAfter(input).button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }).removeClass("ui-corner-all").addClass("ui-corner-right ui-button-icon").click(function(event) { 
     input.focus(); 
     if (isOpen) { 
      input.autocomplete("close"); 
      isOpen = false; 
     } else { 
      input.autocomplete("search", ""); 
      event.stopImmediatePropagation(); 
     } 
    }); 
} 
$(window).click(function() { 
    input.autocomplete("close"); 
    isOpen = false; 
}); 
$(function() { 
    _init(); 
    afterInit(); 
});​ 
+0

但在你的代码中...组合框无法第二次点击.. – 2012-04-25 04:19:06

+0

@lakshmipriya - 是的。工作正常。 – j08691 2012-04-25 12:15:04

+0

对不起..它正常工作... – 2012-04-25 12:30:41

这个问题是因为在jquery ui自动完成中解决。在特定条件下关闭菜单有一个mousedown事件设置。在其中一个条件中,它检查是否引发mousedown的项目是自动填充小部件的一部分。如果不是,则关闭菜单。由于您正在处理组合框行为,并且您的按钮不是自动填充小部件的一部分,因此点击该按钮将关闭菜单。

autocomplete source on github的第205行开始,您可以看到违规情况。这可能是值得提出的问题在jQuery UI论坛上,因为他们的组合框演示也有这个bug。

UPDATE

此替换事件基于关闭的jquery的UI 1.8.18的。这个事件发生了变化,很可能会再次发生变化。如果你走这条路线,你可能需要手动更新这个代码。

如果在您创建自动填充(jsfiddle demo)之后运行以下操作而点击了您的组合按钮,则可以将mousedown事件修补为不关闭菜单。

var input = $('#combotextbox').autocomplete(/*options*/); 
input.data('autocomplete').menu.element.unbind('mousedown').mousedown(function(event) { 
     var self = input.data('autocomplete'); 
     event.preventDefault(); 
     // clicking on the scrollbar causes focus to shift to the body 
     // but we can't detect a mouseup or a click immediately afterward 
     // so we have to track the next mousedown and close the menu if 
     // the user clicks somewhere outside of the autocomplete 
     var menuElement = self.menu.element[0]; 
     if (!$(event.target).closest(".ui-menu-item").length) { 
      setTimeout(function() { 
       $(document).one('mousedown', function(event) { 
        var t = $(event.target); 
        if (event.target !== self.element[0] && event.target !== menuElement && !$.ui.contains(menuElement, event.target) && !t.hasClass('ui-combo-trigger') && !t.parent().hasClass('ui-combo-trigger')) { 
         self.close(); 
        } 
       }); 
      }, 1); 
     } 

     // use another timeout to make sure the blur-event-handler on the input was already triggered 
     setTimeout(function() { 
      clearTimeout(self.closing); 
     }, 13); 
    }); 

这消除了当前鼠标按下事件,然后将其放回与加入的检查,看看是否触发事件或其父(按钮点击或点击按钮内部UI-图标)的元件具有类ui-combo-trigger

创建按钮的代码相对不变。我们只需要添加新类ui-combo-trigger

var button = $("<button type='button'>&nbsp;</button>").attr("tabIndex", -1).attr("title", "Show all items").insertAfter(input).button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }).removeClass("ui-corner-all").addClass("ui-corner-right ui-button-icon ui-combo-trigger").click(function(event) { 

     // when i put breakpoint here, and my focus is not on input, 
     // then this if steatment is false???? 
     if (input.autocomplete("widget").is(":visible")) { 
      input.autocomplete("close"); 

      return; 
     } 


     // work around a bug (likely same cause as #5265) 
     $(this).blur(); 

     // pass empty string as value to search for, displaying all results 
     input.autocomplete("search", ""); 
     input.focus(); 
     event.stopImmediatePropagation(); 
    }); 

试试这个jsfiddle。我认为它会帮助你。

var input = $('#txtComplete'); 

var data = []; 
var openCheck = false; 

function _init() { 
    for (var idx = 0; idx <= 100; idx++) { 
     data.push('item: ' + idx); 
    }; 
    input.autocomplete({ 
     source: data, 
     minLength: 0, 
     open: function(event, ui) { 
      openCheck = true; 
     }, 
     select: function(event, ui) { 
      openCheck = false; 
     } 
    }); 
} 

function afterInit() { 
    var button = $("<button type='button'>&nbsp;</button>").attr("tabIndex", -1).attr("title", "Show all items").insertAfter(input).button({ 
     icons: { 
      primary: "ui-icon-triangle-1-s" 
     }, 
     text: false 
    }).removeClass("ui-corner-all").addClass("ui-corner-right ui-button-icon").click(function(event) { 
     if (openCheck) { 
      input.autocomplete("close"); 
      openCheck = false; 
     } else { 
      input.autocomplete("search", ""); 
     } 
    }); 
} 

$(function() { 
    _init(); 
    afterInit(); 
}); 
+0

无法使用箭头键导航列表了。 – 2012-04-26 13:29:58

+0

对不起...只需添加input.focus();点击事件...它会工作... – 2012-04-27 03:35:43

Brian解释了这个问题非常好。随着jQuery UI的11,你可以这样做:

wasOpen = false; 
$button 
    .mousedown(function() { 
    wasOpen = input.autocomplete("widget").is(":visible"); 
    }) 
    .click(function() { 
     input.focus(); 

     // Close if already visible 
     if (wasOpen) { 
      return; 
     } 

见例如在http://jqueryui.com/autocomplete/#combobox