0

I'm getting absolutely no where in getting the underlying select to fire a changed event after a autocomplete value is selected.

How can I force a change within the widget. From what I can find I need to trigger a select event and trigger a change with something like this, but I can't get it to work

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 -->
Jesse
  • 1,846
  • 2
  • 22
  • 32
  • 1
    did you try [this](http://stackoverflow.com/questions/6431459/jquery-autocomplete-trigger-change-event)? – Aminur Rashid Jan 26 '17 at 13:04
  • That was the solution I was using to bind to the autocomplete versus the underlying select, but that required me to change a lot pre-existing code. So while your suggest is a solution it's not the preferred way I would like to do it. Thanks – Jesse Jan 27 '17 at 22:10

1 Answers1

1

In case inquiring minds want to know, I solved this with the following

  _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; 
    }

This will fire a change when you tab or exit the autocomplete. If you want it to fire the change on select then use

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


_select: function (event, ui) {                                  
        this.element.trigger('change');             
    },
Jesse
  • 1,846
  • 2
  • 22
  • 32