打造基于jQuery的智能选择输入框
UPDATE:修正了在FireFox下显示的问题,重新copy CSS即可
写完这个名字忽然觉得有点标题党的嫌疑,但是又不知道什么样的名字比较合适,那就暂且这样吧。
今天要讲的东西比较简单,其中会用到另外的一个jQuery控件,是一个人员选择输入框。那到底是个什么东西呢? 
那好还是先来看最后的效果,有个直接的了解。

是不是和时下流行的SNS网站的选择人员控件很像?对比一下,哈哈是的,其实目的是差不多的。

其实还有很多这样应用,如邮件系统中发件人,在输入时的自动补全,它是一个类似于Autocomplete的功能,但是又要比Autocomplete多那么一些功能的插件
基于这个情况,我所编写的这个控件时基于一个Autocomplete控件的,它就是jQuery.autocomplete,它的官方网址是:http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/
大家可以通过访问以下来获取它的使用方法,资料和demo还是比较详细,我这边就不重复写了。所以我们还是直接开始扩展的部分
第一我们还是先确定HTML
从html上分析autocomplete和选人控件的所查的就是
1:外侧的容器 2:选中的人员的那个小方块
容器我们用Div就可以了,小方块也比较简单 ,来看一下,最外层是div包裹,然后是嵌套一个a标签(为了方便以后做hover效果),在a标签中是一个span放置文字,
input[type=hidden]来防止这个节点的数据,img就似乎删除按钮的载体,那控件的载体又是什么呢?其实从设计来说可以是个input的,但是我更偏向于div,在实例化的时候往div中动态添加一个input来附加autocomplete的属性,如果反过来在input外包裹容器的话,在一些特殊情况下定位会是问题。

那html既然已经定义好了,接着就是CSS了,这个css其实很简单,就是容器的边框还有就是item的样子而已,来看下代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | .bbit-usbox{    border: solid1px#3C7FB1;            margin:20px;    padding:2px;        display:block;    background-color:#f3fefe;}.bbit-usbox .bbit-usbox-item{    width:auto;    margin-left:4px;    margin-top:2px;    background-color:#e0e5ee;        border: solid1px#ccd5e4;        float:left;       white-space : nowrap;}.bbit-usbox .bbit-usbox-item a{    color:#000;     text-decoration:none;    padding-left:2px;}.bbit-usbox .bbit-usbox-item a span{  }.bbit-usbox .bbit-usbox-del{    background:url("images/usbox/del.gif") no-repeat50%80%;    width:10px;    height:5px;    cursor:pointer;    border:none;    vertical-align:middle;     margin-left:2px;}.bbit-usbox-boxc {  margin-left:4px;  clear:left;}.bbit-usbox-box{}.bbit-usbox-boxc  input{    background-color:#f3fefe;    width:100%;    height:17px;    display:block;    border:none;    } | 
本例中只有使用一个图片 
第二 开始编写Javascript
还是老规矩,先来个完整代码,非常简单只有不到70行代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | ; (function($) {    if(!$.Autocompleter) {        alert("请先引用jquery.autocomplete.js");        return;    }    $.fn.usbox = function(o) {        vardef = {            urlOrData: "ResponseAutoComplete.ashx",            width: "90%", //宽度            addItem: false,            removeItem: false,            clickItem: function() { },            completeOp: {}        };        $.extend(def, o);        varco = $.extend({ scroll: false, formatItem: function(row, i, max) { returnrow[0] + "["+ row[1] + "]"; } }, def.completeOp);        vartemp = "<div class='bbit-usbox-item'><a href='javascript:void(0);'><span>${text}</span><input type='hidden' value='${value}'/><img src='../Themes/Shared/images/s.gif' alt='点击删除' class='bbit-usbox-del'/></a></div>";        returnthis.each(function(e) {            varme = $(this);            varid = me.attr("id");            if(id == null|| id == "") {                id = "usbox_"+ newDate().getTime();            }            varinc = $("<div class='bbit-usbox-boxc'/>");            varinput = $("<input type='text' id='"+ id + "_inbox' class='bbit-usbox-box' />").appendTo(inc);            me.addClass("bbit-usbox").width(def.width).append(inc);            input.autocomplete(def.urlOrData, co).result(function(event, data, formatted) {                $(this).val("");                additem(this, data);            });            me.bind("addboxitem", function(e,data) { additem(input,data); });            functionadditem(inc, data) {                vartp = $(temp.replace(/\$\{([\w]+)\}/g, function(s1, s2) {                    if(s2 == "text") {                        returndata[0];                    }                    elseif(s2 == "value") {                        returndata.join("|");                    }                    else{                        returns1;                    }                }));                tp.click(def.clickItem).find("img.bbit-usbox-del").click(removeitem);                $(inc).parent().before(tp);                if(def.addItem) {                    def.addItem(data);                }            }            functionremoveitem() {                varp = $(this).prev()                varv = p.val();                vararr = v.split("|");                if(def.removeItem) {                    def.removeItem(arr);                }                $(this).parent().parent().remove();            }            returnme;        });    };    $.fn.addboxitem = function(op) {        $(this).trigger("addboxitem", [op]);    };})(jQuery) | 
接着我们来一步一步来分析我的实现,开始还是编写jQuery控件的“模板”,关于为什么要这么写,请参考这篇的说明
| 1 2 3 4 5 6 7 8 | ; (function($) {    if(!$.Autocompleter) {         alert("请先引用jquery.autocomplete.js");        return;    }   $.fn.usbox = function(o) {   }})(jQuery) | 
这次加了一个判断,因为我们这个控件是依赖于autocomplete的,如果你看了前两篇,那么就一定知道接着就是编写默认参数
| 1 2 3 4 5 6 7 8 | vardef = {        urlOrData:false,//必须!请求数据的url和或者直接是数据,格式参考autocomplete的说明        width: "90%", //宽度        addItem: false,//当从下拉选项中选择一个人员后触发的函数        removeItem: false,//当从已选择的人员删除一个人时触发的函数        clickItem: function() { },//点击人员小方块时触发的时间        completeOp: {}//autocomplete的参数,格式参考它自身的说明    }; | 
参数也是比较简单,添加和移除的两个函数比较重要,在demo中会讲到,autocomplete的参数因为太多,大家只有自己参考一下官方的说明, 默认不管也可以,因为我会给大家默认来一下.
| 1 2 3 4 5 | $.extend(def, o);//这才是默认的Complete的参数 varco = $.extend({ scroll: false, formatItem: function(row, i, max) { returnrow[0] + "["+ row[1] + "]"; } }, def.completeOp);//定义小方块的模板,其中s.gif是个空图片,位置可根据实际情况进行调整  vartemp = "<div class="bbit-usbox-item"><a href="javascript:void(0);"><span>${text}</span><input value="${value}" type="hidden"><img class="bbit-usbox-del" alt="点击删除" src="../Themes/Shared/images/s.gif"></a></div>"; | 
formatItem函数是下拉中显示的格式 ,接着是生成HTML,注册事件,详细的步骤我已经注释到代码中了如下所示
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | returnthis.each(function(e) {            varme = $(this);            varid = me.attr("id");            //获取唯一的ID            if(id == null|| id == "") {                id = "usbox_"+ newDate().getTime();            }            //input的容器            varinc = $("<div class='bbit-usbox-boxc'/>");            //生成一个input用于附加autocomplete控件            varinput = $("<input type='text' id='"+ id + "_inbox' class='bbit-usbox-box' />").appendTo(inc);            //设置样式,并把input添加到对象中            me.addClass("bbit-usbox").width(def.width).append(inc);            //给input注册autocomplete功能,并设置回调函数            input.autocomplete(def.urlOrData, co).result(function(event, data, formatted) {                $(this).val("");//选择人员了则把输入框自己清空                additem(this, data);//生成小方块            });            //注册一个自定义的事件,事件名addboxitem            me.bind("addboxitem", function(e,data) { additem(input,data); });            functionadditem(inc, data) {                //小方块的模板替换成正确的值                vartp = $(temp.replace(/\$\{([\w]+)\}/g, function(s1, s2) {                    if(s2 == "text") {                        returndata[0]; //返回的第一个值是displayname                    }                    elseif(s2 == "value") {                        returndata.join("|");//其他全部放到input[type=hidden]中                    }                    else{                        returns1;                    }                }));                //触发小放开的click事件,并且在内部查找删除按钮,注册点击事件,jQuery的链式哦                tp.click(def.clickItem).find("img.bbit-usbox-del").click(removeitem);                //把小方块放到input之前!                $(inc).parent().before(tp);                if(def.addItem) { //如果additem存在则触发                    def.addItem(data);                }            }            //移除的方法            functionremoveitem() {                varp = $(this).prev()//获取input[type=hidden],this指向delete img                varv = p.val();                vararr = v.split("|"); //拼成一个数组                if(def.removeItem) {//触发移除函数                    def.removeItem(arr);                }                //小方块移除本身                $(this).parent().parent().remove();//            }            returnme;        }); | 
最后是公开一个函数来方便外面调用additem,如我有一个弹出界面可以一次选择n个人回来,那么就可以调用这个函数了
| 1 2 3 | $.fn.addboxitem = function(op) {        $(this).trigger("addboxitem", [op]);//想到我在之前注册的自定义事件了吗?    }; | 
至此我们的控件其实已经分析完成了,但是为了让大家更好的理解这个控件,我把对应的服务器端代码也顺便写写因为Demo是Asp.NET MVC的,那么就以asp.net mvc 为例来讲吧 先来看看Demo的调用代码,urlOrData是个Action,additem和removeitem分别处理将选中的人员添加到指定的隐藏域或从中删除,以便表单提交。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | $(document).ready(function() {            $("#usbox").usbox({                width: 430,                urlOrData:"<%=Url.Action("QueryComplete")%>",                addItem: function(data) {                    vart = $("#hdtext").val();                    varv = $("#hdvalue").val();                    vart1 = t != ""? t.split(",") : [];                    varv1 = v != ""? v.split(",") : [];                    t1.push(data[0]);                    v1.push(data[2]);                    $("#hdtext").val(t1.join(","));                    $("#hdvalue").val(v1.join(","));                },                removeItem: function(data) {                    vart = $("#hdtext").val();                    varv = $("#hdvalue").val();                    vart1 = t.split(",");                    varv1 = v.split(",");                    varindex = -1;                    for(vari = v1.length - 1; i >= 0; i--) {                        if(data[2] == v1[i]) {                            index = i;                            break;                        }                    }                    if(index > -1) {                        t1.splice(index, 1);                        v1.splice(index, 1);                        $("#hdtext").val(t1.join(","));                        $("#hdvalue").val(v1.join(","));                    }                }            });            vartempdata = ["假正经哥哥", "xuanye","001"];                     $("#usbox").addboxitem(tempdata);        }); | 
HTML代码
| 1 2 3 4 5 | <divid="usbox" class="bbit-usbox"> </div><inputid="hdtext" type="text"/><inputid="hdvalue" type="text"/>输入框在实际项目中可能是隐藏域,默认我加上了假正经哥哥 | 
再来看看Action的代码,默认接受两个参数,一个是q,即input中的输入框,一个是限制条数(默认是10,可通过修改complete的参数来改变)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | publicContentResult QueryComplete(stringq, intlimit)        {            stringret = "";            if(q != ""&& limit >0)            {              //根据关键字搜索数据库或缓存,这个就比较简单不深入了               List<Person> list=_respository.QueryCompletePerson(q, limit);               if(list != null)               {                   StringBuilder sb = newStringBuilder();                   foreach(Person person inlist)                   {               //以|分割的数据格式,可以是多个,这里是三个。当然也可以吧ID作为特殊的                       sb.AppendLine(person.FullName + "|"+ person.PY+"|"+person.ID);                   }                   ret = sb.ToString();               }                            }            returnContent(ret);        } | 
本示例的地址是:http://jscs.cloudapp.net/ControlsSample/usbox
另外抱怨一下:部署到window azure 真的是有点麻烦哟。。搞了几次
最后 你的支持就是我继续写作的动力!
本文地址:http://www.cnblogs.com/xuanye/archive/2009/10/28/1591733.html
转载请保留!
出处:http://www.cnblogs.com/xuanye/archive/2009/10/28/xuanye_jquery_usbox_bog.html
打造基于jQuery的智能选择输入框的更多相关文章
- 打造基于jQuery的日期选择控件
		终于把jQuery拼写正确了哈,哈哈javascript也是区分大小写的,所以确实不能写错,今天我来和大家分享的是日期选择控件的实现,功能也许不够强大,但是能够满足需求. 我之前也写过(正确的说是改过 ... 
- 基于jquery的城市选择插件
		城市选择插件的难度不是很大,主要是对dom节点的操作.而我写的这个插件相对功能比较简答,没有加入省市联动. 上代码好了,参照代码的注释应该比较好理解. /* *基于jquery的城市选择插件 *aut ... 
- 基于jquery的ui选择之路
		选定: 主框架:jqueryUi tree:ztree grid:jqGrid layout:jquery.layout 原由: 还有其他demo,ajax实现等参看连接: 正在做的一个项目选择jqu ... 
- 福利到~分享一个基于jquery的智能提示控件intellSeach.js
		一.需求 我们经常会遇到[站内搜索]的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示.例如:某公司人事管理系统,想搜索李XX,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户 ... 
- 一个基于jquery的智能提示控件intellSeach.js
		一.需求 我们经常会遇到[站内搜索]的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示.例如:某公司人事管理系统,想搜索李XX,只要输入“李”,系统自然会提示一些姓李的员工,这样方便用户 ... 
- jquery的智能提示控件
		福利到~分享一个基于jquery的智能提示控件intellSeach.js 一.需求 我们经常会遇到[站内搜索]的需求,为了提高用户体验,我们希望能做到像百度那样的即时智能提示.例如:某公司人事管 ... 
- 基于jQuery的input输入框下拉提示层(自动邮箱后缀名)
		基于jQuery的input输入框下拉提示层,方便用户输入邮箱时的提示信息,需要的朋友可以参考下 效果图 // JavaScript Document (function($){ $.fn ... 
- 基于jQuery打造的选项卡向上弹出jquery焦点图切换特效
		基于jQuery打造的选项卡向上弹出jquery焦点图切换特效 鼠标经过标题栏,会出现层特效向上滑动,并且在同时进行幻灯片切换,效果十分不错. 有兴趣的童鞋可以下载看看,在IE6方面兼容性也不错,只有 ... 
- 基于jQuery美化联动下拉选择框
		今天给大家介绍一款基于jQuery美化联动下拉选择框.这款下下拉选择框js里自带了全国所有城市的数数库.下拉选择框适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲 ... 
随机推荐
- jQuery源码分析--Event模块(1)
			jQuery的Event模块提供了强大的功能:事件代理,自定义事件,自定义数据等.今天记录一下它实现的原理. 我们都知道,在js的原生事件中,有事件对象和回调函数这两样东西.但是事件对象是只读的,所以 ... 
- Android查缺补漏(IPC篇)-- 进程间通讯之AIDL详解
			本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8436529.html 进程间通讯篇系列文章目录: Android查缺补漏(IP ... 
- SQL学习笔记三(补充-3)之MySQL完整性约束
			阅读目录 一 介绍 二 not null与default 三 unique 四 primary key 五 auto_increment 六 foreign key 七 作业 一 介绍 约束条件与数据 ... 
- P1052 过河(离散化+dp)
			P1052 过河 dp不难,重点是要想到离散化. 石子个数$<=100$意味着有大量空间空置,我们可以缩掉这些空间. 实现的话自己yy下就差不多了. #include<iostream&g ... 
- Python3.x:基础学习
			Python3.x:基础学习 1,Python有五种标准数据类型 1.数字 2.字符串 3.列表 4.元组 5.字典 (1).数字 数字数据类型存储数字值.当为其分配值时,将创建数字对象. var1 ... 
- 关于《Java读书笔记》第六章课后习题选择题总结与疑问
			课后习题 选择题 3 题 代码: class Some{ String ToString(){ return "Some instance"; } } public class M ... 
- Codeforces Round #394 (Div. 2) A,B,C,D,E
			A. Dasha and Stairs time limit per test 2 seconds memory limit per test 256 megabytes input standard ... 
- codeforces 356 div2 C.Bear and Prime 100 数学
			C. Bear and Prime 100 time limit per test 1 second memory limit per test 256 megabytes input standar ... 
- ng-grid
			请查看官网:http://angular-ui.github.io/ui-grid/ 简单的使用: 总的来说我们 1.需要引入ng-grid-1.3.2.js 2.在html页面需要加入 class ... 
- C#对象初始或器-Chapter3 P38
			protected string GetMessage() { //如何构造和初始化泛型集合库中的一个数组和两个类. Product myProduct = ,Name="Kayak&quo ... 
