0

我遇到了最新的 jQuery 组合框的问题。用例如下所述。

  1. 我在组合框中输入一些内容,这会显示所有匹配选项,然后我选择其中一个匹配选项。这会将组合框文本设置为所选项目的文本。
  2. 现在,我将焦点移出组合框,然后回到组合框并删除所有文本,但不选择其他项目。即使所选值存在,组合框仍显示空白文本。这对我来说似乎不是很直观,因为空白文本应该意味着没有选择任何选项。

可以在此处找到说明此问题的视频:http: //screencast.com/t/QLUtZYsL2

这就是我在上述用例中的目标: 我想确保万一用户以某种方式删除组合框文本,然后在离开组合框时,文本将恢复为所选项目的文本。

带有 jQ​​uery 组合框的示例 html 页面如下所示。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery UI Example Page</title>
<link type="text/css" href="css/cupertino/jquery-ui-1.8.21.custom.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.21.custom.min.js"></script>
<script type="text/javascript" src="http://jzaefferer.github.com/jquery-validation/jquery.validate.js"></script>
<style>
.ui-combobox {
    position: relative;
    display: inline-block;
}
.ui-combobox-toggle {
    position: absolute;
    top: 0;
    bottom: 0;
    margin-left: -1px;
    padding: 0;
    /* adjust styles for IE 6/7 */
    *height: 1.7em;
    *top: 0.1em;
}
.ui-combobox-input {
    margin: 0;
    padding: 0.3em;
}
</style>
<script type="text/javascript">
    (function ($) {
        $.widget("ui.combobox", {
            _create: function () {
                var input,
                self = this,
                select = this.element.hide(),
                selected = select.children(":selected"),
                value = selected.val() ? selected.text() : "",
                wrapper = this.wrapper = $("<span>")
                    .addClass("ui-combobox")
                    .insertAfter(select);

                input = $("<input>")
                .appendTo(wrapper)
                .val(value)
                .addClass("ui-state-default ui-combobox-input")
                .autocomplete({
                    delay: 0,
                    minLength: 0,
                    source: function (request, response) {
                        var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
                        response(select.children("option").map(function () {
                            var text = $(this).text();
                            if (this.value && (!request.term || matcher.test(text)))
                                return {
                                    label: text.replace(
                                        new RegExp(
                                            "(?![^&;]+;)(?!<[^<>]*)(" +
                                            $.ui.autocomplete.escapeRegex(request.term) +
                                            ")(?![^<>]*>)(?![^&;]+;)", "gi"
                                        ), "<strong>$1</strong>"),
                                    value: text,
                                    option: this
                                };
                        }));
                    },
                    select: function (event, ui) {
                        ui.item.option.selected = true;
                        self._trigger("selected", event, {
                            item: ui.item.option
                        });
                    },
                    change: function (event, ui) {
                        if (!ui.item) {
                            var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"),
                                valid = false;
                            select.children("option").each(function () {
                                if ($(this).text().match(matcher)) {
                                    this.selected = valid = true;
                                    return false;
                                }
                            });
                            if (!valid) {
                                // remove invalid value, as it didn't match anything
                                $(this).val("");
                                select.val("");
                                input.data("autocomplete").term = "";
                                return false;
                            }
                        }
                    }
                })
                .addClass("ui-widget ui-widget-content ui-corner-left");

                input.data("autocomplete")._renderItem = function (ul, item) {
                    return $("<li></li>")
                    .data("item.autocomplete", item)
                    .append("<a>" + item.label + "</a>")
                    .appendTo(ul);
                };

                $("<a>")
                .attr("tabIndex", -1)
                .attr("title", "Show All Items")
                .appendTo(wrapper)
                .button({
                    icons: {
                        primary: "ui-icon-triangle-1-s"
                    },
                    text: false
                })
                .removeClass("ui-corner-all")
                .addClass("ui-corner-right ui-combobox-toggle")
                .click(function () {
                    // close if already visible
                    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();
                });
            },

            destroy: function () {
                this.wrapper.remove();
                this.element.show();
                $.Widget.prototype.destroy.call(this);
            }
        });
    })(jQuery);

    $(function () {
        $("#combobox").combobox();
        $("#toggle").click(function () {
            $("#combobox").toggle();
        });
    });
</script>
</head>
<body>
<div class="demo">
    <div class="ui-widget">
        <label>
            Your preferred programming language:
        </label>
        <select id="combobox">
            <option value="">Select one...</option>
            <option value="ActionScript">ActionScript</option>
            <option value="AppleScript">AppleScript</option>
            <option value="Asp">Asp</option>
            <option value="BASIC">BASIC</option>
            <option value="C">C</option>
            <option value="C++">C++</option>
            <option value="Clojure">Clojure</option>
            <option value="COBOL">COBOL</option>
            <option value="ColdFusion">ColdFusion</option>
            <option value="Erlang">Erlang</option>
            <option value="Fortran">Fortran</option>
            <option value="Groovy">Groovy</option>
            <option value="Haskell">Haskell</option>
            <option value="Java">Java</option>
            <option value="JavaScript">JavaScript</option>
            <option value="Lisp">Lisp</option>
            <option value="Perl">Perl</option>
            <option value="PHP">PHP</option>
            <option value="Python">Python</option>
            <option value="Ruby">Ruby</option>
            <option value="Scala">Scala</option>
            <option value="Scheme">Scheme</option>
        </select>
    </div>
    <button id="toggle">
        Show underlying select</button>
 </div>
 <!-- End demo -->
</body>
</html>
4

2 回答 2

0

您可以利用 change 事件缓存当前选定的文本和值,然后使用 focusout 或 blur 事件来确保离开时文本不会保持空白。如果您可以发布代码示例,我可以对其进行修改以向您展示我在说什么。

于 2012-07-08T22:21:22.773 回答
0

我终于找到了出路,但让我从一些建设性的批评开始。jQuery 就像火箭科学。哈哈。jQuery 没有直观的事件模型,在这方面 javascript 击败了 jQuery。我花了很多时间试图在 jQuery 组合框上触发 change 或 blur 或 focusout 事件,但没有任何成功。因此,解决我在最初帖子中提到的问题的最佳解决方案是遵循下面给出的两种方法中的任何一种。

  1. 将 blur 或 focusout 事件附加到 jQuery 组合框的父级。例如,一个 div 可以是父级,因为它里面有 jQuery 组合框。看看下面的代码。

       $(document).ready(function () {
        $("#dropdown_sel").combobox();
        $($('.ui-combobox-input')[0]).css('width', '500px');
        $("#toggle").click(function () {
            $("#dropdown_sel").toggle();
        });
        //line below attaches the focusout event
        $('#dropdown_sel').parent().bind('focusout', function () { if ($.trim($('#dropdown_sel option:selected').val()) != '') { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:selected').text()); } });
    });
    
  2. 或者将 blur 或 focusout 事件附加到 jQuery 组合框的输入元素。看看下面的代码。

     $(document).ready(function () {
        $("#dropdown_sel").combobox();
        $($('.ui-combobox-input')[0]).css('width', '500px');
        $("#toggle").click(function () {
            $("#dropdown_sel").toggle();
        });
        //line below attaches the focusout event
        $('#dropdown_sel').next().find('input').bind('focusout', function () { if ($.trim($('#dropdown_sel option:selected').val()) != '') { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:selected').text()); } });
    });
    

如果您默认选择第一个选项来提示用户,则附加焦点事件的代码将更改为如下所示。在事件的逻辑中添加了一个 else 部分,其中 input 元素的文本设置为第一个选项的文本。

 $('#dropdown_sel').next().find('input').bind('focusout', function () { if ($.trim($('#dropdown_sel option:selected').val()) != '') { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:selected').text()); } else { $('#dropdown_sel').next().find('input').val($('#dropdown_sel option:first').text()); } });
于 2012-07-10T20:19:37.010 回答