如何使用Tab键在selected.js多个下拉列表中选择一个选项?

时间:2014-12-31 21:24:11

标签: jquery jquery-chosen

好,

我尝试了很多不同的东西,但我似乎无法弄清楚如何在输入搜索后让tab键选择所选的选项。输入键工作得很好。

我会展示我尝试过的东西,但老实说,我不知道从哪里开始。

以下是示例代码:

<html>
<head>
    <script type='text/javascript' src='http://code.jquery.com/jquery-1.6.4.js'></script>
    <script type='text/javascript' src="http://harvesthq.github.io/chosen/chosen.jquery.js"></script>
    <link rel="stylesheet" type="text/css" href="http://harvesthq.github.io/chosen/chosen.css">

</head>
<body>
<select id="chosen_example" style="width: 200px;" multiple="multiple">
    <option value="1">A English Test A</option>
    <option value="1">B German Test B</option>
    <option value="1">C Greek Test C</option>
</select>
<script>
    $(document).ready(function () {
        var chosen_control = $('#chosen_example');
        chosen_control.chosen().keydown(function (e, obj) {
            //it's not getting in here
            console.log('key pressed');
            if (e.which == 9) {
                console.log('tab key pressed');
                //not sure what to do at this point
            }
        });
    });

</script>
</body>
</html>

我已经尝试.chosen().bind(...)了。我已尝试$('#chosen_example').bind(...),以及其他一些事情

这是JS Fiddle随之而来的。

非常感谢任何帮助或指示,或者如果您需要更多信息,请发表评论。

修改 - 解决方案

根据收到的答案,Wondercricket的答案使我朝着正确的方向前进。

通过更改核心js文件choosen.jquery.js,我在case 9下添加了以下内容:

if (this.results_showing) {
    this.result_select(evt);
}
this.mouse_on_container = false;
break;

我已将此添加到Chosen.prototype.keydown_checkerAbstractChosen.prototype.keyup_checker

3 个答案:

答案 0 :(得分:2)

这是一个非常有趣的事情,因为它适用于所选的单选,但它不适用于所选的多选。

我能够通过tab键选择多选项来选择,但它需要对chosen.js脚本本身进行非常小的更改。

在深入了解本地计算机上的chosen.js文件之后,我发现已经有了处理keydown函数的已编写功能,具体如下:

Chosen.prototype.keydown_checker = function (evt) {
        var stroke, _ref1;
        stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
        this.search_field_scale();
        if (stroke !== 8 && this.pending_backstroke) {
            this.clear_backstroke();
        }
        switch (stroke) {
            case 8:
                this.backstroke_length = this.search_field.val().length;
                break;
            case 9:
                if (this.results_showing && !this.is_multiple) {
                   this.result_select(evt);
                }
                this.mouse_on_container = false;
                break;
            case 13:
                if (this.results_showing) {
                    evt.preventDefault();
                }
                break;
            case 32:
                if (this.disable_search) {
                    evt.preventDefault();
                }
                break;
            case 38:
                evt.preventDefault();
                this.keyup_arrow();
                break;
            case 40:
                evt.preventDefault();
                this.keydown_arrow();
                break;
        }
    };

作为tab键是9,已经编写了处理它的功能;但是有书面的逻辑阻止你做你想做的事。

如果您希望在使用多项选择时能够使用Tab键选择一个选项,请删除!this.is_multiple声明中的if条件。

case 9:
    if (this.results_showing) {
           this.result_select(evt);
     }
     this.mouse_on_container = false;
     break;

答案 1 :(得分:1)

答案&amp;演示

没有简单的方法可以做到这一点,但是我让它发挥作用,我已经更新了JSFiddle以证明效果。

HTML

<select id="chosen_example" style="width: 200px;" multiple="multiple">
    <option value="1">A English Test A</option>
    <option value="1">B German Test B</option>
    <option value="1">C Greek Test C</option>
</select>

与您的初始标记相同:)

##JavaScript##

var selector = "#chosen_example";
var chosen_control = $(selector);
chosen_control.chosen();
var chosen_element = $(selector + "_chosen");
var chosen_input = chosen_element.find("input");
chosen_input.keydown(function (e) {
    if (e.which == 9) {
        e.preventDefault();
        var chosen_option = chosen_element.find("div > ul > li");
        var chosen_index = chosen_option.attr( "data-option-array-index" );
        var index = parseInt( chosen_index ) + 1;
        var chosen_control_option = chosen_control.find("option:nth-child(" + index + ")");
        chosen_control_option.prop( "selected" , true );
        chosen_control.trigger('chosen:updated');
    }
});

这就是魔术发生的地方。

说明

变量

  • 选择器:您的控制器选择器(最好是ID,未经其他任何测试)
  • chosen_control JQuery object包含您的选择。
  • chosen_element JQuery object包含插件的容器div
  • chosen_input JQuery object包含插件的input。 (实际输入的地方)
  • chosen_option JQuery object包含插件容器div中显示的当前选项。
  • chosen_index string包含根据data-option-array-index的所述选项的索引。请记住,此索引从0开始,选项的索引从1开始。
  • index :选项的索引,相当于所选索引+ 1。
  • chosen_control_option :select元素中包含所述索引的实际选项。

开发

所以我就是这样做的,就像我说的那样,这不容易/漂亮,但它有效:

  • 首先,我们会收到您的selectchosen_control
  • 然后,我们执行插件并获取容器divchosen_element
  • 然后我们获取chosen_input,并在其上绑定一个keydown event
  • event将检测是否按下了标签,它将执行一系列脏计算以选择标签应显示的选项,并将选择它。
  • 我们执行所选元素的触发命令以刷新自身。

注意

我只是发现如果有多个选项以相同的字母开头,代码不起作用,它只会选择第一个,我会修复它,但不是现在,这是新的一年!

见到你,再见:)

答案 2 :(得分:0)

基于现有的答案,我将其汇总以避免修改所选的源代码:

// Initialise Chosen
$select.chosen(/* ... */);

// Handle Tab correctly in a multi-select input
$select.next().find('.chosen-search-input').keydown(function (event) {
    if (event.key === 'Tab') {
        let $input = $(this);

        // If the search results list is open
        if ($input.closest('.chosen-container').hasClass('chosen-with-drop')) {
            // Cancel Tab
            event.preventDefault();

            // Send Enter instead
            let replacementEvent = $.Event('keyup');
            replacementEvent.which = 13;
            $input.trigger(replacementEvent);
        }
    }
});

但是,我之所以没有使用它,是因为该字段一集中就会打开下拉列表,因此用户在使用键盘移动表单时可能会意外选择某些内容。