创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件

时间:2022-09-01 17:06:15

Bootstrap是当下流行的前端UI组件库之一。利用Bootstrap,可以很方便的构造美观、统一的页面。把设计师从具体的UI编码中解放出来。

 

Bootstrap提供了不少的前端UI组件。带下拉菜单的文本框就是其中之一,效果图如下(真要自己完全设计,还得费一番功夫)

创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件

 

关于该组件的详情参看Bootstrap官网带下拉菜单的文本框

 

看到上面的效果图,使我想到WinForm编程中的DropDownList控件。不过,和DropDownList控件相比,还缺少以下内容

1、当点击菜单中的某一项,菜单的文字自动显示在文本框中

2、当点击菜单中的某一项,提供一个函数来获得相关的数据(可以是菜单的文字,也可以是相关的文本)

3、文本框不能编辑,只能通过点击菜单来更改内容

4、能设置下拉菜单的最大高度,使得菜单项过多时,能出现滚动条。(想想看,30条目将会占满整个屏幕是多么恐怖的事)

 

当然,Bootstrap只提供了前端UI的外观,上面的这几条都可以通过编码来完成

 

基于码农的精神,自力更生,自己写一个DropDownList的JQuery组件。

先规划好这个JQuery组件的属性:

InputName:文本框的name和id属性,默认值是“Q”;

ButtonText:右侧按钮的文字,默认值是“示例”;

ReadOnly:文本框的可编辑性属性。默认是true,也就是不能编辑,只能通过点击菜单来改变文字;

MaxHeight:下拉菜单的最高高度。默认值是-1,不设置最高高度,菜单的高度由菜单的条目决定;

onSelect:设置选择菜单条目时调用的函数。默认值是$.noop(),JQuery中的空函数;

Items:菜单条目的集合。每个菜单项提供ItemText属性(菜单文字)、ItemData属性(相关数据)、Selected属性(默认选择项,有多个,算最后一个)

Sections:菜单组的几何。每个组包含ItemHeader属性(组标题文字)、Items属性(该组菜单条目的集合)。每个组之间有一条分割线。该属性的优先级高于Items属性(如果仅仅设置了Items,则意味着只有一个菜单组,没有分割线,没有组标题文字)。

 

DropDownList的组件代码如下,由于是基于JQuery,故要把该代码置于JQuery引用代码之下:

代码比较简单,主要就是依据属性值来拼接HTML代码,下面简单的说明一下:

ReadOnly的实现:由于不是通过设置文本框的ReadOnly属性(会改变文本框的外观),因此采用绑定屏蔽掉文本框的cut、copy、paste、keydown事件来实现。

MaxHeight的实现:判断下拉菜单(元素UL)的高度是否超过MaxHeight,若超过则设置CSS属性Height和Overflow

onSelect函数:要自己实现一个函数,参数有两个值,第一个值是文本框的名字,第二个是当前点中的菜单项的相关数据(ItemData属性)

 

.sh_darkness{background:none; padding:0; margin:0; border:0 none;}.sh_darkness .sh_sourcecode{background-color:#000;color:#fff;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_keyword{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_type{color:#0f0;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_string{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_regexp{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_specialchar{color:#bfbfbf;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_comment{color:#888;font-weight:normal;font-style:italic;}.sh_darkness .sh_sourcecode .sh_number{color:#619de7;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_preproc{color:#1da3cf;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_symbol{color:#f0f;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_function{color:#f34627;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_cbracket{color:#f0f;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_url{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_date{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_time{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_file{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_ip{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_name{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_variable{color:#26e0e7;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_oldfile{color:#bfbfbf;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_newfile{color:#abab00;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_difflines{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_selector{color:#26e0e7;font-weight:normal;font-style:normal;}.sh_darkness .sh_sourcecode .sh_property{color:#ff0;font-weight:bold;font-style:normal;}.sh_darkness .sh_sourcecode .sh_value{color:#abab00;font-weight:bold;font-style:normal;}

/*-------- Snippet Base Styles ----------*/
.snippet-wrap {position:relative;}
*:first-child+html .snippet-wrap {display:inline-block;}
* html .snippet-wrap {display:inline-block;}
.snippet-wrap .snippet-menu {position:absolute; top:10px; right:15px; font-size:.9em;z-index:1;background-color:transparent; width:50%; text-align:right;}
.snippet-wrap .snippet-menu pre {background-color:transparent; margin:0; padding:0;}
.snippet-wrap .snippet-menu a {padding:0 5px; text-decoration:underline;}
.snippet-wrap pre.sh_sourcecode{padding:1em;line-height:1.8em;overflow:auto;position:relative;
-moz-border-radius:15px 0px 15px 0px;
-webkit-border-radius:15px 0px 15px 0px;
border-radius:15px 0px 15px 0px;
}
.snippet-wrap pre.snippet-textonly {padding:2em;}
*:first-child+html .snippet-wrap pre.snippet-formatted {padding:2em 1em;}
* html .snippet-wrap pre.snippet-formatted {padding:2em 1em;}
.snippet-wrap .snippet-no-num{list-style:none !important; padding:.6em 1em; margin:0 !important;}
.snippet-wrap .snippet-no-num li {list-style:none; padding-left:0; margin:0px;}

.snippet-container{width:80%;word-wrap:break-word;}


  • <script>
  • (function($){
  •     jQuery.fn.DropDownList = function(options) {
  •        
  •         //设置插件的默认属性
  •         var defaults ={
  •             InputName:"Q",
  •             ButtonText:"示例",
  •             ReadOnly:true,
  •             MaxHeight:-1,
  •             onSelect:$.noop(),
  •         }
  •  
  •         var options = $.extend(defaults,options);
  •  
  •         return this.each(function(){
  •             var o=options;
  •             var Obj=$(this);
  •   
  •             var S="<div class='input-group'>";
  •             S = S + "<input type='text' class='form-control' name='" + o.InputName + "' id='" + o.InputName + "'  />";
  •             S = S + "<div class='input-group-btn'>";
  •             S = S + "<button type='button' class='btn btn-default dropdown-toggle' data-toggle='dropdown'>" + o.ButtonText + "<span class='caret'></span></button>";
  •             S = S + "<ul class='dropdown-menu dropdown-menu-right' role='menu'>";
  •   
  •             //可以由Sections参数或Items参数设置下拉条目,Sections的优先级比Items高
  •             if (o.Sections!== undefined)
  •             {
  •                 $.each(o.Sections,function(n,value){
  •                        
  •                     //从第2节开始,在每节的顶部添加一条分割线
  •                     if (n>0) { S=S + "<li class='divider'></li>"; }
  •  
  •                     //如果设置了ItemHeader参数,则给该节添加标题文本
  •                     if (value.ItemHeader!==undefined) { S = S + "<li class='dropdown-header'>" + value.ItemHeader + "</li>"; }
  •  
  •                     CreateItem(value);
  •                 });
  •             }
  •             else
  •             {
  •                 CreateItem(o);
  •             }
  •   
  •  
  •             var SelText="";
  •             var SelData="";
  •  
  •             function CreateItem(Items)
  •             {
  •                 $.each(Items.Items,function(n,Item){
  •  
  •                     //如果ItemData参数没有定义,则把ItemText参数传给ItemDate
  •                     if (Item.ItemData===undefined) {Item.ItemData=Item.ItemText;}
  •  
  •                     S=S + "<li><a href='#'  ItemData='"  + Item.ItemData + "' >" + Item.ItemText + "</a></li>";
  •  
  •                     //如果设置了Selected参数,则获取该条目的ItemDada和ItemText。
  •                     //如果有多个条目设置该参数,则获取的是满足条件最后一个条目
  •                     if (Item.Selected==true) { SelText=Item.ItemText;SelData=Item.ItemData;}
  •                 });
  •             }
  •   
  •   
  •             S =S + "</ul></div></div>";
  •   
  •             Obj.html(S);
  •   
  •             var Input=Obj.find("input");
  •  
  •             //如果有条目设置Selected参数,则调用设置活动条目的函数
  •             if (SelText!="") { SetData(SelText,SelData); }
  •   
  •             //给所有的条目绑定单击事件,单击后调用设置活动条目的函数
  •             Obj.find("a").bind("click", function(e) {SetData($(this).html(),$(this).attr("ItemData"));});
  •   
  •             //如果ReadOnly参数设置为true,则屏蔽掉文本框的相关事件,使得文本框不能编辑。(而又显示为激活状态)
  •             if (o.ReadOnly==true)
  •             {
  •                 Input.bind("cut copy paste keydown", function(e) {e.preventDefault();});
  •             }
  •   
  •             //设置MaxHeight参数后(大于0),则设置下拉菜单的最大高度,若条目过多,会出现垂直滚动条
  •             if (o.MaxHeight>0)
  •             {
  •                 var UL=Obj.find("ul");
  •                 if (UL.height()>o.MaxHeight)
  •                 {UL.css({'height':o.MaxHeight,'overflow':'auto'});}
  •             }
  •   
  •             function SetData(Text,Data)
  •             {
  •                 Input.val(Text);
  •                 if (o.onSelect) { o.onSelect(o.InputName,Data); }
  •             }
  •                  
  •         });
  •     }
  • })(jQuery);
  •  
  • </script>

下面是几个用法实例:对Id为DropDownList的div元素运用组件,则在该div内部添加一个DropDownList组件

 

1、用Items属性实现下拉菜单(所有菜单项都在一个组里,没有组标题,没有分割线)

 


  • function ShowData(InputName,Data)
  • {
  •     alert(InputName + ":" + Data); 
  • }
  •  
  • $("#DropDownList").DropDownList(
  •     {
  •         InputName:"Q",
  •         ButtonName:"参考",
  •         onSelect : function(I,Data)
  •             {
  •                 ShowData(I,Data);
  •             },
  •  
  •         Items:[
  •             {ItemText:"示例1",ItemData:"Demo1",Selected:true},
  •             {ItemText:"示例2",ItemData:"Demo2"},
  •             {ItemText:"示例3",ItemData:"Demo3"}
  •         ]
  •     });

效果图:

创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件

 

 

2、用Sections属性实现下拉菜单(菜单组之间有分割线,菜单组可以设置组标题)

 


  • function ShowData(InputName,Data)
  • {
  •     alert(InputName + ":" + Data); 
  • }
  •  
  • $("#DropDownList").DropDownList(
  •     {
  •         InputName:"Q",
  •         ButtonText:"参考",
  •         onSelect : function(I,Data)
  •             {
  •                 ShowData(I,Data);
  •             },
  •  
  •         Sections:[
  •             {
  •                 ItemHeader:"全部",
  •                 Items:[
  •                     {ItemText:"全部",ItemData:"All"}
  •                 ]
  •             },
  •             {
  •                 Items:[
  •                     {ItemText:"示例1",ItemData:"Demo1",Selected:true},
  •                     {ItemText:"示例2"}
  •                 ]
  •             }
  •         ]
  •     });

效果图:

创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件

 

3、实现全国省份直辖市的下拉选择,要设置MaxHeight属性

 


  • function ShowData(InputName,Data)
  • {
  •     alert(InputName + ":" + Data); 
  • }
  •  
  • $("#DropDownList").DropDownList(
  •     {
  •         InputName:"Q",
  •         ButtonText:"参考",
  •         MaxHeight:310,
  •         onSelect : function(I,Data)
  •             {
  •                 ShowData(I,Data);
  •             },
  •  
  •         Sections:[
  •             {
  •                 ItemHeader:"直辖市",
  •                 Items:[
  •                     {ItemText:"北京",ItemData:"Beijing"},
  •                     {ItemText:"上海",ItemData:"Shanghai",Selected:true},
  •                     {ItemText:"天津",ItemData:"Tianjin"},
  •                     {ItemText:"重庆",ItemData:"Chongqing"}
  •                 ]
  •             },
  •             {
  •                 ItemHeader:"华东地区",
  •                 Items:[
  •                     {ItemText:"山东",ItemData:"Shandong"},
  •                     {ItemText:"江苏",ItemData:"Jiangsu"},
  •                     {ItemText:"安徽",ItemData:"Anhui"},
  •                     {ItemText:"浙江",ItemData:"Zhejiang"},
  •                     {ItemText:"福建",ItemData:"Fujian"}
  •                 ]
  •             },
  •             {
  •                 ItemHeader:"华南地区",
  •                 Items:[
  •                     {ItemText:"广东",ItemData:"Guangdong"},
  •                     {ItemText:"广西",ItemData:"Guangxi"},
  •                     {ItemText:"海南",ItemData:"Hainan"}
  •                 ]
  •             },
  •             {
  •                 ItemHeader:"华中地区",
  •                 Items:[
  •                     {ItemText:"湖北",ItemData:"Hubei"},
  •                     {ItemText:"湖南",ItemData:"Hunan"},
  •                     {ItemText:"河南",ItemData:"Henan"},
  •                     {ItemText:"江西",ItemData:"Jiangxi"}
  •                 ]
  •             },
  •             {
  •                 ItemHeader:"华北地区",
  •                 Items:[
  •                     {ItemText:"河北",ItemData:"Hebei"},
  •                     {ItemText:"山西",ItemData:"Shanxi"},
  •                     {ItemText:"内蒙古",ItemData:"Neimenggu"}
  •                 ]
  •             },
  •             {
  •                 ItemHeader:"西北地区",
  •                 Items:[
  •                     {ItemText:"宁夏",ItemData:"Ningxia"},
  •                     {ItemText:"*",ItemData:"*"},
  •                     {ItemText:"青海",ItemData:"Qinghai"},
  •                     {ItemText:"陕西",ItemData:"Shaanxi"},
  •                     {ItemText:"甘肃",ItemData:"Gansu"},
  •                 ]
  •             },
  •             {
  •                 ItemHeader:"西南地区",
  •                 Items:[
  •                     {ItemText:"四川",ItemData:"Sichuan"},
  •                     {ItemText:"云南",ItemData:"Yunnan"},
  •                     {ItemText:"贵州",ItemData:"Guizhou"},
  •                     {ItemText:"*",ItemData:"Xizang"}
  •                 ]
  •             },
  •             {
  •                 ItemHeader:"东北地区",
  •                 Items:[
  •                     {ItemText:"辽宁",ItemData:"Liaoning"},
  •                     {ItemText:"吉林",ItemData:"Jilin"},
  •                     {ItemText:"黑龙江",ItemData:"Heilongjiang"}
  •                 ]
  •             }
  •         ]
  •     });

效果图:

创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件

 

唯一的遗憾就是有滚动条的时候,滚动条会覆盖下拉菜单右侧的两个圆角,如果真要完美的话,可能要对Bootstrap中的源代码进行修改了。

创建基于Bootstrap的下拉菜单的DropDownList的JQuery插件的更多相关文章

  1. 第二百四十四节,Bootstrap下拉菜单和滚动监听插件

    Bootstrap下拉菜单和滚动监听插件 学习要点: 1.下拉菜单 2.滚动监听 本节课我们主要学习一下 Bootstrap 中的下拉菜单插件,这个插件在以组件的形式我们 已经学习过,那么现在来看看怎 ...

  2. Bootstrap按钮式下拉菜单

    前面的话 按钮式下拉菜单仅从外观上看,和下拉菜单效果基本上是一样的.不同的是普通的下拉菜单是block元素,而按钮式下拉菜单是inline-block元素.本文将详细介绍Bootstrap按钮式下拉菜 ...

  3. 基于Bootstrap的下拉框插件bootstrap-select

    写在前面: 在这次的项目中,没有再使用liger-ui做为前端框架了,改为了Bootstrap,这次也好接触下新的技术,在学习的过程中发现,Bootstrap的一些组件基本都是采用class的形式,就 ...

  4. bootstrap多级下拉菜单

    只需为下拉菜单的任意 <li> 元素添加 .dropdown-submenu 的类,并在该 <li> 元素下添加 .dropdown-menu 类的列表,就可以为该菜单项添加一 ...

  5. 下拉菜单&semi;手风琴&semi;九宫格的Jquery的使用实例

    下拉菜单;手风琴;九宫格的Jquery的使用实例 1.下拉菜单 效果如图: 代码如下: <!DOCTYPE html> <html lang="en"> & ...

  6. Bootstrap 下拉菜单和滚动监听插件

    一.下拉菜单 常规使用中,和组件方法一样,代码如下: //声明式用法 <div class="dropdown"> <button class="btn ...

  7. Bootstrap的下拉菜单float问题

    在学习bootstrap中的下拉菜单时,遇到下面情况: <div class="dropdown"> <button class="btn btn-de ...

  8. bootstrap的下拉菜单组件与导航条

    前期准备:bootstrap的css文件和js文件先引入 Bootstrap 组件-拉下菜单(class+js) 下拉菜单必需三级结构 <div class="dropdown&quo ...

  9. bootstrap悬停下拉菜单显示

    使用Bootstrap导航条组件时,如果你的导航条带有下拉菜单,那么这个带下拉菜单的导航在点击时只会浮出下拉菜单,它本身的href属性会失效,也就是失去了超链接功能,这并不是我想要的,我希望导航条的链 ...

随机推荐

  1. SQL IN 操作符、SQL BETWEEN 操作符、SQL Alias(别名)

    IN 操作符 IN 操作符允许我们在 WHERE 子句中规定多个值. SQL IN 语法 SELECT column_name(s) FROM table_name WHERE column_name ...

  2. 安卓序列化漏洞 —— CVE-2015-3525

    在2014年,Jann Horn发现一个安卓的提权漏洞,该漏洞允许恶意应用从普通应用权限提权到system用户执行命令,漏洞信息与POC见(1].漏洞的成因源于在安卓系统(<5.0)中,java ...

  3. PHP图的绘制1

    最近在学习php图的绘制,写的代码放上来,供自己以后学习查看: <?php //*函数说明: //这个函数返回的是 // resource imagecreate ( int $x_size , ...

  4. 前序 中序 后序 遍历 递归 非递归算法 java实现

    前序遍历 非递归 public void preordernorec(TreeNode root){ //System.out.println("先序遍历(非递归):"); //用 ...

  5. arcpy&period;mapping常用四大件-MapDocument

    arcpy.mapping常用四大件-MapDocument by 李远祥 点开arcpy.mapping的帮助,可以看到其有限的几个类,看起来东西不是很多,但却是非常的使用.由于arcpy定位就是粗 ...

  6. ConcurrentHashMap 扩容分析拾遗

    前言 这是一篇对 transfer 方法的拾遗,关于之前那篇文章的一些一笔带过,或者当时不知道的地方进行回顾. 疑点 1. 为什么将链表拆成两份的时候,0 在低位,1 在高位? 回顾一下 transf ...

  7. 4&period;10 Routing -- Asynchronous Routing

    本节介绍了路由器的一些更高级的功能和处理复杂异步逻辑的能力. 一.A word on promises 1. 在Ember的Router中Ember使用了大量的Promises概念来处理异步逻辑.简而 ...

  8. python中赋值、浅拷贝、深拷贝详解(转)

    一.赋值 >>> a = [1, 2, 3]>>> b = a>>> print(id(a), id(b), sep='\n')139701469 ...

  9. Android架构设计之MVP分析

    转载请注明出处:http://blog.csdn.net/crazy1235/article/details/51471280

  10. Python编程从入门到实践,个人笔记

    3-9 晚餐嘉宾:在完场练习3-6时编写的程序之一中,使用len()打印一条消息,指出有多少位嘉宾来与你共进晚餐. 自己先写的程序如下: # coding=gbk #邀请一些人吃饭 per_list= ...