[MVC] MVC5 的 AutoComplete 筆記

ASP.NET MVC 的版本雜沓, 我時常遇到過去慣用的程式碼在新版本中突然無法使用的情況。最近想在一個案子裡套用許久未用的 AutoComplete 功能, 但是當拿出舊的程式來用時, 卻發現完全無效! 翻了幾本書, 發現都是舊的, 情況完全一樣。情急之下, 上網東查西查, 結果發現有時不太看得出來網路上的範例到底是新是舊, 而且也都全部無效。直到現在, 我還是搞不懂, 為什麼以前天天在用的程式, 什麼時候突然不能用了, 而且我真看不出來到底是哪裡被改了? 這幾年間, 我到底是哪裡沒有 follow 到...

ASP.NET MVC 的版本雜沓, 我時常遇到過去慣用的程式碼在新版本中突然無法使用的情況。最近想在一個案子裡套用許久未用的 AutoComplete 功能, 但是當拿出舊程式來用時, 卻發現完全無效! 翻了幾本書, 發現都是舊的, 情況完全一樣。情急之下, 上網東查西查, 結果發現有時不太看得出來網路上的範例到底是新是舊, 而且也都全部無效。直到現在, 我還是搞不懂, 為什麼以前天天在用的程式, 什麼時候突然不能用了, 而且我真看不出來到底是哪裡被改了。這幾年間, 似乎有什麼東西沒有 follow 到。

不管如何, 靠著一股絕不死心的熱情, 手上的唯一武器就是 trial and error, 我最終還是把事情解決了。時間說久不久, 好歹也花了一上午, 所以我把我的發現寫在這裡當作備忘, 免得以後又忘了。但是到底是哪裡改了什麼, 容我暫且保留, 因為我真的還沒有研究出什麼值得向大家報告的心得, 手上的事情又多; 如果讀者們有興趣, 或許可以自己去研究看看。

我要做的事情很簡單, 只是在 MVC 網頁裡讓一個普通的 TextBox 提供 AutoComplete 功能罷了。

我在同一個 Controller 中 (在本例中是 /Controllers/TrackerController.cs, 路徑是 /Tracker/Index/) 加入了一個名為 QueryEmployees 的 Action:

public JsonResult QueryEmployees(string term)
{
    var items = Employee.GetEmployees();
    var filteredItems = items.Where(
        item => item.StartsWith(term));
    return Json(filteredItems.DefaultIfEmpty(), JsonRequestBehavior.AllowGet);
}

這裡 items 事實上是從其它程式來的 List<Employee> 物件 (cached)。所以上述方法很單純, 只是把資料篩選之後再輸出而已。

View 裡面的寫法則是這樣的:

<input type="text" id="txtEmployeeId" placeholder="請輸入員工編號" />
...
@section Scripts {
<script type="text/javascript">
    $('#txtEmployeeId').autocomplete({
        source: "/Tracker/QueryEmployeeId",
        minLength: 6,
        delay: 100
    });
    // 以下是另一種寫法
    // $('#txtRetailerId').autocomplete({
    //    source: function (request, response) {
    //        var rId = $('#txtEmployeeId').val();
    //        $.getJSON('/Tracker/QueryEmployeeId/?id=' + rId, null, function (data) {
    //            response(data);
    //        })
    //    },
    //    minLength: 6,
    //    delay: 100
    // });
</script>

此外, 還有幾個檔案必須 bundle 輸出:

1. jquery-ui.js 這個檔案應該在 BundleConfig.cs 中包裝載入
 

bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
            "~/Scripts/jquery-ui.js"));

2. jquery-ui.css 這個檔案也應該在 BundleConfig.cs 中和其它既有的檔案一起包裝載入
 

bundles.Add(new StyleBundle("~/Content/css").Include(
         "~/Content/bootstrap.css",
         "~/Content/jquery-ui.css",
         "~/Content/site.css"));

3. 上面定義過的 jqueryui 必須在頁面中做 render (我是寫在 _Layout.cshtml 裡):

    @Scripts.Render("~/bundles/jqueryui")

按照以上各步驟中各種寫法, AutoComplete 的結果是正確的。如果任何一個地方沒有照著這樣做或這樣寫, 就不會出現搜尋結果。例如, Action 方法的參數一定要叫做 "term"; 如果你將它命名為其它名稱 (例如 "id"), 就必須自行給予參數, 而不能採用上面的精簡寫法了, 應該採用註解起來的第二種寫法。

 


Dev 2Share @ 點部落