如果文本被用户消隐,请将jQuery组合框的文本恢复为所选选项的文本?

时间:2012-07-08 22:09:58

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

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

  1. 我在组合框中键入了一些东西,它会显示所有匹配的选项,我选择其中一个匹配选项。这会将组合框文本设置为所选项目的文本。
  2. 现在,我专注于组合框,然后回到组合框并删除所有文本,但不选择其他项目。 组合框显示空白文本,即使选中的值在那里。这对我来说不是很直观,因为空白文本应该意味着没有选择任何选项。
  3. 可以在此处找到说明此问题的视频:http://screencast.com/t/QLUtZYsL2

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

    使用jQuery组合框的示例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>
    

2 个答案:

答案 0 :(得分:0)

您可以利用更改事件来缓存当前选定的文本和值,然后使用focusout或blur事件来确保在您离开时文本不会保持空白。如果您可以发布代码示例,我可以修改它以向您展示我正在谈论的内容。

答案 1 :(得分:0)

我终于找到了出路,但让我先从一些建设性的批评开始。 jQuery就像是ROCKET SCIENCE。大声笑。 jQuery没有直观的事件模型,在这个领域javascript失败了jQuery。我花了很多时间试图在jQuery组合框上触发更改或模糊或聚焦事件,但没有任何成功。因此,解决我在最初的帖子中提到的问题的最佳解决方案是遵循下面给出的两种方法中的任何一种。

  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组合框的input元素。看下面的代码。

     $(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()); } });
    });
    
  3. 如果您在默认情况下选择第一个选项以提示用户,则附加焦点事件的代码将更改为如下所示。将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()); } });