2012年12月16日 星期日

jQuery 練習題:ASP.NET MVC 連動下拉選單與 jQuery UI Autocomplete ComboBox

嗯…… 我很少使用 jQuery UI,應該說除非必要,不然我不會在專案中去使用 jQuery UI,它是個好物,尤其是在專案需要一個整合性的前端 UI 處理介面又必須要與 jQuery 來搭配時,jQuery UI 往往是很多人的首選,但我還是很少會去使用它,因為總覺得就像開發 ASP.NET Web Forms 專案時去使用 Server Controls 或是 AJAX Control Tool Kit 一般,是可以帶來很多立即可見的功能,但如果想要在這個基礎上面去做客製的處理就必須要花時間與下功夫,我必須說 jQuery UI 是個好物,只是我對它真的很不熟,因為不熟所以也就會有上面的一些誤解看法。

既然不熟的話,那為什麼要寫這篇文章哩?

因為有位朋友向我問了有關 jQuery UI Autucomplete ComboBox 與連動下拉選單的問題,所以花了一點時間看文件並試做了類似情境的操作,覺得把這個過程給記錄下來以免日後遇到相似狀況時我會忘記怎麼做解決的。


有關於 ASP.NET MVC 連動下拉選單的作法可以參考以下的文章內容:

ASP.NET MVC 3 - 基本三層連動式下拉選單應用

jQuery 練習題:三層式連動下拉選單(無後端整合)

ASP.NET MVC 3 - DropDownList 的基本設定方式

 

依據上面的文章內容做出了一個兩層式的連動下拉選單,使用 ASP.NET MVC 4, ADO.NET Entity Framework, MS SQL Server,資料庫使用 Northwind,

Controller:

public class SampleController : Controller
{
    private NorthwindEntities db = new NorthwindEntities();
 
    public ActionResult Index()
    {
        var categories = this.db.Categories.OrderBy(x => x.CategoryID).ToList();
        ViewBag.CategoryList = new SelectList(categories, "CategoryID", "CategoryName");
 
        return View();
    }
 
    [HttpPost]
    public JsonResult Products(string categoryID)
    {
        List<KeyValuePair<string, string>> items = new List<KeyValuePair<string, string>>();
 
        int id = 0;
 
        if (!string.IsNullOrWhiteSpace(categoryID) && int.TryParse(categoryID, out id))
        {
            var products = this.db.Products.Where(x => x.CategoryID == id).OrderBy(x => x.ProductID).ToList();
            if (products.Count() > 0)
            {
                foreach (var product in products)
                {
                    items.Add(new KeyValuePair<string, string>(
                        product.ProductID.ToString(),
                        product.ProductName
                    ));
                }
            }
        }
        return this.Json(items);
    }
 
    protected override void Dispose(bool disposing)
    {
        this.db.Dispose();
        base.Dispose(disposing);
    }
 
}

View:

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
<h2>Index</h2>
<p>
    Category:@Html.DropDownList("CategoryList", "-- Select a Category --")
</p>
<p>
    Products:<select id="Products" name="Products"><option>------</option></select>
</p>
@section scripts
{
    <script type="text/javascript">
        $(document).ready(function () {
            $('#CategoryList').change(function (e) {
                e.preventDefault();
                CategoryListChangeEventHandler();
            });
        });
 
        function CategoryListChangeEventHandler() {
            var selectedValue = $('#CategoryList option:selected').val();
            if ($.trim(selectedValue).length > 0) {
                GetProducts($.trim(selectedValue));
            }
        }
 
        function GetProducts(categoryID) {
            $.ajax({
                type: 'POST',
                url: '@Url.Action("Products", "Sample")',
                data: { categoryID: categoryID },
                dataType: 'json',
                cache: false,
                async: false,
                success: function (response) {
                    if (response.length > 0) {
                        $('#Products').empty();
                        $('#Products')
                            .append($('<option></option>').val('')
                            .text('-- [ ' + $('#CategoryList option:selected').text() + ' ] Products --'));
                        $.each(response, function (i, item) {
                            $('#Products').append($('<option></option>')
                                .val(item.Key)
                                .text(item.Value));
                        });
                    }
                }
            });
        }
    </script>
}

Result:

image

 

 

jQuery UI – Autocomplete Combobox

http://jqueryui.com/autocomplete/#combobox

image

想要使用這個 Autocomplete Combobox 就需要先看 source 的內容,

source

   1: <!doctype html>
   2:  
   3: <html lang="en">
   4: <head>
   5:     <meta charset="utf-8" />
   6:     <title>jQuery UI Autocomplete - Combobox</title>
   7:     <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
   8:     <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
   9:     <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
  10:     <link rel="stylesheet" href="/resources/demos/style.css" />
  11:     <style>
  12:     .ui-combobox {
  13:         position: relative;
  14:         display: inline-block;
  15:     }
  16:     .ui-combobox-toggle {
  17:         position: absolute;
  18:         top: 0;
  19:         bottom: 0;
  20:         margin-left: -1px;
  21:         padding: 0;
  22:         /* adjust styles for IE 6/7 */
  23:         *height: 1.7em;
  24:         *top: 0.1em;
  25:     }
  26:     .ui-combobox-input {
  27:         margin: 0;
  28:         padding: 0.3em;
  29:     }
  30:     </style>
  31:     <script>
  32:     (function( $ ) {
  33:         $.widget( "ui.combobox", {
  34:             _create: function() {
  35:                 var input,
  36:                     that = this,
  37:                     select = this.element.hide(),
  38:                     selected = select.children( ":selected" ),
  39:                     value = selected.val() ? selected.text() : "",
  40:                     wrapper = this.wrapper = $( "<span>" )
  41:                         .addClass( "ui-combobox" )
  42:                         .insertAfter( select );
  43:  
  44:                 function removeIfInvalid(element) {
  45:                     var value = $( element ).val(),
  46:                         matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( value ) + "$", "i" ),
  47:                         valid = false;
  48:                     select.children( "option" ).each(function() {
  49:                         if ( $( this ).text().match( matcher ) ) {
  50:                             this.selected = valid = true;
  51:                             return false;
  52:                         }
  53:                     });
  54:                     if ( !valid ) {
  55:                         // remove invalid value, as it didn't match anything
  56:                         $( element )
  57:                             .val( "" )
  58:                             .attr( "title", value + " didn't match any item" )
  59:                             .tooltip( "open" );
  60:                         select.val( "" );
  61:                         setTimeout(function() {
  62:                             input.tooltip( "close" ).attr( "title", "" );
  63:                         }, 2500 );
  64:                         input.data( "autocomplete" ).term = "";
  65:                         return false;
  66:                     }
  67:                 }
  68:  
  69:                 input = $( "<input>" )
  70:                     .appendTo( wrapper )
  71:                     .val( value )
  72:                     .attr( "title", "" )
  73:                     .addClass( "ui-state-default ui-combobox-input" )
  74:                     .autocomplete({
  75:                         delay: 0,
  76:                         minLength: 0,
  77:                         source: function( request, response ) {
  78:                             var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
  79:                             response( select.children( "option" ).map(function() {
  80:                                 var text = $( this ).text();
  81:                                 if ( this.value && ( !request.term || matcher.test(text) ) )
  82:                                     return {
  83:                                         label: text.replace(
  84:                                             new RegExp(
  85:                                                 "(?![^&;]+;)(?!<[^<>]*)(" +
  86:                                                 $.ui.autocomplete.escapeRegex(request.term) +
  87:                                                 ")(?![^<>]*>)(?![^&;]+;)", "gi"
  88:                                             ), "<strong>$1</strong>" ),
  89:                                         value: text,
  90:                                         option: this
  91:                                     };
  92:                             }) );
  93:                         },
  94:                         select: function( event, ui ) {
  95:                             ui.item.option.selected = true;
  96:                             that._trigger( "selected", event, {
  97:                                 item: ui.item.option
  98:                             });
  99:                         },
 100:                         change: function( event, ui ) {
 101:                             if ( !ui.item )
 102:                                 return removeIfInvalid( this );
 103:                         }
 104:                     })
 105:                     .addClass( "ui-widget ui-widget-content ui-corner-left" );
 106:  
 107:                 input.data( "autocomplete" )._renderItem = function( ul, item ) {
 108:                     return $( "<li>" )
 109:                         .data( "item.autocomplete", item )
 110:                         .append( "<a>" + item.label + "</a>" )
 111:                         .appendTo( ul );
 112:                 };
 113:  
 114:                 $( "<a>" )
 115:                     .attr( "tabIndex", -1 )
 116:                     .attr( "title", "Show All Items" )
 117:                     .tooltip()
 118:                     .appendTo( wrapper )
 119:                     .button({
 120:                         icons: {
 121:                             primary: "ui-icon-triangle-1-s"
 122:                         },
 123:                         text: false
 124:                     })
 125:                     .removeClass( "ui-corner-all" )
 126:                     .addClass( "ui-corner-right ui-combobox-toggle" )
 127:                     .click(function() {
 128:                         // close if already visible
 129:                         if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
 130:                             input.autocomplete( "close" );
 131:                             removeIfInvalid( input );
 132:                             return;
 133:                         }
 134:  
 135:                         // work around a bug (likely same cause as #5265)
 136:                         $( this ).blur();
 137:  
 138:                         // pass empty string as value to search for, displaying all results
 139:                         input.autocomplete( "search", "" );
 140:                         input.focus();
 141:                     });
 142:  
 143:                     input
 144:                         .tooltip({
 145:                             position: {
 146:                                 of: this.button
 147:                             },
 148:                             tooltipClass: "ui-state-highlight"
 149:                         });
 150:             },
 151:  
 152:             destroy: function() {
 153:                 this.wrapper.remove();
 154:                 this.element.show();
 155:                 $.Widget.prototype.destroy.call( this );
 156:             }
 157:         });
 158:     })( jQuery );
 159:  
 160:     $(function() {
 161:         $( "#combobox" ).combobox();
 162:         $( "#toggle" ).click(function() {
 163:             $( "#combobox" ).toggle();
 164:         });
 165:     });
 166:     </script>
 167: </head>
 168: <body>
 169:  
 170: <div class="ui-widget">
 171:     <label>Your preferred programming language: </label>
 172:     <select id="combobox">
 173:         <option value="">Select one...</option>
 174:         <option value="ActionScript">ActionScript</option>
 175:         <option value="AppleScript">AppleScript</option>
 176:         <option value="Asp">Asp</option>
 177:         <option value="BASIC">BASIC</option>
 178:         <option value="C">C</option>
 179:         <option value="C++">C++</option>
 180:         <option value="Clojure">Clojure</option>
 181:         <option value="COBOL">COBOL</option>
 182:         <option value="ColdFusion">ColdFusion</option>
 183:         <option value="Erlang">Erlang</option>
 184:         <option value="Fortran">Fortran</option>
 185:         <option value="Groovy">Groovy</option>
 186:         <option value="Haskell">Haskell</option>
 187:         <option value="Java">Java</option>
 188:         <option value="JavaScript">JavaScript</option>
 189:         <option value="Lisp">Lisp</option>
 190:         <option value="Perl">Perl</option>
 191:         <option value="PHP">PHP</option>
 192:         <option value="Python">Python</option>
 193:         <option value="Ruby">Ruby</option>
 194:         <option value="Scala">Scala</option>
 195:         <option value="Scheme">Scheme</option>
 196:     </select>
 197: </div>
 198: <button id="toggle">Show underlying select</button>
 199:  
 200:  
 201: </body>
 202: </html>

其中 Line: 32 ~ 158 就是我們要使用地方,而 Line:161 則是將原本下拉選單給置換為 Autocomplete Combobox,接著就是把我們原本所做的 View 進行修改,並且加入並要的內容(jquery.ui.js, jquery.ui.css … etc),為了不影響原本的 _Layout.cshtml 所以另外做了一個專門用來操作使用 jQuery UI 的 layout,

_LayoutIncludeJQueryUI.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    <link href="~/Content/themes/base/jquery-ui.css" rel="stylesheet" />
    @RenderSection("HeadContent", required: false)
</head>
<body>
    @RenderBody()
 
    @Scripts.Render("~/bundles/jquery")
    <script src="~/Scripts/jquery-ui-1.9.2.min.js"></script>
    @RenderSection("scripts", required: false)
</body>
</html>

修改後的 View 內容:

   1: @{
   2:     ViewBag.Title = "Index";
   3:     Layout = "~/Views/Shared/_LayoutIncludeJQueryUI.cshtml";
   4: }
   5: @section HeadContent
   6: {
   7:     <style>
   8:     .ui-combobox {
   9:         position: relative;
  10:         display: inline-block;
  11:     }
  12:     .ui-combobox-toggle {
  13:         position: absolute;
  14:         top: 0;
  15:         bottom: 0;
  16:         margin-left: -1px;
  17:         padding: 0;
  18:         /* adjust styles for IE 6/7 */
  19:         *height: 1.7em;
  20:         *top: 0.1em;
  21:     }
  22:     .ui-combobox-input {
  23:         margin: 0;
  24:         padding: 0.3em;
  25:     }
  26:     </style>    
  27: }
  28:  
  29: <h2>Index</h2>
  30: <p>
  31:     Category:@Html.DropDownList("CategoryList", "-- Select a Category --")
  32: </p>
  33: <p>
  34:     Products:<select id="Products" name="Products"><option>------</option></select>
  35: </p>
  36: @section scripts
  37: {
  38:     <script type="text/javascript">
  39:         $(document).ready(function () {
  40:             $('#CategoryList').change(function (e) {
  41:                 e.preventDefault();
  42:                 CategoryListChangeEventHandler();
  43:             });
  44:  
  45:             //將 CategoryList 下拉選單給置換為 Autocomplete Combobox
  46:             $("#CategoryList").combobox();
  47:         });
  48:  
  49:         function CategoryListChangeEventHandler() {
  50:             var selectedValue = $('#CategoryList option:selected').val();
  51:             if ($.trim(selectedValue).length > 0) {
  52:                 GetProducts($.trim(selectedValue));
  53:             }
  54:         }
  55:  
  56:         function GetProducts(categoryID) {
  57:             $.ajax({
  58:                 type: 'POST',
  59:                 url: '@Url.Action("Products", "Sample")',
  60:                 data: { categoryID: categoryID },
  61:                 dataType: 'json',
  62:                 cache: false,
  63:                 async: false,
  64:                 success: function (response) {
  65:                     if (response.length > 0) {
  66:                         $('#Products').empty();
  67:                         $('#Products')
  68:                             .append($('<option></option>').val('')
  69:                             .text('-- [ ' + $('#CategoryList option:selected').text() + ' ] Products --'));
  70:                         $.each(response, function (i, item) {
  71:                             $('#Products').append($('<option></option>')
  72:                                 .val(item.Key)
  73:                                 .text(item.Value));
  74:                         });
  75:                     }
  76:                 }
  77:             });
  78:         }
  79:  
  80:         (function ($) {
  81:             $.widget("ui.combobox", {
  82:                 _create: function () {
  83:                     var input,
  84:                         that = this,
  85:                         select = this.element.hide(),
  86:                         selected = select.children(":selected"),
  87:                         value = selected.val() ? selected.text() : "",
  88:                         wrapper = this.wrapper = $("<span>")
  89:                             .addClass("ui-combobox")
  90:                             .insertAfter(select);
  91:  
  92:                     function removeIfInvalid(element) {
  93:                         var value = $(element).val(),
  94:                             matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(value) + "$", "i"),
  95:                             valid = false;
  96:                         select.children("option").each(function () {
  97:                             if ($(this).text().match(matcher)) {
  98:                                 this.selected = valid = true;
  99:                                 return false;
 100:                             }
 101:                         });
 102:                         if (!valid) {
 103:                             // remove invalid value, as it didn't match anything
 104:                             $(element)
 105:                                 .val("")
 106:                                 .attr("title", value + " didn't match any item")
 107:                                 .tooltip("open");
 108:                             select.val("");
 109:                             setTimeout(function () {
 110:                                 input.tooltip("close").attr("title", "");
 111:                             }, 2500);
 112:                             input.data("autocomplete").term = "";
 113:                             return false;
 114:                         }
 115:                     }
 116:  
 117:                     input = $("<input>")
 118:                         .appendTo(wrapper)
 119:                         .val(value)
 120:                         .attr("title", "")
 121:                         .addClass("ui-state-default ui-combobox-input")
 122:                         .autocomplete({
 123:                             delay: 0,
 124:                             minLength: 0,
 125:                             source: function (request, response) {
 126:                                 var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
 127:                                 response(select.children("option").map(function () {
 128:                                     var text = $(this).text();
 129:                                     if (this.value && (!request.term || matcher.test(text)))
 130:                                         return {
 131:                                             label: text.replace(
 132:                                                 new RegExp(
 133:                                                     "(?![^&;]+;)(?!<[^<>]*)(" +
 134:                                                     $.ui.autocomplete.escapeRegex(request.term) +
 135:                                                     ")(?![^<>]*>)(?![^&;]+;)", "gi"
 136:                                                 ), "<strong>$1</strong>"),
 137:                                             value: text,
 138:                                             option: this
 139:                                         };
 140:                                 }));
 141:                             },
 142:                             select: function (event, ui) {
 143:                                 ui.item.option.selected = true;
 144:                                 that._trigger("selected", event, {
 145:                                     item: ui.item.option
 146:                                 });
 147:                             },
 148:                             change: function (event, ui) {
 149:                                 if (!ui.item)
 150:                                     return removeIfInvalid(this);
 151:                             }
 152:                         })
 153:                         .addClass("ui-widget ui-widget-content ui-corner-left");
 154:  
 155:                     input.data("autocomplete")._renderItem = function (ul, item) {
 156:                         return $("<li>")
 157:                             .data("item.autocomplete", item)
 158:                             .append("<a>" + item.label + "</a>")
 159:                             .appendTo(ul);
 160:                     };
 161:  
 162:                     $("<a>")
 163:                         .attr("tabIndex", -1)
 164:                         .attr("title", "Show All Items")
 165:                         .tooltip()
 166:                         .appendTo(wrapper)
 167:                         .button({
 168:                             icons: {
 169:                                 primary: "ui-icon-triangle-1-s"
 170:                             },
 171:                             text: false
 172:                         })
 173:                         .removeClass("ui-corner-all")
 174:                         .addClass("ui-corner-right ui-combobox-toggle")
 175:                         .click(function () {
 176:                             // close if already visible
 177:                             if (input.autocomplete("widget").is(":visible")) {
 178:                                 input.autocomplete("close");
 179:                                 removeIfInvalid(input);
 180:                                 return;
 181:                             }
 182:  
 183:                             // work around a bug (likely same cause as #5265)
 184:                             $(this).blur();
 185:  
 186:                             // pass empty string as value to search for, displaying all results
 187:                             input.autocomplete("search", "");
 188:                             input.focus();
 189:                         });
 190:  
 191:                     input
 192:                         .tooltip({
 193:                             position: {
 194:                                 of: this.button
 195:                             },
 196:                             tooltipClass: "ui-state-highlight"
 197:                         });
 198:                 },
 199:  
 200:                 destroy: function () {
 201:                     this.wrapper.remove();
 202:                     this.element.show();
 203:                     $.Widget.prototype.destroy.call(this);
 204:                 }
 205:             });
 206:         })(jQuery);
 207:     </script>
 208: }

上面所修改的內容只有增加 Line:5 ~ 27 的 css style,Line:46 替換下拉選單為 Combobox,以及 Line:80 ~ 206 的 Autocomplete Combobox widget 程式,後端的Controller 內容都不需要做任何的變動,經過修改之後的執行畫面如下:

image

輸入文字,會自動帶出有相關文字的內容選項,

image

如果輸入的文字內容不在原本的下拉選單選項裡,當滑鼠游標點擊頁面的空白處時就會顯示提示訊息,

image

但因為原本的下拉選單 CategoryList 已經被置換為動態產生的「ui-combox」,而原本的 CategoryList 則是被修改為不顯示,如下所示:

image

P.S.
上圖中的綠色文字內容會顯示各個 element 綁定的 event,這是在 Firefox 擴充套件 firebug 的一個外掛功能 FireQuery,在我之前的文章「Firefox 開發前端語言時的偵錯工具 Firebug 以及好用的套件」裡曾經介紹過。

 

image

因為 CategoryList 已經被置換了,原本我們綁在 CategoryList change 事件上面的連動操作就不會有任何的作用啦,這時候的 Combobox 再怎樣去變動與選擇都不會讓 Products 下拉選單有任何的變化,所以就不用在原本的 CategoryList change 事件裡去傷腦筋,哪麼應該怎麼解決讓這個動態產生的 Combobox 一樣有連動下拉選單的功能呢?

 

API 文件,API Document

沒錯,當然是要看 API 文件啦,在 API 文件中寫得相當詳細,讓我們來看看 Autocomplete Widget 的 API Document 內容,

http://api.jqueryui.com/autocomplete/#event-select

image

這邊就直接看 select event 內容:http://api.jqueryui.com/autocomplete/#event-select

image

對照 combobox widget 的程式內容中的 select 事件,

image

這裡是 combobox 選定項目的操作,所以在這邊我們可以判斷是否取得 ui.item.option.value,當有取得選項值之後就可以到後端去取得相關的Products 資料,這樣一來就可以連動處理 Products 下拉選單的內容。

所以這邊就在 select event 裡加了一些程式,

image

而 GetProducts(selectValue) 這邊就是原本 CategoryList change 事件中的程式內容,

image

如此一來在 Combobox 中不管是輸入文字或是使用下拉選擇項目都可以連動改變 Products 下拉選單的內容,

image

 

看到這邊似乎把這問題給解決了,但總是會遇到一點小問題,如果前一個操作有選取到某一個 Category 選項並且改變了 Products 下拉選單的內容,此時輸入一個在 Category Combobox 項目中沒有的文字後, Combobox 會提示沒有符合的項目,但是 Products 下拉選單卻還是停留在上一個 Category 的選擇狀態,依照我的習慣,當提示輸入的文字找不到符合的 Category 項目,應該是要清空 Products 下拉選單的內容,以避免造成操作上的混淆,

image

image

其實要做這個部分的修改其實很簡單,在 combobox widget 程式中的  removeIfInvalid 這個 function 裡去做修改就可以了,另外我們也順便來修改當找不到相符合文字時的提示文字內容,

原本的 removeIfInvalid 內容:

   1: function removeIfInvalid(element) {
   2:     var value = $(element).val(),
   3:         matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(value) + "$", "i"),
   4:         valid = false;
   5:     select.children("option").each(function () {
   6:         if ($(this).text().match(matcher)) {
   7:             this.selected = valid = true;
   8:             return false;
   9:         }
  10:     });
  11:     if (!valid) {
  12:         // remove invalid value, as it didn't match anything
  13:         $(element)
  14:             .val("")
  15:             .attr("title", value + " didn't match any item")
  16:             .tooltip("open");
  17:         select.val("");
  18:         setTimeout(function () {
  19:             input.tooltip("close").attr("title", "");
  20:         }, 2500);
  21:         input.data("autocomplete").term = "";
  22:         return false;
  23:     }
  24: }

修改後:

   1: function removeIfInvalid(element) {
   2:     var value = $(element).val(),
   3:         matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(value) + "$", "i"),
   4:         valid = false;
   5:     select.children("option").each(function () {
   6:         if ($(this).text().match(matcher)) {
   7:             this.selected = valid = true;
   8:             return false;
   9:         }
  10:     });
  11:     if (!valid) {
  12:         // remove invalid value, as it didn't match anything
  13:         $(element)
  14:             .val("")
  15:             .attr("title", "( "+ value + " ) 找不到符合的選項")
  16:             .tooltip("open");
  17:         select.val("");
  18:         setTimeout(function () {
  19:             input.tooltip("close").attr("title", "");
  20:         }, 2500);
  21:         input.data("autocomplete").term = "";
  22:  
  23:         //當找不到相符合的選項時就清空 Products 內容
  24:         $('#Products').empty();
  25:  
  26:         return false;
  27:     }
  28: }

執行結果:

先選一個 Category 選項,讓 Products 下拉選單有內容,

image

接著輸入一個在 Category Combobox 選項中不會相符的文字,

image

清空 Products 下拉選單的內容,

image

 

嗯…… 就這樣!

 

參考連結:

jQuery UI
http://jqueryui.com/

jQuery UI  - Autocomplete Combobox
http://jqueryui.com/autocomplete/#combobox

jQuery UI  API Document - Autocomplete Widget
http://api.jqueryui.com/autocomplete/

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。