jQueryUI 自动完成在目标输入字段中显示值而不是标签

jQueryUI autocomplete displays value instead of label in the target input field

我正在从本地数组中输入 jQuery UI 自动完成,如下所示:

var articleCategories = [
{
    label: "Technical",
    value: 1
}, 
...
];

我希望控件能够仅显示建议框中的标签,它确实如此,并且也仅显示 [=49= 中 selected 项的标签]目标输入字段,在我的例子中是一个文本框,idtxtCategory

function displaySelectedCategoryLabel(event, ui) {
    $("#txtCategory").val(ui.item.label);
    $("#hidSelectedCategoryId").val(ui.item.value);
};

var autoComplete = $("#txtCategory").autocomplete({
    source: articleCategories,
    classes: ...,
    position: ...,
    focus: function (event, ui) {
        $("#txtCategory").val(ui.item.label);
    }, 
    select: function (event, ui) {
        displaySelectedCategoryLabel(event, ui);
    }, 
    change: function (event, ui) {
        displaySelectedCategoryLabel(event, ui);
    }
});

因此,我为所有三个事件提供了覆盖,focusselectchange 事件。当我在调试器中单步执行时,我看到它们的行为都与我预期的一样,除了一个小偏差,如下所述。

情况如下:

  1. 当我通过将鼠标悬停在建议框中的项目上来改变焦点时,focus 事件正常工作,显示标签在目标输入字段中。

  2. 但是,如果我使用我的键盘键 浏览建议框中的项目 ,再一次,只有 value 出现在目标输入字段。我还需要覆盖 keypresskeyupkeydown 事件吗?但是which控件,因为建议框是动态创建的。

  3. 当我 select 来自建议框的条目时,目标输入字段显示 label 服从我的处理程序,但只是短暂的,如上所述。只要我留在目标控件内,它很快就会变回显示 value

  4. 正如预期的那样,一旦我将焦点从目标控件移到外部,更改事件就会发生并且目标输入字段开始显示 label 根据我的处理程序。

这是怎么回事?我是否缺少事件处理程序?

演示

Here is a working demo 说明了问题。请下载名为 TestJQueryUIAutoComplete 的整个文件夹,因为它包含 jQueryUI javascript 文件和 CSS文件。如果您已经有了这些 CSS 和 JS 文件,那么您只需要下载 TestJQueryUIAutoComplete.html 文件。

看起来焦点被触发了两次,在其覆盖版本和默认版本中,将值放入自动完成框中。

在 focus 和 displaySelectedCategoryLabel 上添加 preventDefault() 似乎可以解决问题,而我仍在调查为什么会这样。

<html>
<head>
    <link rel = "stylehseet" type = "text/css" href = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.css"  />
    <link rel = "stylehseet" type = "text/css" href = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.structure.css"  />
    <link rel = "stylehseet" type = "text/css" href = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.theme.css"  />
    <style>
        #txtCategory {
            width: 400px;
            height: 50px;
            border: 2px solid red;
            padding-left: 20px;
            font-size: 20px;
        }

        .myCustomClass {
            font-size: 40px;
            font-family: "Georgia";
            list-style-type: none;
            background-color: blue;
            color: white;
        }
    </style>
<meta charset="utf-8"
</head>

<body>
    <input id = "txtCategory" />
    <input id = "hidSelectedCategoryId" type = "hidden" />

    <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src = "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js"></script>
    <script>
        $(function() {

            var articleCategories = [
            {
                label: "Technical",
                value: 1
            },
            {
                label: "Non-Technical",
                value: 2
            },
            {
                label: "External Publications",
                value: 3
            },
            {
                label: "Books",
                value: 4
            },
            {
                label: "Movies",
                value: 5
            }
        ];
        function displaySelectedCategoryLabel(event, ui) {
            $("#txtCategory").val(ui.item.label);
            $("#hidSelectedCategoryId").val(ui.item.value);
            event.preventDefault();
        };
        var autoComplete = $("#txtCategory").autocomplete({
            source: articleCategories,
            classes: {
                "ui-autocomplete": "myCustomClass"
            },
            position: {
                my: "left top",
                at: "left bottom",
                of: "#txtCategory",
                collision: "fit"
            },
            focus: function (event, ui) {
                $("#txtCategory").val(ui.item.label);
                event.preventDefault();
            },
            select: function (event, ui) {
                displaySelectedCategoryLabel(event, ui);
            },
            change: function (event, ui) {
                displaySelectedCategoryLabel(event, ui);
            }
        });
    });
    </script>
</body>