easyui源码翻译1.32--Combo(自定义下拉框)
前言
扩展自$.fn.validatebox.defaults。使用$.fn.combo.defaults重写默认值对象。下载该插件翻译源码
自定义下拉框显示一个可编辑的文本框和下拉面板在html页面。这是构建其他复杂的组合部件(如:combobox,combotree,combogrid等)之前需要构建的最基本的组件
依赖关系
- validatebox
- panel
源码
/**
* jQuery EasyUI 1.3.2
*
*翻译:qq 1364386878 自定义下拉框
*/
(function ($) {
//调整组件宽度
function _resize(jq, width) {
var opts = $.data(jq, "combo").options;
var combo = $.data(jq, "combo").combo;
var panel = $.data(jq, "combo").panel;
if (width) {
opts.width = width;
}
if (isNaN(opts.width)) {
var c = $(jq).clone();
c.css("visibility", "hidden");
c.appendTo("body");
opts.width = c.outerWidth();
c.remove();
}
combo.appendTo("body");
var combotext = combo.find("input.combo-text");
var comboarrow = combo.find(".combo-arrow");
var arrowWidth = opts.hasDownArrow ? comboarrow._outerWidth() : 0;//下拉箭头宽度
combo._outerWidth(opts.width)._outerHeight(opts.height);
combotext._outerWidth(combo.width() - arrowWidth);
combotext.css({ height: combo.height() + "px", lineHeight: combo.height() + "px" }); comboarrow._outerHeight(combo.height());
panel.panel("resize", {
width: (opts.panelWidth ? opts.panelWidth : combo.outerWidth()),
height: opts.panelHeight
});
combo.insertAfter(jq);
};
//是否显示下拉箭头
function setDownArrow(jq) {
var opts = $.data(jq, "combo").options;
var combo = $.data(jq, "combo").combo;
if (opts.hasDownArrow) {
combo.find(".combo-arrow").show();
} else {
combo.find(".combo-arrow").hide();
}
};
// 渲染组件
function renderCombo(target) {
$(target).addClass("combo-f").hide();
var combo = $("<span class=\"combo\"></span>").insertAfter(target);
var text = $("<input type=\"text\" class=\"combo-text\">").appendTo(combo);//将text框添加到combo
$("<span><span class=\"combo-arrow\"></span></span>").appendTo(combo);//将下来箭头添加到combo
$("<input type=\"hidden\" class=\"combo-value\">").appendTo(combo);//将隐藏域添加到combo以存放combo的value
var combpanel = $("<div class=\"combo-panel\"></div>").appendTo("body");//将下来面板添加到body
//设置下拉面板
combpanel.panel({
doSize: false,
closed: true,
cls: "combo-p",
style: { position: "absolute", zIndex: 10 },
onOpen: function () {
$(this).panel("resize");
}
});
var name = $(target).attr("name");
if (name) {
combo.find("input.combo-value").attr("name", name);
$(target).removeAttr("name").attr("comboName", name);
}
text.attr("autocomplete", "off");//关闭自动完成
return { combo: combo, panel: combpanel };
};
//销毁Combo
function _destroy(jq) {
var textBox = $.data(jq, "combo").combo.find("input.combo-text");
textBox.validatebox("destroy");
$.data(jq, "combo").panel.panel("destroy");
$.data(jq, "combo").combo.remove();
$(jq).remove();
};
//绑定事件
function bindEvents(jq) {
var combo = $.data(jq, "combo");
var opts = combo.options;
var combo2 = $.data(jq, "combo").combo;
var panel = $.data(jq, "combo").panel;
var combotext = combo2.find(".combo-text");
var comboarrow = combo2.find(".combo-arrow");//下拉箭头
$(document).unbind(".combo").bind("mousedown.combo", function (e) {
//鼠标点击combo外,关闭选择面板
var p = $(e.target).closest("span.combo,div.combo-panel");
if (p.length) {
return;
}
var combopanel = $("body>div.combo-p>div.combo-panel");
combopanel.panel("close");
});
//移除事件处理器
combo2.unbind(".combo");
panel.unbind(".combo");
combotext.unbind(".combo");
comboarrow.unbind(".combo");
//若组件未禁用,添加以下事件处理器
if (!opts.disabled) {
combotext.bind("mousedown.combo", function (e) {
$("div.combo-panel").not(panel).panel("close");
////该方法将停止事件的传播,阻止它被分派到其他 Document节点,
e.stopPropagation();
}).bind("keydown.combo", function (e) {
switch (e.keyCode) {
case 38://小键盘上箭头
opts.keyHandler.up.call(jq);
break;
case 40://小键盘下箭头
opts.keyHandler.down.call(jq);
break;
case 13://Enter键
e.preventDefault();
opts.keyHandler.enter.call(jq);
return false;
case 9://Tab键
case 27://Esc键
hidePanel(jq);
break;
default:
if (opts.editable) {
if (combo.timer) {
clearTimeout(combo.timer);
}
combo.timer = setTimeout(function () {
var q = combotext.val();
if (combo.previousValue != q) {
combo.previousValue = q;
$(jq).combo("showPanel");
opts.keyHandler.query.call(jq, combotext.val());
_validate(jq, true);
}
}, opts.delay);
}
}
});
//下拉箭头绑定事件
comboarrow.bind("click.combo", function () {
if (panel.is(":visible")) {
hidePanel(jq);
} else {
$("div.combo-panel").panel("close");
$(jq).combo("showPanel");
}
combotext.focus();
}).bind("mouseenter.combo", function () {
$(this).addClass("combo-arrow-hover");
}).bind("mouseleave.combo", function () {
$(this).removeClass("combo-arrow-hover");
}).bind("mousedown.combo", function () {
});
}
};
//showPanel
function _showPanel(jq) {
var opts = $.data(jq, "combo").options;
var combo = $.data(jq, "combo").combo;
var panel = $.data(jq, "combo").panel;
if ($.fn.window) {
//若放在窗口里面,则显示在窗口之上
panel.panel("panel").css("z-index", $.fn.window.defaults.zIndex++);
}
panel.panel("move", {
left: combo.offset().left,
top: getOffsetTop()
});
if (panel.panel("options").closed) {
panel.panel("open");
opts.onShowPanel.call(jq);
}
(function () {
if (panel.is(":visible")) {
panel.panel("move", {
left: getOffsetLeft(),
top: getOffsetTop()
});
setTimeout(arguments.callee, 200);
}
})();
//* 获取Left位置
function getOffsetLeft() {
var left = combo.offset().left;
if (left + panel._outerWidth() > $(window)._outerWidth() + $(document).scrollLeft()) {
left = $(window)._outerWidth() + $(document).scrollLeft() - panel._outerWidth();
}
if (left < 0) {
left = 0;
}
return left;
};
// 获取TOP位置
function getOffsetTop() {
var top = combo.offset().top + combo._outerHeight();
if (top + panel._outerHeight() > $(window)._outerHeight() + $(document).scrollTop()) {
top = combo.offset().top - panel._outerHeight();
}
if (top < $(document).scrollTop()) {
top = combo.offset().top + combo._outerHeight();
}
return top;
};
};
// 隐藏下拉选择面板
function hidePanel(jq) {
var opts = $.data(jq, "combo").options;
var panel = $.data(jq, "combo").panel;
panel.panel("close");
opts.onHidePanel.call(jq);
};
//校验值
function _validate(jq, tag) {
var opts = $.data(jq, "combo").options;
var textBox = $.data(jq, "combo").combo.find("input.combo-text");
textBox.validatebox(opts);
if (tag) {
textBox.validatebox("validate");
}
};
// 设置禁用/启用组件样式
function _disable(jq, disabled) {
var opts = $.data(jq, "combo").options;
var combo = $.data(jq, "combo").combo;
if (disabled) {
opts.disabled = true;
$(jq).attr("disabled", true);
combo.find(".combo-value").attr("disabled", true);
combo.find(".combo-text").attr("disabled", true);
} else {
opts.disabled = false;
$(jq).removeAttr("disabled");
combo.find(".combo-value").removeAttr("disabled");
combo.find(".combo-text").removeAttr("disabled");
}
};
// 清空combo值
function _clear(jq) {
var opts = $.data(jq, "combo").options;
var combo = $.data(jq, "combo").combo;
if (opts.multiple) {
combo.find("input.combo-value").remove();
} else {
combo.find("input.combo-value").val("");
}
combo.find("input.combo-text").val("");
};
//获取text值
function _getText(jq) {
var combo = $.data(jq, "combo").combo;
return combo.find("input.combo-text").val();
};
//设置text值
function _setText(jq, text) {
var combo = $.data(jq, "combo").combo;
combo.find("input.combo-text").val(text);
_validate(jq, true);
$.data(jq, "combo").previousValue = text;
};
//获取值(多选)
function _getValues(jq) {
var values = [];
var combo = $.data(jq, "combo").combo;
combo.find("input.combo-value").each(function () {
values.push($(this).val());
});
return values;
};
//设置值(多选)
function _setValues(jq, values) {
var opts = $.data(jq, "combo").options;
var nowValues = _getValues(jq);//获取当前值数组
var combo = $.data(jq, "combo").combo;
combo.find("input.combo-value").remove();//清空原来的值
var name = $(jq).attr("comboName");
for (var i = 0; i < values.length; i++) {
var _4c = $("<input type=\"hidden\" class=\"combo-value\">").appendTo(combo);
if (name) {
_4c.attr("name", name);
}
_4c.val(values[i]);
}
var tmp = [];
for (var i = 0; i < nowValues.length; i++) {
tmp[i] = nowValues[i];
}
var aa = [];
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < tmp.length; j++) {
if (values[i] == tmp[j]) {
aa.push(values[i]);
//splice()方法用于插入、删除或替换数组的元素,详细参考http://www.w3school.com.cn/js/jsref_splice.asp
tmp.splice(j, 1);
break;
}
}
}
////若设置值数组与原值数组不相等,则将设置值数组、原值数组返回给onChange事件作为参数,并响应事件
if (aa.length != values.length || values.length != nowValues.length) {
if (opts.multiple) {
opts.onChange.call(jq, values, nowValues);
} else {
opts.onChange.call(jq, values[0], nowValues[0]);
}
}
};
//获取值(单选)
function _getValue(jq) {
var values = _getValues(jq);
return values[0];
};
//设置值(单选)
function _setValue(jq, value) {
_setValues(jq, [value]);
};
//初始化combo值
function initValue(jq) {
var opts = $.data(jq, "combo").options;
var fn = opts.onChange;
opts.onChange = function () { };
//如果设置多选
if (opts.multiple) {
if (opts.value) {
if (typeof opts.value == "object") {
_setValues(jq, opts.value);
} else {
_setValue(jq, opts.value);
}
} else {
_setValues(jq, []);
}
opts.originalValue = _getValues(jq);
} else {
_setValue(jq, opts.value);
opts.originalValue = opts.value;
}
opts.onChange = fn;
};
//实例化下拉框
$.fn.combo = function (target, parm) {
if (typeof target == "string") {
return $.fn.combo.methods[target](this, parm);
}
target = target || {};
return this.each(function () {
var combo = $.data(this, "combo");
if (combo) {
$.extend(combo.options, target);
} else {
var r = renderCombo(this);
combo = $.data(this, "combo", {
options: $.extend({},
$.fn.combo.defaults,
$.fn.combo.parseOptions(this),
target),
combo: r.combo,
panel: r.panel,
previousValue: null
});
$(this).removeAttr("disabled");
}
$("input.combo-text", combo.combo).attr("readonly", !combo.options.editable);
setDownArrow(this);//设置是否显示下拉箭头
_disable(this, combo.options.disabled);//设置是否禁用
_resize(this);
bindEvents(this);
_validate(this);
initValue(this);//初始化combo值
});
};
//默认方法
$.fn.combo.methods = {
//返回属性对象
options: function (jq) {
return $.data(jq[0], "combo").options;
},
//返回下拉面板对象
panel: function (jq) {
return $.data(jq[0], "combo").panel;
},
//返回文本框对象
textbox: function (jq) {
return $.data(jq[0], "combo").combo.find("input.combo-text");
},
//销毁该组件
destroy: function (jq) {
return jq.each(function () {
_destroy(this);
});
},
// 调整组件宽度
resize: function (jq, width) {
return jq.each(function () {
_resize(this, width);
});
},
//显示下拉面板
showPanel: function (jq) {
return jq.each(function () {
_showPanel(this);
});
},
//隐藏下拉面板
hidePanel: function (jq) {
return jq.each(function () {
hidePanel(this);
});
},
//禁用组件
disable: function (jq) {
return jq.each(function () {
_disable(this, true);
bindEvents(this);
});
},
//启用组件
enable: function (jq) {
return jq.each(function () {
_disable(this, false);
bindEvents(this);
});
},
//验证输入的值
validate: function (jq) {
return jq.each(function () {
_validate(this, true);
});
},
//返回验证结果
isValid: function (jq) {
var combo = $.data(jq[0], "combo").combo.find("input.combo-text");
return combo.validatebox("isValid");
},
//清除控件的值
clear: function (jq) {
return jq.each(function () {
_clear(this);
});
},
//重置控件的值
reset: function (jq) {
return jq.each(function () {
var opts = $.data(this, "combo").options;
if (opts.multiple) {
$(this).combo("setValues", opts.originalValue);
} else {
$(this).combo("setValue", opts.originalValue);
}
});
},
//获取输入的文本
getText: function (jq) {
return _getText(jq[0]);
},
//设置输入的文本
setText: function (jq, text) {
return jq.each(function () {
_setText(this, text);
});
},
//获取组件值的数组
getValues: function (jq) {
return _getValues(jq[0]);
},
//设置组件值的数组
setValues: function (jq, values) {
return jq.each(function () {
_setValues(this, values);
});
},
//获取组件的值
getValue: function (jq) {
return _getValue(jq[0]);
},
//设置组件的值
setValue: function (jq, value) {
return jq.each(function () {
_setValue(this, value);
});
}
};
//解析器 定义属性转化为options
$.fn.combo.parseOptions = function (target) {
var t = $(target);
return $.extend({}, $.fn.validatebox.parseOptions(target),
$.parser.parseOptions(target, ["width", "height", "separator",
{ panelWidth: "number", editable: "boolean", hasDownArrow: "boolean", delay: "number" }]),
{
panelHeight: (t.attr("panelHeight") == "auto" ? "auto" : parseInt(t.attr("panelHeight")) || undefined),
multiple: (t.attr("multiple") ? true : undefined),
disabled: (t.attr("disabled") ? true : undefined),
value: (t.val() || undefined)
});
};
//默认属性和事件
$.fn.combo.defaults = $.extend({}, $.fn.validatebox.defaults, {
width: "auto",//组件的宽度
height: 22,//组件的高度
panelWidth: null,//下拉面板宽度
panelHeight: 200,//下拉面板高度
multiple: false,//定义是否支持多选
separator: ",",//在多选的时候使用何种分隔符进行分割
editable: true,//定义用户是否可以直接输入文本到字段中
disabled: false,//定义是否禁用字段
hasDownArrow: true,//定义是否显示向下箭头按钮。
value: "",//字段的默认值
delay: 200,//最后一次输入事件与执行搜索之间的延迟间隔(执行自动完成功能的延迟间隔)
//在用户按下键的时候调用一个函数
keyHandler: {
up: function () {},
down: function () {},
enter: function () {},
query: function (q) {}
},
//当下拉面板显示的时候触发
onShowPanel: function () {},
//当下拉面板隐藏的时候触发
onHidePanel: function () {},
//当字段值改变的时候触发
onChange: function (newValue, oldValue) {}
});
})(jQuery);
示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Basic Combo - jQuery EasyUI Demo</title>
<link rel="stylesheet" type="text/css" href="../../themes/default/easyui.css">
<link rel="stylesheet" type="text/css" href="../../themes/icon.css">
<link rel="stylesheet" type="text/css" href="../demo.css">
<script type="text/javascript" src="../../jquery-1.8.0.min.js"></script>
<script src="../../plugins2/jquery.parser.js"></script>
<script src="../../plugins2/jquery.validatebox.js"></script>
<script src="../../plugins2/jquery.panel.js"></script>
<script src="../../plugins2/jquery.combo.js"></script>
</head>
<body>
<h2>Basic Combo</h2>
<div class="demo-info" style="margin-bottom:10px">
<div class="demo-tip icon-tip"></div>
<div>Click the right arrow button to show drop down panel that can be filled with any content.</div>
</div>
<select id="cc" style="width:150px"></select>
<div id="sp">
<div style="color:#99BBE8;background:#fafafa;padding:5px;">Select a language</div>
<input type="radio" name="lang" value="01"><span>Java</span><br/>
<input type="radio" name="lang" value="02"><span>C#</span><br/>
<input type="radio" name="lang" value="03"><span>Ruby</span><br/>
<input type="radio" name="lang" value="04"><span>Basic</span><br/>
<input type="radio" name="lang" value="05"><span>Fortran</span>
</div>
<script type="text/javascript">
$(function(){
$('#cc').combo({
required:true,
editable:false
});
$('#sp').appendTo($('#cc').combo('panel'));
$('#sp input').click(function(){
var v = $(this).val();
var s = $(this).next('span').text();
$('#cc').combo('setValue', v).combo('setText', s).combo('hidePanel');
});
});
</script>
</body>
</html>
插件效果
easyui源码翻译1.32--Combo(自定义下拉框)的更多相关文章
- easyui源码翻译1.32--ComboTree(树形下拉框)
前言 扩展自$.fn.combo.defaults和$.fn.tree.defaults.使用$.fn.combotree.defaults重写默认值对象.下载该插件翻译源码 树形下拉框结合选择控件和 ...
- 第二百一十二节,jQuery EasyUI,Combo(自定义下拉框)组件
jQuery EasyUI,Combo(自定义下拉框)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方 ...
- Combo( 自定义下拉框) 组件
本节课重点了解 EasyUI 中 Combo(自定义下拉框)组件的使用方法,这个组件依赖于ValidateBox(验证框)组件 一. 加载方式自定义下拉框不能通过标签的方式进行创建.<input ...
- easyui源码翻译1.32+API翻译全篇导航 (提供下载源码)
前言 EasyUI每个组件都会有 属性.方法.事件 属性 所有的属性都定义在jQuery.fn.{plugin}.defaults里面.例如,对话框属性定义在jQuery.fn.dialog.defa ...
- jq--实现自定义下拉框
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- jquery美化select,自定义下拉框样式
select默认的样式比较丑,有些应用需要美化select,在网上找到一个很好的美化样式效果,本人很喜欢,在这里分享一下. <!DOCTYPE html PUBLIC "-//W3C/ ...
- 关于safari上的select宽高问题小技,自定义下拉框
之前一直用windows做开发,最近换了个mac,在几经折腾之下,安装完了各种开发工具,IDE等,然后欣然打开自己正在开发的网站.突然发现mac上所有的下拉框都变了,都是默认样式,无论padding, ...
- vue自定义下拉框组件
创建下拉框组件 Select.vue <template> <div class="selects"> <div :class="{sele ...
- easyui源码翻译1.32--datagrid(数据表格)
前言 此前网上有easyui1.25的源码 应该算是比较老的版本 之后又经历了1.26 . 1.3. 1.31. 1.32 .1.33.1.34 1.33开始支持css3 算是又一个转折 但是 ...
随机推荐
- java基础总结
/查看数组是否为空 String[] aorgPks = userRole.getAssignOrgPks(); if(ArrayUtils.isEmpty(aorgPks)){ //uapstudi ...
- ArryList vs LinkedList
references: http://www.javaperformancetuning.com/articles/randomaccess.shtml http://stackoverflow.co ...
- Mysql 冷备份批处理
@Rem Generate today date @echo wscript.echo dateadd("d",0,date)>GetOldDate.vbs @for /f ...
- cocos2d-x实战 C++卷 学习笔记--第5章 精灵
前言: 精灵类是Sprite类.它的子类有PhysicsSprite 和 Skin. PhysicsSprite 是物理引擎精灵类,而Skin是皮肤精灵类,用于骨骼动画. 创建Sprite精灵对象 创 ...
- 用法简单的图片和视频播放的框架Demo
最近在恶补自己不足的基础知识,偶然在一个QQ群里看到作为同行业的大神们在开源自己的代码.并且在炫耀说让我们找Bug,于是出于好奇就看了下,点开了一个关于图片和视频播放的Demo.也就是接下来我要说的这 ...
- TreeSet集合
TreeSet集合 TreeSet集合是一个依靠TreeMap实现的有序集合,内部存储元素是自动按照自然排序进行排列,所以如果想要保留存储时的顺序,那么就不建议使用TreeSet. TreeSet继承 ...
- jtemplate使用笔记
最近的项目中用到了jtemplate, 它是客户端基于javascript的模板引擎,绑定的数据为json对象.以前我在页面上显示数据列表时最喜欢用Repeater控件了,因为它相对与其它几个服务端控 ...
- C# 链表操作
关于链表操作,在C#当中微软已经提供了一个LinkedList<T>的数据结构,通过这个类提供的一系列方法就能够实现链表操作. 这里我提供一段代码,这是在论坛里面有人提问时给出的代码,它实 ...
- 安装Android Studio报failed to find java version for 'C:\windows\system32\java.exe':[2] The system cannot find the specified file.错误的解决方案
方案很简单,找到SYSTEM32目录下的java.exe文件,重命名为java.exe.orj. 方案出处:http://stackoverflow.com/questions/10339679/an ...
- 利用数据库链做DML操作时报ORA-02069: global_names parameter must be set to TRUE for this operation
按照 http://space.itpub.net/195110/viewspace-711110 的说法顺利解决问题. 通过DBLink更新远程数据的时候,如果使用到本地的sequence.函数.过 ...