自动完成组合框小部件强制更改

Autocomplete combobox widget force change

在自动完成值被 selected 后,我完全没有办法让底层 select 触发更改的事件。

如何在小部件中强制进行更改。从我能找到的我需要 触发一个 select 事件并触发类似这样的更改,但我无法让它工作

select: function(event,ui) { 
    this.value=ui.item.value; 
    $(this).trigger('change'); 
    return false; }

(function( $ ) {
    $.widget("st.comboboxAutocomplete", {
        options: {
            minLength: 0,
            showDropdown: false,
            width: '',
            Id: '',
        },
        _create: function () {
            this.wrapper = $("<span>")
              .addClass("st-comboboxAutocomplete")
              .css({ 'padding': '0px 0px', 'width': this.options.width})              
              .insertAfter(this.element);            
            this.element.hide();
            this._createAutocomplete();
            if (this.options.showDropdown)
            {
                this._createShowAllButton();
            }
            
        },

        _createAutocomplete: function () {            
            var selected = this.element.children(":selected"),
              value = selected.val() ? selected.text() : "";            
            this.input = $("<input>")
              .appendTo(this.wrapper)
              .val(value)
              .attr("title", "")
              .attr("id", this.options.Id)
              .addClass("st-comboboxAutocomplete-input")
              .css('margin-right', '5px')
              .autocomplete({
                  delay: 0,
                  minLength: this.options.minLength,                  
                  source: $.proxy(this, "_source"),                 
              });

            this._on(this.input, {
                autocompleteselect: function (event, ui) {                    
                    ui.item.option.selected = true;
                    this._trigger("select", event, {                        
                        item: ui.item.option                        
                    });                    
                },          
                autocompletechange: "_removeIfInvalid"
            });
        },

        _createShowAllButton: function () {
            var input = this.input,
              wasOpen = false;

            $("<a>")
              .attr("tabIndex", -1)
              .attr("title", "Show All Items")
              .tooltip()
              .css('background-color', '#fff')
              .appendTo(this.wrapper)
              .button({
                  icons: {
                      primary: "ui-icon-triangle-1-s"
                  },
                  text: false
              })
              .removeClass("ui-corner-all")
              .addClass("st-comboboxAutocomplete-toggle ui-corner-right")
              .on("mousedown", function () {
                  wasOpen = input.autocomplete("widget").is(":visible");
              })
              .on("click", function () {
                  input.trigger("focus");

                  // Close if already visible
                  if (wasOpen) {
                      return;
                  }

                  // Pass empty string as value to search for, displaying all results
                  input.autocomplete("search", "");
              });
        },

        _source: function (request, response) {
            var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
            response(this.element.children("option").map(function () {
                var text = $(this).text();
                if (this.value && (!request.term || matcher.test(text)))
                    return {
                        label: text,
                        value: text,
                        option: this
                    };
            }));
        },
        
        _removeIfInvalid: function (event, ui) {

            // Selected an item, nothing to do
            if (ui.item) {
                return;
            }

            // Search for a match (case-insensitive)
            var value = this.input.val(),
              valueLowerCase = value.toLowerCase(),
              valid = false;
            this.element.children("option").each(function () {
                if ($(this).text().toLowerCase() === valueLowerCase) {
                    this.selected = valid = true;
                    return false;
                }
            });

            // Found a match, nothing to do
            if (valid) {
                return;
            }

            // Remove invalid value
            this.input
              .val("")
              .attr("title", value + " didn't match any item")
              .tooltip("open");
            this.element.val("");
            this._delay(function () {
                this.input.tooltip("close").attr("title", "");
            }, 2500);
            this.input.autocomplete("instance").term = "";
        },

        _destroy: function () {
            this.wrapper.remove();
            this.element.show();
        }
    });
})( jQuery );

     $(function() {
         $( "#combobox" ).comboboxAutocomplete();  
            $("#combobox").change(function() {
             alert(this.value);
         });
     });
    .ui-button { margin-left: -1px; }
     .ui-button-icon-only .ui-button-text { padding: 0.35em; } 
     .ui-autocomplete-input { margin: 0; padding: 0.48em 0 0.47em 0.45em; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>

<meta charset="utf-8">  
<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 -->



<div class="demo-description">
<p>A custom widget built by composition of Autocomplete and Button. You can either type something into the field to get filtered suggestions based on your input, or use the button to get the full list of selections.</p>
<p>The input is read from an existing select-element for progressive enhancement, passed to Autocomplete with a customized source-option.</p>
</div><!-- End demo-description -->

如果有好奇心的人想知道,我用下面的方法解决了这个问题

  _createAutocomplete: function () {            
        var selected = this.element.children(":selected"),
          value = selected.val() ? selected.text() : "";            
        this.input = $("<input>")
          .appendTo(this.wrapper)
          .val(value)
          .attr("title", "")
          .attr("id", this.options.Id)
          .addClass("st-comboboxAutocomplete-input")
          .css('margin-right', '5px')
          .autocomplete({
              delay: 0,
              minLength: this.options.minLength,                  
              source: $.proxy(this, "_source"),
              change: $.proxy(this, "_change")
          });

        this._on(this.input, {
            autocompleteselect: function (event, ui) {                    
                ui.item.option.selected = true;
                this._trigger("select", event, {                        
                    item: ui.item.option                        
                });                    
            },          
            autocompletechange: "_removeIfInvalid"
        });
    }



 _change: function (event, ui) {            
        this.value = ui.item.value;            
        this.element.trigger('change'); 
        return false; 
    }

这将在您按 Tab 键或退出自动完成时触发更改。如果您希望它在 select 上触发更改,请使用

   select: $.proxy(this, "_select")


_select: function (event, ui) {                                  
        this.element.trigger('change');             
    },