2014-01-28 86 views
3

我正在使用JQuery UI Autocomplete combobox如何動態填充JQuery自動完成組合框?

我有一個簡單的選擇是這樣的:

<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); 

回答

0

使用jQuery UI的自動完成功能,它更容易

http://jqueryui.com/autocomplete/

+0

感謝您的快速反應。這就是我正在使用的。我正在使用自動完成組合框(作爲我的問題中的鏈接)。 – seemorgh

+0

您不應該調用組合框來創建窗口小部件,而是使用.autocomplete,頁面上有演示,嘗試過它們嗎? – vasu

+0

根據演示中的源代碼(在頁面底部查看源代碼鏈接 - 請參閱我的問題中的鏈接),附加組合框的調用是這樣的:$(「#combobox」).combobox(); – seemorgh

1

我過去曾使用Chosen來完成此操作。可能爲你工作?

+0

嗨Wefx。謝謝你快速的回覆。我可以試試,但JQuery UI組合框是我的客戶使用的,他們寧願保持一致性。有什麼方法可以輕鬆實現我所要求的嗎?它不應該那麼難! – seemorgh

2

jsFiddle Demo

你鏈接的演示,以及combobox你打電話時,顯示的「自動完成什麼可以」自定義實現。爲了使用這個功能,你必須編寫你自己的組合框。這是該演示的重點。所以對於你來說,你需要必須實現你自己的combobx部件才能使用它的功能。沒有「combobox」標準的jQuery UI,只有自動完成。請注意,您將收到錯誤消息:

Uncaught TypeError: Object [object Object] has no method '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>'); 
+0

感謝Travis J.我不確定你的意思。我已經下載幷包含在我的項目中,否則我該如何使用它?我也對它做了一些修改,但不能做你在最後幾行提到的內容。但是,我的版本(除了我的更改外)與您在此發佈的版本之間存在一些差異。我會嘗試你的版本,如果它的工作,可能需要添加我的更改。但我只是好奇爲什麼我的不工作。 – seemorgh

+0

@seemorgh - 當你第一次發佈你的問題時,很難得出確實的情況,因爲它沒有你的源代碼。我看到你已經在你的源代碼中進行了編輯,並將發佈一個編輯到我的答案。 –