2015/8/3

[MVC] MVC5 的 AutoComplete 筆記

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"), 就必須自行給予參數, 而不能採用上面的精簡寫法了, 應該採用註解起來的第二種寫法。

 

沒有留言:

張貼留言