Xây dựng Autocomplete Textbox trong Asp.Net MVC với Jquery TypeHead

Trong ví dụ này mình sẽ chia sẻ với các bạn về cách xây dựng tính năng Autocomplete Texbox trên Asp.Net MVC5 với  jQuery Typeahead . Với sự hỗ trợ của JqueryTypeHead chúng ta có thể xây dựng được một tính năng gọi ý tìm kiếm nâng cao, cho phép với mỗi từ khóa người dùng gõ trên ô tìm kiếm, sẽ đưa ra được một danh sách gợi ý phân loại một cách rất trực quan và rõ ràng.

Các bạn xem hình trên, ví dụ khi người dùng gõ từ khóa "samsung" thì gợi ý tìm kiếm sẽ phân biệt ra là đang muốn tìm theo tên điện thoại "phone" hay tìm theo hãng điện thoại "brand". Từ đó người dùng sẽ có được một cái nhìn trực quan hơn trong tìm kiếm, và chức năng gọi ý tìm kiếm autocomplete sẽ mang lại hiệu quả cao hơn trong trường hợp này.

 

1. Download jQuery Typeahead 

Các bạn có thể tìm hiểu về thư viện này và download về tại link sau: 
http://www.runningcoder.org/jquerytypeahead/

 

2. Tích hợp jQuery Typeahead  vào project

Trong page _Layout.cshtml ta chỉ cần kéo css vào phần <head>

<link href="~/Content/jquery.typeahead.min.css" rel="stylesheet" />

Và file javascript vào phía cuối trang

<script src="~/Scripts/jquery.typeahead.min.js"></script>

 

3. Tạo Database 

Đâu tiên chúng ta tạo 1 database với dữ liệu test, sau đó sẽ viết hàm API lấy dữ liệu suggest từ database này.

Trong source code ví dụ đính kèm cuối bài viết, các bạn chạy file ~/ScriptDatabase/ScriptDatabase.sql để tạo Database

 

4. Viết hàm API lấy dữ liệu suggest

Chúng ta có thể cung cấp dữ liệu gợi ý cho jQuery Typeahead dưới dạng json data (xem thêm tại đây), do vậy với Database test vừa tạo ở trên, chúng ta cần viết 1 hàm trả về json data cho jQuery Typeahead

HomeController.cs

//init data for autocomplete filter
        public JsonResult GetValueAutoComplate()
        {
            AutoCompleteView returnObj = new AutoCompleteView();
            using (var db = new AutoComplateDatabaseEntities())
            {
                returnObj.Phones = new List<ItemView>();
                var queryPhone = from p in db.Phones
                                 join b in db.Brands on p.BrandId equals b.Id
                                 select new ItemView()
                                 {
                                     Id = p.Id,
                                     Name = p.Name,
                                     Description = p.Description + " " + b.Name
                                 };
                returnObj.Phones = queryPhone.ToList();

                returnObj.Brands = new List<ItemView>();
                var queryBrand = from b in db.Brands
                                 select new ItemView()
                                 {
                                     Id = b.Id,
                                     Name = b.Name,
                                     Description = b.Description
                                 };
                returnObj.Brands = queryBrand.ToList();
            }
            return Json(returnObj, JsonRequestBehavior.AllowGet);
        }

Tạo class ~/Models/AutoCompleteView.cs cho hàm trên.

AutoCompleteView.cs

using System.Collections.Generic;
namespace AutoCompleteSearch.Models
{
    public class AutoCompleteView
    {
        public List<ItemView> Phones { set; get; }//iphone 4, iphone 5, samsung galaxy s8...
        public List<ItemView> Brands { set; get; }//apple, samsung, xixaomin
    }
    public class ItemView
    {
        public int Id { set; get; }
        public string Name { set; get; }
        public string Description { set; get; }
        public string Icon { set; get; }
    }
}

 

5. Tích hợp jQuery Typeahead vào page

Và cuối cùng ta cần đưa form search của jQuery Typeahead vào trên trang (nơi bạn muốn đặt form tìm kiếm), ví dụ này mình sẽ để form search ở page index.cshtml

Index.cshtml

@model AutoCompleteSearch.Models.IndexView

@{
    ViewBag.Title = "Home Page";
}

<h2>Auto complete search with jquery-typehead</h2>
<hr />
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <div class="row">
        <div class="col-md-3">
            @*Input auto complete*@
            <div class="typeahead__container">
                <div class="typeahead__field">

                    <span class="typeahead__query">
                        <input class="js-typeahead"
                               name="q"
                               type="search"
                               placeholder="Enter product name or brand"
                               autocomplete="off">
                    </span>
                </div>
            </div>

            @*hidden value for search*@
            @Html.HiddenFor(x=>x.Keyword, new { @id= "Keyword" })
            @Html.HiddenFor(x => x.Type, new { @id = "TypeSearch" })
        </div>
        <div class="col-md-4">
            @*Submit button*@
            <input type="submit" name="submit" value="Search" class="btn btn-primary" />
        </div>
    </div>
}

Chúng ta cần tạo thêm class ~/Models/IndexView.cs để lưu trạng thái tìm kiếm lựa chọn và từ khóa tìm kiếm

IndexView.cs

namespace AutoCompleteSearch.Models
{
    public class IndexView
    {
        public string Type { set; get; }
        public string Keyword { set; get; }
    }
}

Tiếp theo ta cần thêm hàm javascript của jQuery Typehead để thực hiện việc lấy dữ liệu tìm kiếm và hiện thị gợi ý ngay dưới textbox search

Index.cshtml

@section scripts{
    <script>
        $.typeahead({
            input: ".js-typeahead",
            order: "asc",
            hint: true,
            group: {
                template: "{{group}}"
            },
            maxItemPerGroup: 5,
            template: function (query, item) {
                return "<div class='suggest-item'>{{Name}} - <small>{{Description}}</small></div>";
            },
            source: {
                "Phones": {
                    ajax: {
                        url: "/Home/GetValueAutoComplate",
                        path: "Phones"
                    },
                    display: "Name"
                },
                "Brands": {
                    ajax: {
                        url: "/Home/GetValueAutoComplate",
                        path: "Brands"
                    },
                    display: "Name"
                }
            },
            callback: {
                onClickAfter: function (node, a, item, event) {
                    $('#TypeSearch').val(item.group);
                    $('#Keyword').val(item.Name);
                }
            }
        });
    </script>
}

Ở hàm trên, trong sự kiện onClickAfter ta cần lưu lại từ khóa #Keyword và kiểu tìm kiếm #TypeSearch (Tìm theo tên sản phẩm, hay tìm theo loại sản phẩm) lại để xử lý cho việc redirect đến trang tìm kiếm phù hợp.

Ví dụ khi người dùng thực hiện tìm kiếm với gợi ý autocomplete hiện ra, sẽ xẩy ra 3 trường hợp sau:

  • Người dùng click vào tên sản phẩm trên ô gợi ý -> Redirect sang trang SearchPhone.cshtml (nếu sản phẩm là duy nhất thì có thể xử lý redirect đến page ProductDetail.cshtml)
  • Người dùng click vào tên loại sản phẩm trên ô gợi ý -> Redirect sang trang SearchBrand.cshtml
  • Người dùng không click vào gợi ý tìm kiếm mà gõ từ khóa rồi click search -> Redirect sang trang SearchAll.cshtml

Với 3 trường hợp có thể xẩy ra ở trên, ta sẽ viết hàm xử lý redirect ở HomeController như sau (xử lý tìm kiếm khi người dùng click button Search)

HomeController.cs

[HttpPost, ValidateAntiForgeryToken]
        public ActionResult Index(IndexView obj)
        {
            if (obj.Type == "Phones")
                return RedirectToAction("SearchPhone", "Home", new { keyword = obj.Keyword });
            else if (obj.Type == "Brands")
                return RedirectToAction("SearchBrand", "Home", new { keyword = obj.Keyword });
            else
                return RedirectToAction("SearchAll", "Home", new { keyword = obj.Keyword });
        }

        public ActionResult SearchAll(string keyword)
        {
            return View();
        }

        public ActionResult SearchPhone(string keyword)
        {
            return View();
        }

        public ActionResult SearchBrand(string keyword)
        {
            return View();
        }

Lúc đó, với dữ liệu tìm kiếm trả về tương ứng với mỗi trường hợp tìm kiếm, các bạn có thể xử lý tìm kiếm và hiện thị kết quả cho phù hợp.

Các bạn có thể xem demo ngay trên chức năng tìm kiếm của blog hiện tại của mình (Mình vừa tích hợp vào ô tìm kiếm của blog)

Hoặc download source code của ví dụ này dưới đây

Xem thêm: Autocomplete với jQuery

 

Download Source

Related Post


File Upload trong Asp.Net MVC sử dụng DropZone
Monday, July 3, 2017
Trước đây mình có làm một ví dụ tích hợp DropZone để xây dựng chức năng Upload Multiple File trong WebForm, hôm nay mình chia sẻ thêm một ví dụ về cách tích hợp DropZone vào Asp.Net MVC
Đếm số ngươi Online website với SignalR
Wednesday, June 28, 2017
SignalR là một thư viện cho phép các lập trình viên .Net đơn giản hóa việc xây dựng các chức năng xử lý real-time trong quá trình phát triển ứng dụng. Nó cho phép server đẩy nội dung tới client một cách tức thì ngay khi có sự kiện xẩy ra, chứ không phải server đợi client yên cầu rồi trả về nội dung tương ứng như giao thức HTTP truyền thống. Trong ví dụ này mình làm một chức năng nhỏ đó là đếm số người online trên website với SignalR, ngay khi có người connect vào website, server sẽ nhận biết và trả về client ngay lập tức.
Search

Category

Blog Archive

Đăng ký nhận bài mới

Facebook Page