原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://dba10g.blog.51cto.com/764602/1188190
闲话少聊,今天本人重点看了看jquery插件开发这一块。想通过代码,实际练下兵。当然,也是为了解决项目的实际需要。平时,我们经常遭遇"选择框"这个控件。 平时,如果我们的选择项非常简单, 一般用浏览器自带的select 就OK了。但是如果字典项直接存在上下级关系,也就是经常见到的树结构 ,那就非常非常难受了。自己很纳闷,为什么jquery插件千千万,为什么就没有这么一款插件呢,一般就是纯粹的树插件, 要不就是下拉框插件。总之,个人没有找到满足自己要求的插件。那就自己就着手写一个吧。
先亮底牌,展示效果。
![](https://i-blog.csdnimg.cn/blog_migrate/ce1ed2ac96c166e40294033dbb3802f7.png)
主要有两种效果:
第一种:对于数据一般情况, 用浏览器的select 标签也可,主要是可以解决自身select标签的样式.重点是在美化,使用一些标签进行仿真 select标签;
第二种:也就是重点, 下拉选择树。 下拉列表中显示树结构
实现方式
其实这个插件,自己只负责组装。意思就是:这两种效果自己都参照了其他jquery插件,个人只是把两者合并了一下。
因为个人对美工这一块的干活,一直都是远观的状态。
使用的两个插件分别是:
ztree.3.5
jquery.mfs
实现代码(droptree.js)
/**
下拉树
*/
( function($){
var defaults={
idLabel: "code",
textLabel: "name",
pidLabel: "pid",
transition: "ztree",
items:[]
};
/**
target:input element;
*/
function DropTree(target,options){
this.target = target;
this.value = target.value;
this.$target = $(target);
this.opts = $.extend({}, defaults, options, this.$target.data());
this.id = this.target.id || this.target.name;
if( this.$target.length >0){
this._init();
}
return this;
}
DropTree.prototype._init = function(){
var self = this;
this.$target.hide();
this.$wrap = this.$target.wrap('<div class= "mfs-container">').parent();
this.$selected = $('<a class= "mfs-selected-option" href= "#" />').prependTo( this.$wrap);
//this.$selected.css("height",15);
this.$selected.html( this.value+ " ");
this.$down = $( "<span> </span>").prependTo( this.$selected);
this.transition = Transitions[ this.opts.transition].call( this);
};
var Transitions = {
mfs: function(){
var mfsId = this.id+ "_mfs";
this.$options = $('<ul class= "mfs-options" id= "'+mfsId+'"/>').insertAfter( this.$selected);
var idLabel = this.opts.idLabel;
var textLabel = this.opts.textLabel;
var $options = this.$options;
//var (this.id);
$.each( this.opts.items, function(i,n){
var $op = $('<a href= "#" index= "'+i+'">'+n[textLabel]+'</a>').wrap('<li class= "mfs-option">').parent();
$options.prepend($op);
});
//添加活力
var enableMagic = function (theContainer){
//TODO 可配置
var selectElm = theContainer.find('select');
var selectElmOptions = selectElm.find('option');
var optionList = theContainer.find('#'+mfsId);
var optionListLi = optionList.find('li.mfs-option');
var selectedOption = theContainer.find('a.mfs-selected-option');
var optionListOptions = optionList.find('a');
optionList.hide();
optionListOptions.click( function(){
optionListLi.removeClass('active').removeClass('selected');
$( this).closest('li').addClass('selected');
selectedOption.html($( this).text()+'<span> </span>');
selectElmOptions.removeAttr('selected');
selectElmOptions.eq($( this).attr('index')).prop('selected', 'selected');
optionList.hide();
// Make a refresh function that just updates the select magic (destroy and re-enable)
if (selectElm.selectedIndex != $( this).attr('index') && selectElm.onchange) {
selectElm.selectedIndex = $( this).attr('index');
selectElm.onchange();
}
if (selectElm.selectedIndex != $( this).attr('index')) {
selectElm.selectedIndex = $( this).attr('index');
selectElm.trigger('change');
}
return false;
});
selectedOption.click( function(){
var optionListAll = $('#'+mfsId);
if (optionList.is(':visible')) {
optionList.hide();
mfsSelectOpen = true;
}
else {
optionListLi.removeClass('active');
optionListAll.hide();
optionList.show();
var optionListSelected = optionList.find('li.mfs-option.selected');
if (optionListSelected.length > 0) {
optionListSelected.addClass('active');
}
else {
optionList.find('li.mfs-option:first-child').addClass('active');
}
mfsSelectOpen = optionList;
}
$( this).blur();
return false;
});
optionListLi.mouseover( function(){
optionListLi.removeClass('active');
$( this).addClass('active');
});
}; //end enableMagic
enableMagic( this.$wrap);
},
ztree: function(){
var treeId = this.id+ "_tree";
//<ul id="treeDemo" class="ztree"></ul>
this.$options = $('<ul id= "'+treeId+'" class= "mfs-options ztree">').insertAfter( this.$selected);
var theContainer = this.$wrap;
var optionList = theContainer.find('#'+treeId);
var selectedOption = theContainer.find('a.mfs-selected-option');
var srcElem = this.target;
var idLabel = this.opts.idLabel;
var zTreeOnClick= function(event, treeId, treeNode) {
selectedOption.html(treeNode.name+'<span> </span>'); //span 为下拉箭头占位符
srcElem.value=treeNode[idLabel];
optionList.hide();
};
var setting = {
data: {
simpleData: {
enable: true,
idKey: this.opts.idLabel,
pIdKey: this.opts.pidLabel
}
},
callback: {
onClick: zTreeOnClick
}
};
this.oper = $.fn.zTree.init($( "#"+treeId), setting, this.opts.items);
//设置默认值
var nodes = this.oper.getNodesByParam(idLabel, this.value, null);
if(nodes.length>0){
var nodeName = (nodes[0])[ this.opts.textLabel];
selectedOption.html(nodeName+'<span> </span>'); //span 为下拉箭头占位符
this.oper.selectNode(nodes[0], true);
}
var enableMagic = function (theContainer){
var selectedOption = theContainer.find('a.mfs-selected-option');
optionList.hide();
selectedOption.click( function(){
if (optionList.is(':visible')) {
optionList.hide();
}
else {
optionList.show();
}
$( this).blur();
return false;
});
} //end enableMagic
enableMagic( this.$wrap);
}
};
$.fn.droptree = function(options){
return this.each( function(){
if(!$.data( this,'droptree')){
$.data( this,'droptree', new DropTree( this,options));
}
});
};
})(jQuery)
下拉树
*/
( function($){
var defaults={
idLabel: "code",
textLabel: "name",
pidLabel: "pid",
transition: "ztree",
items:[]
};
/**
target:input element;
*/
function DropTree(target,options){
this.target = target;
this.value = target.value;
this.$target = $(target);
this.opts = $.extend({}, defaults, options, this.$target.data());
this.id = this.target.id || this.target.name;
if( this.$target.length >0){
this._init();
}
return this;
}
DropTree.prototype._init = function(){
var self = this;
this.$target.hide();
this.$wrap = this.$target.wrap('<div class= "mfs-container">').parent();
this.$selected = $('<a class= "mfs-selected-option" href= "#" />').prependTo( this.$wrap);
//this.$selected.css("height",15);
this.$selected.html( this.value+ " ");
this.$down = $( "<span> </span>").prependTo( this.$selected);
this.transition = Transitions[ this.opts.transition].call( this);
};
var Transitions = {
mfs: function(){
var mfsId = this.id+ "_mfs";
this.$options = $('<ul class= "mfs-options" id= "'+mfsId+'"/>').insertAfter( this.$selected);
var idLabel = this.opts.idLabel;
var textLabel = this.opts.textLabel;
var $options = this.$options;
//var (this.id);
$.each( this.opts.items, function(i,n){
var $op = $('<a href= "#" index= "'+i+'">'+n[textLabel]+'</a>').wrap('<li class= "mfs-option">').parent();
$options.prepend($op);
});
//添加活力
var enableMagic = function (theContainer){
//TODO 可配置
var selectElm = theContainer.find('select');
var selectElmOptions = selectElm.find('option');
var optionList = theContainer.find('#'+mfsId);
var optionListLi = optionList.find('li.mfs-option');
var selectedOption = theContainer.find('a.mfs-selected-option');
var optionListOptions = optionList.find('a');
optionList.hide();
optionListOptions.click( function(){
optionListLi.removeClass('active').removeClass('selected');
$( this).closest('li').addClass('selected');
selectedOption.html($( this).text()+'<span> </span>');
selectElmOptions.removeAttr('selected');
selectElmOptions.eq($( this).attr('index')).prop('selected', 'selected');
optionList.hide();
// Make a refresh function that just updates the select magic (destroy and re-enable)
if (selectElm.selectedIndex != $( this).attr('index') && selectElm.onchange) {
selectElm.selectedIndex = $( this).attr('index');
selectElm.onchange();
}
if (selectElm.selectedIndex != $( this).attr('index')) {
selectElm.selectedIndex = $( this).attr('index');
selectElm.trigger('change');
}
return false;
});
selectedOption.click( function(){
var optionListAll = $('#'+mfsId);
if (optionList.is(':visible')) {
optionList.hide();
mfsSelectOpen = true;
}
else {
optionListLi.removeClass('active');
optionListAll.hide();
optionList.show();
var optionListSelected = optionList.find('li.mfs-option.selected');
if (optionListSelected.length > 0) {
optionListSelected.addClass('active');
}
else {
optionList.find('li.mfs-option:first-child').addClass('active');
}
mfsSelectOpen = optionList;
}
$( this).blur();
return false;
});
optionListLi.mouseover( function(){
optionListLi.removeClass('active');
$( this).addClass('active');
});
}; //end enableMagic
enableMagic( this.$wrap);
},
ztree: function(){
var treeId = this.id+ "_tree";
//<ul id="treeDemo" class="ztree"></ul>
this.$options = $('<ul id= "'+treeId+'" class= "mfs-options ztree">').insertAfter( this.$selected);
var theContainer = this.$wrap;
var optionList = theContainer.find('#'+treeId);
var selectedOption = theContainer.find('a.mfs-selected-option');
var srcElem = this.target;
var idLabel = this.opts.idLabel;
var zTreeOnClick= function(event, treeId, treeNode) {
selectedOption.html(treeNode.name+'<span> </span>'); //span 为下拉箭头占位符
srcElem.value=treeNode[idLabel];
optionList.hide();
};
var setting = {
data: {
simpleData: {
enable: true,
idKey: this.opts.idLabel,
pIdKey: this.opts.pidLabel
}
},
callback: {
onClick: zTreeOnClick
}
};
this.oper = $.fn.zTree.init($( "#"+treeId), setting, this.opts.items);
//设置默认值
var nodes = this.oper.getNodesByParam(idLabel, this.value, null);
if(nodes.length>0){
var nodeName = (nodes[0])[ this.opts.textLabel];
selectedOption.html(nodeName+'<span> </span>'); //span 为下拉箭头占位符
this.oper.selectNode(nodes[0], true);
}
var enableMagic = function (theContainer){
var selectedOption = theContainer.find('a.mfs-selected-option');
optionList.hide();
selectedOption.click( function(){
if (optionList.is(':visible')) {
optionList.hide();
}
else {
optionList.show();
}
$( this).blur();
return false;
});
} //end enableMagic
enableMagic( this.$wrap);
}
};
$.fn.droptree = function(options){
return this.each( function(){
if(!$.data( this,'droptree')){
$.data( this,'droptree', new DropTree( this,options));
}
});
};
})(jQuery)
整合点在:Transitions 对象。明眼人一眼就看出来了:该对象提供两个方法:
mfs: 主要参照mfs 插件,构建下拉列表的内容
ztree: 借助ztree 构建 下拉列表树
当然, 没用过ztree的盆友,也可以用其他的tree 插件。当然,那要自己在Transitions 添加了。 总之,跳跳大路通罗马
html 使用
<
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
>
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=utf-8" />
< title >无标题文档 </title>
< script type ="text/javascript" src ="jquery-1.9.1.min.js" > </script>
< script type ="text/javascript" src ="jquery.ztree.all-3.5.js" > </script>
< script type ="text/javascript" src ="droptree.js" > </script>
< link href ="droptree_style.css" rel ="stylesheet" />
< link href ="zTreeStyle/zTreeStyle.css" rel ="stylesheet" />
</head>
< script type ="text/javascript" >
$(document).ready(function(){
$("#simple-select").droptree({
transition:'mfs',
items:[{code:'man',name:'男人'},
{code:'woman',name:'女人'},
{code:'yao',name:'人妖'}
]}
);
$("#simple_input").droptree({items:[
{code:'root',name:'根节点',pid:-1},
{code:'man',name:'男装',pid:'root'},
{code:'woman',name:'女装',pid:'root'},
{code:'man1',name:'男装1',pid:'man'},
{code:'man2',name:'男装2',pid:'man'},
{code:'woman1',name:'女装1',pid:'woman'}
],
transition:"ztree"
});
});
</script>
</head>
< body >
< div class ="wrap" style ="width:600px; margin:0 auto; margin-top:200px" >
< div style ="width:60px;float:left" >
< select id ="simple-select" name ="simple-select" >
< option value ="opt1" >option 1 </option>
< option value ="opt2" >option 2 </option>
< option value ="opt3" selected ="selected" >option 3 </option>
</select>
</div>
< div style ="float:right" >
< input type ="text" name ="simple_input" id ="simple_input" value ="man2" />
</div>
</div>
</body>
</html>
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=utf-8" />
< title >无标题文档 </title>
< script type ="text/javascript" src ="jquery-1.9.1.min.js" > </script>
< script type ="text/javascript" src ="jquery.ztree.all-3.5.js" > </script>
< script type ="text/javascript" src ="droptree.js" > </script>
< link href ="droptree_style.css" rel ="stylesheet" />
< link href ="zTreeStyle/zTreeStyle.css" rel ="stylesheet" />
</head>
< script type ="text/javascript" >
$(document).ready(function(){
$("#simple-select").droptree({
transition:'mfs',
items:[{code:'man',name:'男人'},
{code:'woman',name:'女人'},
{code:'yao',name:'人妖'}
]}
);
$("#simple_input").droptree({items:[
{code:'root',name:'根节点',pid:-1},
{code:'man',name:'男装',pid:'root'},
{code:'woman',name:'女装',pid:'root'},
{code:'man1',name:'男装1',pid:'man'},
{code:'man2',name:'男装2',pid:'man'},
{code:'woman1',name:'女装1',pid:'woman'}
],
transition:"ztree"
});
});
</script>
</head>
< body >
< div class ="wrap" style ="width:600px; margin:0 auto; margin-top:200px" >
< div style ="width:60px;float:left" >
< select id ="simple-select" name ="simple-select" >
< option value ="opt1" >option 1 </option>
< option value ="opt2" >option 2 </option>
< option value ="opt3" selected ="selected" >option 3 </option>
</select>
</div>
< div style ="float:right" >
< input type ="text" name ="simple_input" id ="simple_input" value ="man2" />
</div>
</div>
</body>
</html>
还有一点要注意:适合使用该插件的组件,是form 元素:如input/select| 其他元素使用不合适。
想一想,我们使用下拉选择树,就是获取选择值的,传到后台处理的。如果为radio、checkbox使用了。
那就不是下拉系列了.呵呵。 如果为textarea, 也未尝不可,我只能用赵本山小品一句话,回答阁下:[我看你是,没事吃饱撑着的型]
当然 需要完善的地方也有很多:
如:
1.ajax 支持
2.多选支持
=========================================================
接下来, 应该可以进一步封装下,封装成jsp 标签。 剩下的就是时间问题了
本文出自 “简单” 博客,请务必保留此出处http://dba10g.blog.51cto.com/764602/1188190