jq 之Autocomplete 引发联想及思考
前情纪要:JQuery UI 是以 JQuery 为基础的开源 JavaScript 网页用户界面代码库。包含底层用户交互、动画、特效和可更换主题的可视控件,这些控件主要包括:Accordion,Autocomplete,ColorPicker,Dialog,Slider,Tabs,DatePicker,Magnifier,ProgressBar,Spinner等,其中Autocomplete能够非常容易的帮我们实现类似于百度搜索的智能提示功能。
我现在要实现的是在订单中心下单时,实现通过输入客户名智能查询出客户详细信息(只展示客户名,电话或证件号并实现自动加载到页面选中的数据详情)。
原版实现:指定标签(input)输入时或者单击标签时获取到数据源展示课选中。
1:图片展示:
2:底层代码示例:
public JsonResult GetMemberListByName(string name = "")
{
var pagesize = Convert.ToInt32(Request["limit"]);//每页多少行,autocomplete页面js设定,总是获取第一页
return Json(this.CRMService.ListMember(new MemberRequest
{
ContainsNameOrMobile = name,
CommercialTenantID = this.LoginInfo.CommercialTenantID,
isType = true,
PageIndex = ,
PageSize = pagesize
}).ToList(), JsonRequestBehavior.AllowGet);
}
3:js代码示例:
//页面
<div class="form-group">
<label class="control-label">
会员:</label>
<input id="vipID" class="form-control" style="width: 160px;" placeholder="会员姓名/手机号" />
</div>
//js
$('#vipID').autocomplete('/CommercialTenant/CRM/GetMemberListByName', {
max: , //列表里的条目数
minChars: , //自动完成激活之前填入的最小字符
width: , //提示的宽度,溢出隐藏
scrollHeight: , //提示的高度,溢出显示滚动条
matchContains: true, //包含匹配,就是data参数里的数据,是否只要包含文本框里的数据就显示
autoFill: false, //自动填充
extraParams: { name: function () { return $('#vipID').val(); } },
dataType: 'json',
parse: function (data) {
return $.map(eval(data), function (row) {
return {
data: row,
value: row.Mobile,
result: row.Mobile
}
}); //对ajax页面传过来的数据进行json转码
},
formatItem: function (row, i, max) {
return i + '/' + max + ': ' + row.Name + ' [' + row.Mobile + ']';
},
formatMatch: function (row, i, max) {
return row.Name + row.Mobile;
},
formatResult: function (row) {
return row.Mobile;
}
}).result(function (event, row, formatted) {
$("#UserID").val(row.ID);
$("#vipID").val(row.Name + "[" + row.Mobile + "]");
$("#vipID2").val(row.Name + "[" + row.Mobile + "]");
});
但是代码是copy别人的自己没有啥子理解,突然想起来有个同事说:我们最大的缺点就是“不求甚解”,让他说中了。
今天要在另一个页面实现类似的功能,就又copy了一下,但是却有一些问题导致功能不能实现:
问题如下:多个输入框要实现同样的数据加载。以前是直接指定标签绑定并且传值也是指定的标签,但是现在是要动态绑定事件并且拿对应标签的值。
想起来也不难,就是通过js 中的this 对象就可以获取到当前的事件绑定标签的值。但是在autocomplete 方法中this对象获取到的this对象是window(当前窗体)。
js采用面向对象方法书写(最近才在一个原同事的分享会上学习到的)采用live方法绑定可以实现类似于click方法的动态绑定,这也是今天自己实在是逼得不行了采取主动学习这部分的知识,学习js标签绑定原理后才知道的方法。(心理活动:每天都告诉要学习一点知识,但是有时候还是不求甚解,这种心态是一个程序员成长的最大敌人。)
解决问题一:动态加载标签后自动调用已声明的js 方法再绑定一次autocomplete方法(还没有试验通过live方法绑定autocomplete,明天可以尝试用一下)。
解决问题二:向后台传值问题。原先是通过标签选择器获取指定的标签值获取其value。现在标签时动态加载的尝试使用this对象获取失败后另寻它径。准备换change事件然后通过ajax方法实现,试验后发现可以拿到数据,但是实现的效果对比于百度搜索的样式有一些差距,并且很麻烦(这是一条可行的方法,但是与最初的预期有一些偏差,人生就是一个个选择,在不同的路口选择不同的方向,技术之路也一样)。转而再次研究autocomplete方法。
通过阅读官方文档发现,其实autocomplete其实有三种不同额数据源获取方法,我们是采用了其中调用本方法get请求到数据然后解析,还有人通过xml、session都能实现同样的功能,另外一种先在ajax中获取数据源,在成功方法中调用autocomplete方法,真是一个好的思路,最后的方法我回想感觉类似于我刚才的上一次尝试通过change方法ajax拿数据,然后处理。继续研究,当我看别人博客看到下面文字的时候如梦惊醒:
formatItem: function(row, i, max) { } //结果中的每一行都会调用这个函数,返回值将用LI元素包含,显示在下拉列表中. 三个参数(row, i, max): 返回的结果数组, 当前处理的行数(从1开始), 当前结果数组元素的个数. Default: none, 表示不指定自定义的处理函数. formatResult : function(row, i, max) { } //和formatItem类似,但可以将将要输入到input文本框内的值进行格式化.同样有三个参数,和formatItem一样.Default: none,表示要么是只有数据,要么是使用formatItem提供的值. formatMatch: function(row) { } //对每一行数据使用此函数格式化需要查询的数据格式. 返回值是给内部搜索算法使用的. 参数值row result (function(event, data, formatted){}) //此事件会在用户选中某一项后触发,参数为:event: 事件对象, data: 选中的数据行,formatted:formatResult函数返回的值;
这是四个插件内的方法,原版实现中有用到,但是如果没有去研究绝对不会知道它们每一个是什么作用,现在才知道了formatitem方法内是对数据源处理显示下拉列表;result方法是选中一行后执行的逻辑。(又一次感叹毛主席说的话“一天不学习,赶不上刘少奇”,是多么正确的。)
看到这些熟悉的方法之后我就有预感今天这个问题能解决(我已经研究了近一个半小时了),于是我又对所有参数进行了一次学习,黄天不负苦心人。
extraParams (Object): //为后台(一般是服务端的脚本)提供更多的参数.和通常的作法一样是使用一个键值对对象.如果传过去的值是{ bar:4 },将会被autocompleter解析成my_autocomplete_backend.php?q=foo&bar=4 (假设当前用户输入了foo). Default: {}
我们原程序中传值name:'',这里写到{bar:4} ,被autocompleter解析成my_autocomplete_backend.php?q=foo&bar=4 (假设当前用户输入了foo),
当我看到假设当前用户输入了foo,并且q=foo之后我就断定,后台接收的参数中必定有一个q,于是我在后台接收方法中调用 Request["q"],果然获取到了在页面标签内输入的值,
并且在request对象中又两个默认的参数:limit 代表每页数据(js中有设定,由此反思到以前获取数据源的方法是没有做数据分页的),temp...时间戳(具体单词记不住了),由此解决了我的这个问题。
最后还是通过努力,用原方法实现出了最初的设计,在此感谢博主“PeterZhang” 的一篇博客。还有就是自己不放弃的精神,回想起来自己是有很多不懂得地方,还有很多原理,
很多具体的实现,以及这个插件这么设计的优缺点,和设计者的设计思想自己还真是没有吃透。
做一个程序员,真的怕“不求甚解”。
下面附上最后的实现代码:
1:底层代码:
public JsonResult GetGuestNameAndDocumentByName()
{
var name = Request["q"];//调用autocomplete插件时默认输入框的数据
var pagesize = Convert.ToInt32(Request["limit"]);//每页多少行,autocomplete页面js设定,总是获取第一页
var listguest = this.CRMService.ListGuest(new MemberRequest { CommercialTenantID = this.LoginInfo.CommercialTenantID, ContainsName = name, PageIndex = , PageSize = pagesize }, true);
return Json(listguest, JsonRequestBehavior.AllowGet);
}
2:js实现:
<input class="form-control username" data-value="username_0" type="text" name="userName" id="userName_0" />
addtruser: function () {
$(".addtruser").live("click", function () {
var len = $("#guest tr[name='suike']").length;
$("#guest").append( "<td><input class='form-control username' data-value='username_" + len + "' type='text' id='userName_" + len + "'/>
+ "<i class='epicons addbtns addtruser' ></i>"
+ "<i class='epicons sumbtns minus2' value='" + len + "'>"
+ "</i></td></tr>");
turntolive.autoname();
});
}
autoname: function () {
$('.username').autocomplete('/CommercialTenant/CRM/GetGuestNameAndDocumentByName', {
max: , //列表里的条目数
minChars: , //自动完成激活之前填入的最小字符
width: , //提示的宽度,溢出隐藏
scrollHeight: , //提示的高度,溢出显示滚动条
matchContains: true, //包含匹配,就是data参数里的数据,是否只要包含文本框里的数据就显示
autoFill: false, //自动填充
extraParams: {}, //默认q为输入框值
dataType: 'json',
parse: function (data) {
return $.map(eval(data), function (row) {
return {
data: row,
value: row.Name,
result: row.Name
}
}); //对ajax页面传过来的数据进行json转码
},
formatItem: function (row, i, max) {
return i + '/' + max + ': ' + row.Name + ' [' + row.DocumentTypeName + ':' + row.DocumentNumber + ']';
},
formatMatch: function (row, i, max) {
return row.Name + row.DocumentNumber;
},
formatResult: function (row) {
return row.Name;
}
}).result(function (event, row, formatted) {
var __thisid = $(this)[].id.replace("userName_", ""); //页面固定格式 $('#userName_' + __thisid).val(row.Name);
$('#userName_' + __thisid).attr("readonly", "readonly"); });
},
3:效果图片:
autocomplete一些参数:
minChars: , //至少输入的字符数,default:1;如果设为0,在输入框内双击或者删除内容时显示列表。 width: , //下拉框的宽度,default:input元素的宽度 max: , //下拉项目的个数,default:10 scrollHeight: , // 下拉框的高度, Default: 180 scroll: true, //当结果集大于默认高度时,是否使用滚动条,Default: true multiple: false, //是否允许输入多个值. Default: false autoFill: false, // 是否自动填充. Default: false multipleSeparator: " ", //输入多个字符时,用来分开各个的字符. Default: "," matchCase:false, //是否开启大小写敏感 selectFirst:true, // 如果设置成true,下拉列表的第一个值将被自动选择, Default: true matchSubset:true, //是否启用缓存 cacheLength: , //缓存的长度.即缓存多少条记录.设成1为不缓存.Default: 10 delay: , //击键后的延迟时间(单位毫秒).Default: 远程为400 本地10 mustMatch:false, //如果设置为true,只会允许匹配的结果出现在输入框,当用户输入的是非法字符时,将被清除, Default: false matchContains:true, //决定比较时是否要在字符串内部查看匹配.Default: false formatItem: function(row, i, max) { } //结果中的每一行都会调用这个函数,返回值将用LI元素包含,显示在下拉列表中. 三个参数(row, i, max): 返回的结果数组, 当前处理的行数(从1开始), 当前结果数组元素的个数. Default: none, 表示不指定自定义的处理函数. formatResult : function(row, i, max) { } //和formatItem类似,但可以将将要输入到input文本框内的值进行格式化.同样有三个参数,和formatItem一样.Default: none,表示要么是只有数据,要么是使用formatItem提供的值. formatMatch: function(row) { } //对每一行数据使用此函数格式化需要查询的数据格式. 返回值是给内部搜索算法使用的. 参数值row result (function(event, data, formatted){}) //此事件会在用户选中某一项后触发,参数为:event: 事件对象, data: 选中的数据行,formatted:formatResult函数返回的值; 例如: $("#d").result(function(event, data, formatted){alert(formatted);}) extraParams (Object): //为后台(一般是服务端的脚本)提供更多的参数.和通常的作法一样是使用一个键值对对象.如果传过去的值是{ bar:4 },将会被autocompleter解析成my_autocomplete_backend.php?q=foo&bar=4 (假设当前用户输入了foo). Default: {}
谢谢,希望还能在技术这条路上再走一走。
jq 之Autocomplete 引发联想及思考的更多相关文章
- CSS画三角形引发的一些思考
今天刷知乎时看到了一个问题,有谁能详细讲一下css如何画出一个三角形?怎么想都想不懂? - 知乎.很巧,刚入前端坑的我前不久也遇到过这个问题,今天再来谈一谈这个问题则是因为知乎的一些答案引发了我的 ...
- long和BigDecimal引发的管理思考
关于long.double.BigDecimal在效率.可用性.灵活性等等方面的技术性讨论和测试其实在网上已经很多了,本文也不是打算讨论他们的实现的,其实笔者也曾在很长的职业生涯周期中一度拘泥于此.但 ...
- 由“Beeline连接HiveServer2后如何使用指定的队列(Yarn)运行Hive SQL语句”引发的一系列思考
背景 我们使用的HiveServer2的版本为0.13.1-cdh5.3.2,目前的任务使用Hive SQL构建,分为两种类型:手动任务(临时分析需求).调度任务(常规分析需求),两者均通过我们的 ...
- display:inline-block引发的间隙思考
一.导火线 没错,总有一类属性在助你轻松寻得捷径的同时,也可为你增添烦劳,比如本文的主谋display:inline-block.众前端们所诸知,其作用是将对象呈递为内联对象,但是对象的内容作为块对象 ...
- 初探Android逆向:通过游戏APP破解引发的安全思考
如今移动互联网已经完全融入到我们的生活中,各类APP也是层出不穷,因此对于安卓APP安全的研究也尤为重要.本文通过对一款安卓APP的破解实例,来引出对于APP安全的探讨.(本人纯小白,初次接触安卓逆向 ...
- 记一次Jquery学习引发的学习思考
学习廖雪峰Jquery的教程关于表单的操作时,被最后的习题给困住了,在一番思索后无奈地决定去看博客评论下的答案,却发现自己看不懂,遂以为是对Jquery的了解还不够深,于是便在网上疯狂搜索关于Jque ...
- 关于调试器中int3断点引发异常的思考
INT3断点 INT3断点是利用0Xcc指令实现的,cpu在执行0xcc指令时会引发断点异常调试器会捕捉这个异常. INT3断点引发的异常属于陷阱型异常,在执行完0xcc指令后eip指向下一条指令.但 ...
- required 引发的小小思考
原创:转载请注明出处 首先,因为遇到问题如下: class MainTabBar: UITabBar { override init(frame: CGRect) { super.init(frame ...
- excel表格的特殊需求引发的Java思考
前言: 前些天遇到了这样的一个需求,将下图: 将表格中货号-前面部分一致的行合成一行,并且将第二行,第三行的价格添加到第一行中为价格二,价格三.如图: 接到这样的需求,我的第一感觉是直接手动合并(暗暗 ...
随机推荐
- ip范围生成 C#
#region ip /// <summary> /// ip rang ,ip /// </summary> /// <param name="str&quo ...
- 基于AndroidPn二次开发的可行性
一.背景 如果要自己搭建,从零开始做或基于开源进行修改扩充,开源的push引擎,90%的博文首推AndroidPN,结合公司现状,最优解决方案就是进行AndroidPN的二次开发了.先看一下这个项目: ...
- 转 理解与分析ios应用的崩溃报告
理解与分析ios应用的崩溃报告 源网址: http://developer.apple.com/library/ios/#technotes/tn2151/_index.html 当一个应用程序崩溃时 ...
- 在云服务器上部署node.js服务器
本文档介绍腾讯云·万象优图服务端nodejs的部署和集成,搭建一个nodejs+nginx为基础,对web端或者移动端提供http签名接口服务的例子程序.注意:本文档只是简单的示例,展示了服务端为终端 ...
- Navicat Premium 快捷键
1.ctrl+q 打开查询窗口2.ctrl+/ 注释sql语句3.ctrl+shift +/ 解除注释4.ctrl+r 运行查询窗口的sql语句5.ctrl+shift+r 只运行选中的sql语句6. ...
- zookeeper(四):核心原理(Watcher、事件和状态)
zookeeper主要是为了统一分布式系统中各个节点的工作状态,在资源冲突的情况下协调提供节点资源抢占,提供给每个节点了解整个集群所处状态的途径.这一切的实现都依赖于zookeeper中的事件监听和通 ...
- Source Insight 项目简单使用说明
SI(Source Insight) 是我一直写代码的好伙伴, 相信这强大的软件也是广大程序猿编写软件的利器. 正所谓" 工欲善其事, 必先利其器", 我们要学会利用这款软件. 先 ...
- builtroot make menuconfig流程
本文主要介绍一下,buildroot(buildroot-2018.02.1)的make menuconfig.众所周知,在我们执行menuconfig时,会生成一个图形化界面,然后进行相关的配置.同 ...
- ny82 迷宫寻宝(一) map+queue
题目地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=82 AC代码:讲解,先统计在可搜索范围内对应的钥匙数,把搜到的门存到另外的一个队列中,第一 ...
- async and await 简单的入门
如果有几个Uri,需要获取这些Uri的所有内容的长度之和,你会如何做? 很简单,使用WebClient一个一个的获取uri的内容长度,进行累加. 也就是说如果有5个Uri,请求的时间分别是:1s 2s ...