0

最新の jQuery コンボボックスで問題に直面しています。ユースケースは以下のとおりです。

  1. コンボボックスに何かを入力すると、一致するすべてのオプションが表示され、一致するオプションの 1 つを選択します。これにより、コンボボックスのテキストが選択した項目のテキストに設定されます。
  2. ここで、コンボボックスからフォーカスを外し、コンボボックスに戻ってすべてのテキストを削除しますが、別の項目は選択しません。選択した値が存在するにもかかわらず、コンボボックスに空白のテキストが表示されます。空白のテキストはオプションが選択されていないことを意味するため、これは私にはあまり直感的ではないようです。

この問題を説明するビデオは、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>
4

2 に答える 2

0

change イベントを利用して、現在選択されているテキストと値をキャッシュし、次に focusout または blur イベントを使用して、離れたときにテキストが空白のままにならないようにすることができます。コード サンプルを投稿していただければ、私が話していることを示すためにそれを修正できます。

于 2012-07-08T22:21:22.773 に答える
0

ようやく解決策を見つけましたが、建設的な批判から始めましょう。jQuery は ROCKET SCIENCE のようなものです。笑。jQuery には直感的なイベント モデルがなく、この分野では JavaScript が jQuery に勝っています。jQueryコンボボックスでchange、blur、またはfocusoutイベントを発生させようと何時間も費やしましたが、成功しませんでした。したがって、最初の投稿で述べた問題を解決する最善の解決策は、以下に示す 2 つのアプローチのいずれかに従うことです。

  1. ブラーまたはフォーカスアウト イベントを 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()); } });
    });
    

ユーザーにプロンプ​​トを表示するためにデフォルトで最初のオプションを選択している場合、focusout イベントをアタッチするためのコードは次のように変更されます。イベントのロジックにelse部分が追加され、入力要素のテキストが最初のオプションのテキストに設定されます。

 $('#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 に答える