【问题标题】:How can I select an option in the chosen.js multiple dropdown with the tab key?如何使用 tab 键在 selected.js 多个下拉列表中选择一个选项?
【发布时间】:2014-12-31 21:24:11
【问题描述】:

好的,

我尝试了很多不同的方法,但我似乎无法弄清楚如何在输入搜索后使用 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

【问题讨论】:

  • 只是一个猜测,但你能用chosen_control.focusout() 来表示你已经离开了元素的焦点吗?我无法使用 jsfiddle 进行有效测试...

标签: jquery jquery-chosen


【解决方案1】:

这是一件很有趣的事情,因为它适用于单选选择,但它不适用于多选选择。

我能够通过 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 键选择一个选项,请删除 if 语句中的 !this.is_multiple 条件。

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

【讨论】:

  • 我会在可能的情况下对此进行测试并通知您!
  • 这不起作用,但是...我能够接受您的建议并在代码中应用适当的修复。谢谢。
【解决方案2】:

答案和演示

没有简单的方法可以做到这一点,但是我成功了,我已经更新了你的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');
    }
});

这就是魔法发生的地方。

说明

变量

  • selector : 你的控制器的选择器(最好是一个 id,没有用其他东西测试过)
  • chosen_controlJQuery object 包含您的选择。
  • chosen_element : JQuery object 包含插件的容器 div
  • chosen_inputJQuery object 包含插件的input。 (您实际输入的位置)
  • chosen_optionJQuery object 包含在插件容器 div 中显示的当前选项。
  • chosen_index : string 包含根据data-option-array-index 的所述选项的索引。请记住,此索引从 0 开始,期权的索引从 1 开始。
  • index : 期权的指数,等于所选指数+1。
  • chosen_control_option :您的选择元素中带有所述索引的实际选项。

发展

所以我就是这样做的,正如我所说,这并不容易/漂亮,但它确实有效:

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

注意

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

再见,再见:)

【讨论】:

  • 这行得通,但如果你转到最后一项的标签,它就在那里。
  • 我实际上从未修改过它,因为我以为你从另一个家伙那里得到了答案哈哈哈,不幸的是我现在无法编码,希望明天我能得到你的答案:)
【解决方案3】:

根据已有的答案,我把这些放在一起,以避免修改 Chosen 的源代码:

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

但是,我没有使用它,因为一旦该字段获得焦点,下拉菜单就会打开,因此用户在使用键盘在表单中移动时可能会意外选择某些内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    相关资源
    最近更新 更多