如何动态填充JQuery自动完成组合框?

时间:2014-01-28 18:01:13

标签: jquery jquery-ui-autocomplete

我正在使用JQuery UI Autocomplete combobox

我有一个简单的选择:

<select id="myselect" class="combobox">    
<option value="" ></option>
</select>"

当页面加载时我称之为:

$('.combobox').combobox();

我需要做的是在页面加载后填充组合框。这听起来像是一项微不足道的任务,但是我在最后一天试图让它发挥作用时,我一直在撞墙。

即使我尝试这样简单的追加:

$("#myselect").append('<option value="value1">text 1</option>')

该值不会出现在组合框中。上面的调用必定是错误的,但我不知道如何将值附加到组合框。

请告诉我一种方法。

非常感谢您的帮助

这是我的combobox.js文件的源代码:

(function ($) {
$.widget("ui.combobox", {

    _create: function () {
        var select = this.element;
        select = this.element;
        var watermark = "Please select a restaurant...";
        select.hide();

        // process select options into an array
        var opts = new Array();

        $('option', select).each(function (index) {
            var opt = new Object();
            opt.value = $(this).val();
            if ($(this).text() != "") {
                opt.label = $(this).text();
                opts[opts.length] = opt;
            }
        });

        // set up input text element
        var input = $("<input class='combo_input' type='text'>");

        input.insertAfter(select);
        input.autocomplete({
            source: opts,
            delay: 0,
            change: function (event, ui) {
                if (!ui.item) {
                    // user didn't select an option, but what they typed may still match
                    var enteredString = $(this).val();
                    var stringMatch = false;
                    for (var i = 0; i < opts.length; i++) {
                        if (opts[i].label.toLowerCase() == enteredString.toLowerCase()) {
                            select.val(opts[i].value);// update (hidden) select
                            //$(this).val(opts[i].label);// corrects any incorrect case
                            //opts[i].css("border", "1px solid red");
                            stringMatch = true;

                            // Trigger the custom changed event
                            self._trigger("changed", event, {
                                value: select.val()
                            });
                            break;
                        }
                    }
                    if (!stringMatch) {
                        // remove invalid value, as it didn't match anything
                        $(':selected', select).text("");
                        $(this).val($(':selected', select).text()).addClass('watermark');

                    }
                    return false;
                }
            },
            select: function (event, ui) {
                select.val(ui.item.value);// update (hidden) select
                $(this).val(ui.item.label);
                if ($(this).val() == watermark) {
                    input.addClass('watermark');
                    imgbt.addClass("invisibility");
                }
                else {
                    input.removeClass('watermark');
                    imgbt.removeClass("invisibility");
                }
                // Trigger the selected event
                ui.item.selected = true;
                self._trigger("selected", event, {
                    value: ui.item.value
                });
                return false;
            },
            focus: function (event, ui) {
                if (event.which === 38 || event.which === 40) {
                    $(this).val(ui.item.label);
                    return false;
                }

            },
            // stop parent form from being while menu is open
            open: function (event, ui) {
                input.attr("menustatus", "open");

            },
            close: function (event, ui) {
                input.attr("menustatus", "closed");
            },
            autoFocus: true,
            minLength: 0
        });

        input.addClass("ui-widget");

        // initialise text with what's currently selected

        if ($(':selected', select).val() == "") {
            input.val(watermark).addClass('watermark')
        } else {
            input.val($(':selected', select).text()).removeClass('watermark');
        }
        input.attr('title', input.val());


        // lost focus status            

        input.blur(function (e) {
            if (input.val() == "") {
                input.val(watermark).addClass('watermark');
                imgbt.addClass("invisibility");
            }
            else {
                input.removeClass('watermark')
                imgbt.removeClass("invisibility");
            }
        });

        //clear text when user clicks in text input             
        input.click(function () {
            if ($(this).val() == watermark) {
                $(this).removeClass('watermark').val("");
                imgbt.addClass("invisibility");
            } else {
                imgbt.removeClass("invisibility");
            }

        });


        // over-ride form submit, so it cant submit if the menu is open
        input.attr("menustatus", "closed");
        var form = $(input).parents('form:first');
        $(form).submit(function (e) {
            return (input.attr('menustatus') == 'closed');
        });

        var imgbt = $("<button type=\"button\">&nbsp;</button>");
        imgbt.addClass('clear_bt').addClass('btn');
        if (input.val() == watermark) { imgbt.addClass('invisibility') }
        else { imgbt.removeClass('invisibility') }
        imgbt.insertAfter(input);

        // Clear all the keywords
        imgbt.click(function (e) {
            input.val('');
            $("body").focus();
            $(this).addClass('invisibility');
            $("#rcbRestaurant").val("");
        });
        imgbt.blur(function (e) {
            input.blur();
        });

        // set up button for fake 'select'

        var btn = $("<button>&nbsp;</button>");
        btn.attr("tabIndex", -1);
        btn.attr("title", "Select your option");
        btn.addClass("combobox_bt");
        btn.insertAfter(imgbt);
        if (select.hasClass('disabled')) {
            input.addClass('disabled').attr('disabled', 'disabled');
            btn.addClass('disabled').attr('disabled', 'disabled');
        }
        if (select.hasClass('error')) {
            input.addClass('error').focus();
            btn.addClass('error').focus();
        } else { input.removeClass('error'); btn.removeClass('error'); }

        if (select.attr('autofocus') == 'autofocus') {
            input.focus();
            btn.focus();
        }

        btn.button({
            icons: {
                primary: "ui-icon-triangle-1-s "
            },
            text: false
        });
        btn.removeClass("ui-corner-all");
        btn.addClass("ui-corner-right ui-button-icon");
        btn.click(function () {
            btn.focus();
            input.click();
            //event.preventDefault();
            // close if already visible
            if (input.autocomplete("widget").is(":visible")) {
                input.autocomplete("close");
                return false; // return false, so form isn't automatically submitted
            }
            // pass empty string as value to search for, displaying all results
            input.autocomplete("search", "");
            input.focus();
            return false; // return false, so form isn't automatically submitted
        });

        // add some styles
        btn.css("z-index", "1");
        btn.css("display", "inline");
        btn.css("padding", 0);
        $('span.ui-button-text', btn).css("padding", 0);

        // for testing
        /*
        autocomplete: function(value) {
            this.element.val(value);
            this.input.val(value);
        }
        */
    }
});
})(jQuery);

3 个答案:

答案 0 :(得分:2)

jsFiddle Demo

您链接的演示以及您调用的combobox会显示“自动填充功能可以”的自定义实现。要使用此功能,您必须编写自己的组合框。这是该演示的重点。因此,对于您来说,必须实现您自己的combobx小部件才能使用其功能。没有“combobox”是jQuery UI的标准配置,只有自动完成功能。请注意,您将收到错误消息:

  

未捕获TypeError:对象[object Object]没有方法'combobox'

不使用自定义实现。基本上,您应该复制粘贴窗口小部件,然后使用它或修改它以供您自己使用。

(function( $ ) {
$.widget( "custom.combobox", {
  _create: function() {
    this.wrapper = $( "<span>" )
      .addClass( "custom-combobox" )
      .insertAfter( this.element );

    this.element.hide();
    this._createAutocomplete();
    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", "" )
      .addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
      .autocomplete({
        delay: 0,
        minLength: 0,
        source: $.proxy( this, "_source" )
      })
      .tooltip({
        tooltipClass: "ui-state-highlight"
      });

    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()
      .appendTo( this.wrapper )
      .button({
        icons: {
          primary: "ui-icon-triangle-1-s"
        },
        text: false
      })
      .removeClass( "ui-corner-all" )
      .addClass( "custom-combobox-toggle ui-corner-right" )
      .mousedown(function() {
        wasOpen = input.autocomplete( "widget" ).is( ":visible" );
      })
      .click(function() {
        input.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.data( "ui-autocomplete" ).term = "";
  },

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

带样式

.custom-combobox {
 position: relative;
 display: inline-block;
}
.custom-combobox-toggle {
 position: absolute;
 top: 0;
 bottom: 0;
 margin-left: -1px;
 padding: 0;
 /* support: IE7 */
 height: 1.7em;
 top: 0.1em;
}
.custom-combobox-input {
 margin: 0;
 padding: 0.3em;
}

完成所有这些操作后,您只需使用

即可
$("#myselect").append('<option value="value1">text 1</option>');
$('#myselect').combobox();
$("#myselect").append('<option value="value2">text 2</option>');

答案 1 :(得分:1)

我过去曾使用Chosen来完成此任务。可能适合你吗?

答案 2 :(得分:0)

使用jquery ui自动完成,它更容易

http://jqueryui.com/autocomplete/