【问题标题】:jQueryUI autocomplete displays value instead of label in the target input fieldjQueryUI 自动完成在目标输入字段中显示值而不是标签
【发布时间】:2018-08-27 05:50:34
【问题描述】:

我正在从本地数组中提供一个 jQuery UI 自动完成功能,如下所示:

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

我希望控件能够只显示建议框中的标签,它确实如此,并且也只能在目标输入字段中显示所选项目的标签,在我的情况下,这是一个文本框,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. 但是,如果我使用我的键盘键浏览建议框中的项目,则只有values 再次出现在目标输入字段中。我还需要覆盖keypresskeyupkeydown 事件吗?但是哪个控件,因为建议框是动态创建的。

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

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

发生了什么事?我是否缺少事件处理程序?

演示

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

【问题讨论】:

  • 你能创建一个演示吗?
  • 当然。就这样做。
  • @brk 我刚刚包含了一个演示。

标签: javascript jquery jquery-ui jquery-ui-autocomplete


【解决方案1】:

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

在焦点和 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>

【讨论】:

  • 您是否通过单步执行 jQuery UI 源代码发现了这一点?
  • 不,我已经看到这样的双重触发问题,所以我只是尝试。通常这些问题来自于同时触发来自不同嵌套元素的事件,但情况似乎并非如此。无论如何,它肯定不应该是这样的,所以阅读 UI 源代码可以准确定位问题,因为有足够的时间这样做.. :P
  • 非常感谢。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-28
  • 2012-05-11
  • 2020-09-21
  • 2015-12-26
  • 2021-08-13
相关资源
最近更新 更多