65.9K
CodeProject 正在变化。 阅读更多。
Home

Select2 - 终极 jQuery 自动完成

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (19投票s)

2013年7月22日

CPOL

4分钟阅读

viewsIcon

151114

downloadIcon

6043

终极jQuery自动完成解决方案。通过远程数据源实现无限滚动,以及快速简单的搜索。

引言

我研究过很多可用的AJAX自动完成选项,但大多数选项都或多或少存在不足。

你的选择是:

  1. 在页面上加载少量数据,并让JavaScript对其进行过滤(用户仍然可以滚动浏览数据)。
  2. 通过AJAX查询加载大量数据(但用户无法滚动浏览数据)。

你无法同时做到这两点……直到现在。在我的网站上试用一下该解决方案的在线演示

这得益于Select2 jQuery自动完成插件。虽然它有非常好的文档,但我仍然在.NET MVC环境中启动和运行它时遇到了一些麻烦。为了让入门更容易一些(并鼓励更多人使用这个很棒的插件),我决定创建一个使用此解决方案的示例MVC项目。

背景

本文假定你熟悉jQuery和.NET MVC。如果你正在访问其他人的JSON服务,你只需要jQuery经验即可,但如果你需要创建前端和后端,熟悉.NET MVC也会有所帮助。

这个项目是用Visual Studio 2012 Express构建的。如果你没有,可以免费下载Visual Studio Express

可以在他们的网站上找到Select2设置和代码示例

演示项目需要安装NuGet,因为它会重新下载项目运行所需的依赖项。

代码也可以在GitHub上下载。

使用代码

JavaScript包含文件

要开始使用,请下载最新版本的jQuery以及Select2的CSS和JavaScript。这两个文件也可以通过Visual Studio中的NuGet下载。

<link href="~/Content/css/select2.css" type="text/css" rel="stylesheet" />
<script src="~/Scripts/jquery-2.0.3.js"></script>
<script src="~/Scripts/select2.js"></script> 

要在前端实现此功能,你需要:

  1. 带有id的文本框来标识它。这是Select2将在页面上加载json查询结果的区域。
  2. 你的JSON服务的URL。我们将在这里查找下拉列表的更多数据。
  3. 配置设置来确定你希望它如何工作(运行查询之前的延迟、返回的结果数量等)。

JavaScript的核心代码如下:

//The url we will send our get request to
var attendeeUrl = '@Url.Action("GetAttendees", "Home")';
var pageSize = 20;

$('#attendee').select2(
{
    placeholder: 'Enter name',
    //Does the user have to enter any data before sending the ajax request
    minimumInputLength: 0,            
    allowClear: true,
    ajax: {
        //How long the user has to pause their typing before sending the next request
        quietMillis: 150,
        //The url of the json service
        url: attendeeUrl,
        dataType: 'jsonp',
        //Our search term and what page we are on
        data: function (term, page) {
            return {
                pageSize: pageSize,
                pageNum: page,
                searchTerm: term
            };
        },
        results: function (data, page) {
            //Used to determine whether or not there are more results available,
            //and if requests for more data should be sent in the infinite scrolling
            var more = (page * pageSize) < data.Total; 
            return { results: data.Results, more: more };
        }
    }
}); 

我们用来存储数据的html文本框如下所示:

 <input id="attendee" name="AttendeeId" type="text" value="" /> 

这实际上是在前端实现此功能所需的一切。如果你还需要设置后端,事情会变得稍微复杂一些,但这并不是我们无法处理的。

设置JSON服务

我们需要以某种格式从后端向Select2发送数据。基本上,我们需要为返回的每个结果发送一个idtext值。我们还需要返回所有返回结果的总数

这样,当我们开始滚动浏览数据时,Select2就知道它是否需要继续请求更多数据,或者我们是否已经到达结果的末尾。

因此,我们将创建用于保存结果的类如下所示:

public class Select2PagedResult
{
    public int Total { get; set; }
    public List<Select2Result> Results { get; set; }
}
public class Select2Result
{
    public string id { get; set; }
    public string text { get; set; }
} 

返回JSON的方法将转到我们的数据存储区,获取与下拉列表中键入的搜索词匹配的任何参与者,然后将数据转换为Select2PagedResult类,然后将其作为JSON结果发送回浏览器。

[HttpGet]
public ActionResult GetAttendees(string searchTerm, int pageSize, int pageNum)
{
    //Get the paged results and the total count of the results for this query. 
    AttendeeRepository ar = new AttendeeRepository();
    List<Attendee> attendees = ar.GetAttendees(searchTerm, pageSize, pageNum);
    int attendeeCount = ar.GetAttendeesCount(searchTerm, pageSize, pageNum);

    //Translate the attendees into a format the select2 dropdown expects
    Select2PagedResult pagedAttendees = AttendeesToSelect2Format(attendees, attendeeCount);       

    //Return the data as a jsonp result
    return new JsonpResult
    {
        Data = pagedAttendees,
        JsonRequestBehavior = JsonRequestBehavior.AllowGet
    };
} 

从我们的数据存储区获取测试数据、搜索姓名中的姓和名,并将结果转换为Select2PagedResult类的所有代码都包含在示例项目中。

性能

值得付出所有这些努力吗?如果你的数据列表很小,可能不值得。对于包含100个或更少项目的列表,Select2中的默认JavaScript过滤速度足够快,并且设置起来更容易(只有几行代码)。

在我的演示示例中,代码可以快速轻松地过滤包含1000个参与者的列表,因为所有繁重的工作都是由服务器完成的,JavaScript一次只需要显示20个结果。在这种情况下,使用远程数据源设置Select2将值得你投入的时间。

历史

  • 2013年7月22日 - 发布代码。
© . All rights reserved.