自己寫的Jquery DropTree下拉選擇樹插件
閑話少聊,今天本人重點看了看jquery插件開發這一塊。想通過代碼,實際練下兵。當然,也是為了解決項目的實際需要。平時,我們經常遭遇"選擇框"這個控件。 平時,如果我們的選擇項非常簡單, 一般用瀏覽器自帶的select 就OK了。但是如果字典項直接存在上下級關系,也就是經常見到的樹結構 ,那就非常非常難受了。自己很納悶,為什么jquery插件千千萬,為什么就沒有這么一款插件呢,一般就是純粹的樹插件, 要不就是下拉框插件。總之,個人沒有找到滿足自己要求的插件。那就自己就著手寫一個吧。
先亮底牌,展示效果。
主要有兩種效果:
第一種:對于數據一般情況, 用瀏覽器的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)
整合點在: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>
還有一點要注意:適合使用該插件的組件,是form 元素:如input/select| 其他元素使用不合適。
想一想,我們使用下拉選擇樹,就是獲取選擇值的,傳到后臺處理的。如果為radio、checkbox使用了。
那就不是下拉系列了.呵呵。 如果為textarea, 也未嘗不可,我只能用趙本山小品一句話,回答閣下:[我看你是,沒事吃飽撐著的型]
當然 需要完善的地方也有很多:
如:
1.ajax 支持
2.多選支持
=========================================================
接下來, 應該可以進一步封裝下,封裝成jsp 標簽。 剩下的就是時間問題了