侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

使用JQuery自动完成插件Auto Complete详解

前端  /  管理员 发布于 5年前   361

问题

当你查找一些特殊的东西,当你输入准确的词时,找到它可能是困难的(或者很耗时)。在输入的时候展示出结果(自动完成),使查找变得更简单。

解决方案

使用JQuery自动完成插件,更新现有图书列表页面上的搜索,当用户键入的时候立即显示结果。

讨论

自动完成插件是不会象jQuery基本库一样自动包含在MVC项目中的,所以需要做的第一件事就是的是下载插件
访问http://jquery.com/。两个主要的文件是必需的:JavaScript文件和CSS文件。把新下载的javascript文件放到你MVC应用程序的script 文件夹下。CSS文件可以直接添加到您的content目录。

这个配方也将介绍在view中使用 rendering sections。在shared文件夹下layout中自动添加了2个javascript文件和1个css文件。这些是Ajax和不唐突的Ajax和网站主css文件。每次加载的内容越多,页面视图加载越慢。与其在每个页面都去包含可能不必要的javascript和css 文件,不如在layout中添加一个新的RenderSection()。这允许特别的view在标签去加载特别的javascript或css,但不是每页都添加他们。

下边是一个更新后的Views/Shared/_Layout.cshtml,他使用了一个新的RenderSection()。

_Mobile@RenderSection("JavaScriptAndCSS", required: false)

My MVC Application

@Html.Partial("_LogOnPartial")[ @Html.ActionLink("English", "ChangeLanguage", "Home", new { language = "en" }, null) ][ @Html.ActionLink("Français", "ChangeLanguage", "Home", new { language = "fr" }, null) ]
  • @Html.ActionLink("Home", "Index", "Home", null, new Dictionary {{ "data-role", "button" }})
  • @Html.ActionLink("About", "About", "Home", null, new Dictionary { { "data-role", "button" }})
@RenderBody()

主要的CSS文件和核心的JQuery文件被留下来了,因为css在每个也都需要,并且绝大多数网页也需要JQuery。然而新的JQuery文件和不唐突的AJAX不是每个页面都需要的。

现在,有两种方式使用Autocomplete 插件:

1.在javascript中设置要搜索的数据。

2.当用户输入时通过ajax检索。

在我使用这个插件的经验看来,我发现使用解决方案1时自动完成更快。因为它并不需要每次从数据库中请求数据。然而,使用这种解决方案的限制:只有这么多字符,可传递到function中,大量的JavaScript可能会导致用户的计算机上页面加载缓慢。经过一些试验和错误,我已经确定神奇的数字是大约40,000个结果。如果结果数量超过此,最好使用选项2;否则,始终坚持,因为搜索选项1是瞬时,而不是有轻微的延迟。

在这个例子中,将搜索书籍,我们没有超过40000,所以将使用选项1。BooksController现在必须更新,以设置ViewBag为book title。自动完成功能需要支持一个JavaScript数组的支持,所以书将管道(|)分开。然后在view中,书将被转换到一个数组,使用JavaScript的split()函数。当用户完成键入他们的结果,他们应该有选择完全匹配标题,因此这个函数将被更新。如果只有1本书返回并且用户执行了搜索,它会自动重定向到本书详细介绍页面。

我们要在bookcontroller 中更新Index Action 并添加一个私有方法名为:FormatBooksForAutocomplete。

代码如下:

using System;using System.Collections.Generic;using System.Data;using System.Data.Entity;using System.Linq;using System.Linq.Dynamic;using System.Web;using System.Web.Mvc;using MvcApplication.Models;using MvcApplication.Utils;using PagedList;namespace MvcApplication.Controllers{ public class BooksController : Controller{private BookDBContext db = new BookDBContext();//// GET: /Books/[OutputCache(Duration = Int32.MaxValue, SqlDependency = "MvcApplication.Models.BookDBContext:books", VaryByParam = "sortOrder;filter;page")]public ActionResult Index(string sortOrder, string filter, string Keyword, int page = 1){#region ViewBag ResourcesViewBag.Title = Resources.Resource1.BookIndexTitle;ViewBag.CreateLink = Resources.Resource1.CreateLink;ViewBag.TitleDisplay = Resources.Resource1.TitleDisplay;ViewBag.IsbnDisplay = Resources.Resource1.IsbnDisplay;ViewBag.SummaryDisplay = Resources.Resource1.SummaryDisplay;ViewBag.AuthorDisplay = Resources.Resource1.AuthorDisplay;ViewBag.ThumbnailDisplay = Resources.Resource1.ThumbnailDisplay;ViewBag.PriceDisplay = Resources.Resource1.PriceDisplay;ViewBag.PublishedDisplay = Resources.Resource1.PublishedDisplay;ViewBag.EditLink = Resources.Resource1.EditLink;ViewBag.DetailsLink = Resources.Resource1.DetailsLink;ViewBag.DeleteLink = Resources.Resource1.DeleteLink;#endregion#region ViewBag Sort ParamsViewBag.TitleSortParam = (sortOrder == "Title") ? "Title desc" : "Title";ViewBag.IsbnSortParam = (sortOrder == "Isbn") ? "Isbn desc" : "Isbn";ViewBag.AuthorSortParam = (sortOrder == "Author") ? "Author desc" : "Author";ViewBag.PriceSortParam = (sortOrder == "Price") ? "Price desc" : "Price";ViewBag.PublishedSortParam = (String.IsNullOrEmpty(sortOrder)) ? "Published desc" : "";// Default the sort orderif (String.IsNullOrEmpty(sortOrder)){sortOrder = "Published desc";}ViewBag.CurrentSortOrder = sortOrder;#endregionvar books = from b in db.Books select b;#region Keyword Searchif (!String.IsNullOrEmpty(Keyword)){books = books.Where(b => b.Title.ToUpper().Contains(Keyword.ToUpper()) || b.Author.ToUpper().Contains(Keyword.ToUpper()));// Should we redirect because of only one result?if (books.Count() == 1){Book book = books.First();return RedirectToAction("Details", new { id = book.ID });}}ViewBag.CurrentKeyword = String.IsNullOrEmpty(Keyword) ? "" : Keyword;#endregion#region Filter switchswitch (filter){case "NewReleases":var startDate = DateTime.Today.AddDays(-14);books = books.Where(b => b.Published <= DateTime.Today.Date && b.Published >= startDate);break;case "ComingSoon":books = books.Where(b => b.Published > DateTime.Today.Date);break;default:// No filter neededbreak;}ViewBag.CurrentFilter = String.IsNullOrEmpty(filter) ? "" : filter;#endregionbooks = books.OrderBy(sortOrder);int maxRecords = 1;int currentPage = page - 1;// Get all book titlesViewBag.BookTitles = FormatBooksForAutocomplete();return View(books.ToPagedList(currentPage, maxRecords));}private string FormatBooksForAutocomplete(){string bookTitles = String.Empty;var books = from b in db.Books select b;foreach (Book book in books){if (bookTitles.Length > 0){bookTitles += "|";}bookTitles += book.Title;}return bookTitles;}//// GET: /Books/Details/5public ActionResult Details(int id = 0, string bookTitle = ""){Book book = db.Books.Find(id);return View(book);}//// GET: /Books/Createpublic ActionResult Create(){return View();} //// POST: /Books/Create[HttpPost]public ActionResult Create(Book book, HttpPostedFileBase file){if (ModelState.IsValid){// Upload our filebook.Thumbnail = FileUpload.UploadFile(file);db.Books.Add(book);db.SaveChanges();return RedirectToAction("Index"); }return View(book);}//// GET: /Books/Edit/5public ActionResult Edit(int id){Book book = db.Books.Find(id);return View(book);}//// POST: /Books/Edit/5[HttpPost]public ActionResult Edit(Book book, HttpPostedFileBase file){if (ModelState.IsValid){// Delete old fileFileUpload.DeleteFile(book.Thumbnail);// Upload our filebook.Thumbnail = FileUpload.UploadFile(file);db.Entry(book).State = EntityState.Modified;db.SaveChanges();return RedirectToAction("Index");}return View(book);}//// GET: /Books/Delete/5public ActionResult Delete(int id){Book book = db.Books.Find(id);return View(book);}//// POST: /Books/Delete/5[HttpPost, ActionName("Delete")]public ActionResult DeleteConfirmed(int id){ Book book = db.Books.Find(id);// Delete old fileFileUpload.DeleteFile(book.Thumbnail);db.Books.Remove(book);db.SaveChanges();return RedirectToAction("Index");}protected override void Dispose(bool disposing){db.Dispose();base.Dispose(disposing);}}}

最后book/index view需要更新去初始化jQuery的自动完成。要做的第一件事是使用@节标记,包括必要的JavaScript和CSS文件。接下来,以前创建的搜索文本框更新设置一个键的IDwordSearch。

最后,JavaScript代码添加在视图的底部去在搜索文本框上建立自动完成功能。此JavaScript是有意添加在view的底部,以确保完全呈现给用户,因为在用户的电脑上建立数据是一项工作,Javascript处理可能会“堵塞”页面加载。

(译者:先呈现数据再执行javascript,js不是像传统那样放在head标签里)

这取决于结果的数量。代码如下:

@model PagedList.IPagedList@if (IsAjax){Layout = null;}@section JavascriptAndCSS {}

@MvcApplication4.Resources.Resource1.BookIndexTitle

@Html.ActionLink("Create New", "Create")

Show:@if (ViewBag.CurrentFilter != ""){@Ajax.ActionLink("All", "Index", new { sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })}else{@:All}  |  @if (ViewBag.CurrentFilter != "NewReleases"){@Ajax.ActionLink("New Releases", "Index", new { filter = "NewReleases", sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })}else{@:New Releases}  |  @if (ViewBag.CurrentFilter != "ComingSoon"){@Ajax.ActionLink("Coming Soon", "Index", new { filter = "ComingSoon", sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })}else{@:Coming Soon}

@using (Html.BeginForm()){@:Search: @Html.TextBox("Keyword", (string)ViewBag.CurrentKeyword, new { id = "KeywordSearch" }) }@Html.Partial("_Paging")@foreach (var item in Model){}
@Ajax.ActionLink("Title", "Index", new { sortOrder = ViewBag.TitleSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })@Ajax.ActionLink("Isbn", "Index", new { sortOrder = ViewBag.IsbnSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })Summary@Ajax.ActionLink("Author", "Index", new { sortOrder = ViewBag.AuthorSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })Thumbnail@Ajax.ActionLink("Price", "Index", new { sortOrder = ViewBag.PriceSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })@Ajax.ActionLink("Published", "Index", new { sortOrder = ViewBag.PublishedSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }, new AjaxOptions { UpdateTargetId = "main" })
@Html.DisplayFor(modelItem => item.Title)@Html.DisplayFor(modelItem => item.Isbn)@Html.DisplayFor(modelItem => item.Summary)@Html.DisplayFor(modelItem => item.Author)@Html.DisplayFor(modelItem => item.Thumbnail)@Html.DisplayFor(modelItem => item.Price)@Html.DisplayFor(modelItem => item.Published)@Html.ActionLink("Edit", "Edit", new { id = item.ID }) |@Html.ActionLink("Details", "Details", new { id = item.ID }) |@Html.ActionLink("Delete", "Delete", new { id = item.ID })
@Html.Partial("_Paging")

为了实施选项2,一个Ajax搜索,而不是传递数据数组到自动完成函数,您可以传递一个URL。URL将需要接受查询字符串变量:q。这包含用户输入的搜索值。这将用于执行书本上包含部分匹配的搜索,并返回以分隔符分隔的字符串。JQuery文档中含有较多的这样的成品例子,也有其他的例子,去更新的输出结果(可能包括书的封面的缩略图)。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:

  • Jquery的autocomplete插件用法及参数讲解
  • jQuery插件autocomplete使用详解
  • jQuery autoComplete插件两种使用方式及动态改变参数值的方法详解
  • jquery插件autocomplete用法示例
  • PHP结合jQuery.autocomplete插件实现输入自动完成提示的功能
  • jQuery 插件autocomplete自动完成应用(自动补全)(asp.net后台)
  • 小试JQuery的AutoComplete插件
  • jquery autocomplete自动完成插件的的使用方法


  • 上一条:
    使用异步controller与jQuery实现卷帘式分页
    下一条:
    利用vue-i18n实现多语言切换效果的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客