js代码实现部分 singleSelect.js
/* 单选控件 js begin */
/**
* 它带有两个参数:一个是要创建的插件名称,一个是包含支持插件的函数的对象文字。
*/
$.widget("jd.singleSelect", {
/**
* 默认参数
*
* inputId: 输入框id
*
* componentId : 控件渲染的id
*
* openId: 弹出框的id
*
* items : 所有选项, 格式[{"id":"0","name":"xx","selected":false},...]
*
* excludes : 排除数组 格式'id0'
*
* selected : 已选中ID.
*
* showType : 显示文本方式, 0:表示显示id,1:表示显示文本
*
* filterCountFormat :显示符合查询条件项目数显示格式 selectedCountFormat : 已选项目数显示格式
*
* saveFilterText: 是否保存过滤文本
*
* title : 窗口标题
*
* readOnly : true, 隐藏输入框name
*
* completed : null, 事件名称
*
* filtered : null 筛选事件名称
*
* scrollId : 滚动条id
*
* filterLiWidth : '200px',//默认列表最小宽度
*
* dialogHeader : false,// 是否显示dialog默认的标题头样式
*
* dialogBgColor : '#767779',// 默认 对话框背景色
*
* dialogBgUrl : 'url("")',// 默认 对话框背景图片url
*
* dialogBgPosition : 'center center',// 默认 对话框背景图片position
*
* dialogBgRepeat : 'no-repeat',// 默认 对话框背景图片repeat
*
*/
options : {
inputHiddenId : null,
inputId : null,
readonlyFlag : true,
inputWidth : null,
inputHeight : null,
inputValue : null,
inputClass : [],
componentId : '',
openId : '',
eventId : null,
items : [],
excludes : [],
selected : null,
showType : 1,
itemCountFormat : "共:{0}项",
filterCountFormat : "符合条件:{0}项",
saveFilterText : false,
title : '',// 窗口标题
completed : null,
filtered : null,
scrollId : null,
filterLiWidth : '200px',// 默认列表最小宽度
dialogHeader : false,// 是否显示dialog默认的标题头样式
dialogBgColor : '#767779',// 默认 对话框背景色
dialogBgUrl : 'url("")',// 默认 对话框背景图片url
dialogBgPosition : 'center center',// 默认 对话框背景图片position
dialogBgRepeat : 'no-repeat',// 默认 对话框背景图片repeat
// dialog默认配置
autoOpen : false,
closeOnEscape : true,
hide : "slide",
modal : true,
height : "auto",
width : 'auto',
resizable : false
},
_init : function() {
// this._super();
// 创建控件,控件生命周期内会运行多次
this._initComponent();
this._showItems();
this._showText();
var elemMouseWheel = document.getElementById(this.options.scrollId);
// 浏览器兼容firefox(火狐使用的滚动条触发事件DOMMouseScroll),ie,chrome
// Firefox使用DOMMouseScroll,其他的浏览器使用mousewheel
// Firefox可以使用addEventListener方法绑定DomMouseScroll事件.elem.addEventListener(‘DOMMouseScroll’,
// func, false);
var firefox = navigator.userAgent.indexOf('Firefox') != -1;
firefox ? elemMouseWheel.addEventListener('DOMMouseScroll', this._initHorizontalMouseWheel, false) : (elemMouseWheel.onmousewheel = this._initHorizontalMouseWheel);
},
_create : function() {
// 初始化,控件生命周期内只运行一次
/*
* $(this)代表input this.options.sss = 'K' + parseInt(Math.random() *
* 100000000, 10); a.添加div b.div 初始化成 ui.dialog $("#" +
* this.options.sss).dialog,({}); c.input的放大镜添加事件, div.dialog()
* d.dialog 本身的事件 如: 关闭事件和点击事件 点击事件是要关闭并赋值
*/
var self = this;
if (this.options.eventId == null) {
this.options.eventId = 'E' + parseInt(Math.random() * 100000000, 10);
}
if (this.options.scrollId == null) {
this.options.scrollId = 'K' + parseInt(Math.random() * 100000000, 10);
}
if (this.options.inputHiddenId == null) {
this.options.inputHiddenId = 'H' + parseInt(Math.random() * 100000000, 10);
}
$(this.element).append(
'<input id="' + this.options.inputId + '" class="' + this.options.inputClass + '" style="width:' + this.options.inputWidth + ';height:'
+ this.options.inputHeight + '" type="text" value="' + this.options.inputValue + '"/>' + '<b class="icon_search" id="' + this.options.eventId
+ '"></b>' + '<input id="' + this.options.inputHiddenId + '" type="hidden"/>');
if (this.options.readonlyFlag) {
$("#" + this.options.inputId).attr("readOnly", "readOnly");
} else {
$("#" + this.options.inputId).removeAttr("readOnly");
}
this.options.openId = 'P' + parseInt(Math.random() * 100000000, 10);
var divHtml = '<div id="' + this.options.openId + '" title="' + this.options.title + '" style="overflow: hidden;"></div>';
$('body').append(divHtml);
$("#" + this.options.openId).dialog({
autoOpen : self.options.autoOpen,
closeOnEscape : self.options.closeOnEscape,
hide : self.options.hide,
modal : self.options.modal,
height : self.options.height,
width : self.options.width,
resizable : self.options.resizable
});
},
_initHorizontalMouseWheel : function(e) {
// 浏览器兼容firefox
var firefox = navigator.userAgent.indexOf('Firefox') != -1;
var scrollBox = $('#' + this.id);
e = e || window.event;
// //阻止事件冒泡
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancelBubble = true;
}
// 阻止元素默认事件
if (e.preventDefault) {
e.preventDefault();// ie10,ie11
} else {
e.returnValue = false;// chrome
}
// 五大浏览器(IE、Opera、 Safari、Firefox、Chrome)中
// Firefox 使用detail,
// 其余四类使用wheelDelta;两者只在取值上不一致,代表含义一致,detail与wheelDelta只各取两个值,
// detail只取±3,其中正数表示为向下,负数表示向上。
// wheelDelta只取±120,其中正数表示为向上,负数表示向下。
if (firefox) {
// 浏览器兼容firefox
if (e.detail < 0) {
scrollBox.scrollLeft(scrollBox.scrollLeft() - 100);
} else {
scrollBox.scrollLeft(scrollBox.scrollLeft() + 100);
}
} else {
// 浏览器兼容ie,chrome
if (e.wheelDelta > 0) {
scrollBox.scrollLeft(scrollBox.scrollLeft() - 100);
} else {
scrollBox.scrollLeft(scrollBox.scrollLeft() + 100);
}
}
},
_initItems : function() {
// 初始化临时选项数组
var items = this.options.items;
var excludes = this.options.excludes;
/* 删除排除掉的元素 begin */
var tempMap = new Map(); // id为key, item为value
var exMap = new Map(); // id为key, id为value
for (var i = 0; i < excludes.length; i++) {
exMap.set(excludes[i], excludes[i]);
}
if (items != undefined && items != null) {
// 遍历全部项目,如果在exMap中存在,则删除
for (var i = items.length - 1; i >= 0; i--) {
var exItem = exMap.get(items[i].id);
if (exItem != undefined && exItem != null) {
items.splice(i, 1);
continue;
}
tempMap.set(items[i].id, items[i]);
}
}
/* 删除排除掉的元素 end */
},
_initComponent : function() {
this.options.componentId = 'K' + parseInt(Math.random() * 100000000, 10);
$(this.element).append('<div id="' + this.options.componentId + '" class="jd_single_select" />');
var component = $('#' + this.options.componentId);
var cmpHtml = "";
if (!this.options.dialogHeader) {
$(".ui-dialog[role='dialog']").children('.ui-widget-header').css({
'display' : 'none'
});
cmpHtml += '<div class="show_topbar">' + this.options.title + '<span class="btn_close"><b class="icon_close"></b></span>' + '</div><div class="filter_box">'
+ '<input class="filter_input" type="text"/><span class="item_count count_text"></span>' + '</div>' + '<div class="box_items" id="' + this.options.scrollId
+ '"></div>';
} else {
cmpHtml += '<div class="filter_box">' + '<input class="filter_input" type="text"/><span class="item_count count_text"></span>' + '</div>'
+ '<div class="box_items" id="' + this.options.scrollId + '"></div>';
}
component.html(cmpHtml);
$("#" + this.options.openId).html(component);
if (!this.options.dialogHeader) {
this._bindBtnClose();
}
this._bindBtnOpen();
this._bindFilterInput();
},
selected : function() {
return this.options.selected;
},
items : function() {
return this.options.items;
},
_showItems : function(isFilter) {
// 渲染列表页面
var leftHtml = "";
if (this.options.items != undefined && this.options.items != null) {
// 遍历全部项目,添加Option
var index = 0; // 表示可显示的item序号
var itemCount = this.options.items.length;
var filterCount = itemCount;// 可显示的item数
for (var i = 0; i < itemCount; i++) {
var item = this.options.items[i];
if (item.hidden) {
filterCount--;
} else {
if (index % 10 == 0) {
leftHtml += '<ul class="filter_list">';
}
if (item.id == this.options.selected) {
leftHtml += "<li itemId='" + item.id + "' itemIndex='" + i + "' itemName='" + item.name + "'>" + item.name + "</li>";
} else {
leftHtml += "<li itemId='" + item.id + "' itemIndex='" + i + "' itemName='" + item.name + "'>" + item.name + "</li>";
}
if (index % 10 == 9 || index == filterCount - 1) {
leftHtml += '</ul>';
}
index++;
}
}
var itemCountText = this.options.itemCountFormat.replace('{0}', itemCount + '');
if (isFilter) {
itemCountText = this.options.filterCountFormat.replace('{0}', filterCount + '');
}
$('#' + this.options.componentId + ' .item_count').html(itemCountText);
}
$('#' + this.options.scrollId).html(leftHtml);
this._bindItemClick();
},
_bindItemClick : function() {
// 选中点击事件
var self = this;
$('#' + this.options.componentId + ' .filter_list li').on('click', function() {
var index = $(this).attr("itemIndex");
var item = self.options.items[index];
self.options.selected = item.id;
$('#' + self.options.componentId + ' .filter_list li').removeClass('sel_active');
$('#' + self.options.componentId + " .filter_list li[itemId='" + item.id + "']").addClass('sel_active');
$("#" + self.options.openId).dialog("close");
self._trigger('completed', null, item);
});
},
_filter : function(text) {
// 根据项目显示相应内容
// 项目添加过滤属性 hidden: true 表示因过滤不显示
if (this.options.items != undefined && this.options.items != null) {
// 遍历全部项目,添加Option 如果项目已选中,则隐藏
$.each(this.options.items, function(index, item) { // 遍历二维数组
if (item.name.indexOf(text) >= 0) {
item["hidden"] = false;
} else {
item["hidden"] = true;
}
});
this._showItems(text != '');
this._trigger('filtered', null, text);
}
},
_bindFilterInput : function() {
// 输入事件
var self = this;
$('#' + this.options.componentId + ' .filter_input').on('input', function() {
self._filter($(this).val());
});
},
_bindBtnOpen : function() {
// 添加点击事件
var self = this;
$('#' + self.options.eventId).on('click', function() {
$("#" + self.options.openId).dialog("open");
$('.ui-widget-overlay').css({
'background-color' : self.options.dialogBgColor,
'background-image' : self.options.dialogBgUrl,
'background-position' : self.options.dialogBgPosition,
'background-repeat' : self.options.dialogBgRepeat,
});
$('.filter_list li').css({
'min-width' : self.options.filterLiWidth
});
if (!self.options.saveFilterText && $('#' + self.options.componentId + ' .filter_input').val() != '') {
$('#' + self.options.componentId + ' .filter_input').val('');
self._filter('');
}
});
},
_bindBtnClose : function() {
var self = this;
$('#' + this.options.componentId + ' .btn_close').on('click', function() {
$("#" + self.options.openId).dialog("close");
});
},
_setOptions : function(options) {
var that = this;
$.each(options, function(key, value) {
that._setOption(key, value);
});
},
_setOption : function(key, value) {
// 设置参数
if (key === "items") {
this.options[key] = value;
return;
}
// In jQuery UI 1.9及以后用法
this._super(key, value); // 区分 option 是 自己的还是 dialog的?
// 如果是dialog的那么 调用 dialog.setOption
// In jQuery UI 1.8及以前用法
// $.Widget.prototype._setOption.apply(this, arguments);
},
_showText : function() {
var text = '';
var hiddenVal = '';
var selected = this.selected();
if (selected != undefined && selected != null) {
if (this.options.showType == 0) {
text = selected;
} else {
if (this.options.items != undefined && this.options.items != null) {
var itemCount = this.options.items.length;
for (var i = 0; i < itemCount; i++) {
var item = this.options.items[i];
if (item.id == selected) {
text = item.name;
hiddenVal = selected;
break;
}
}
}
}
}
$('#' + this.options.inputId).val(text);
$('#' + this.options.inputHiddenId).val(hiddenVal);
},
_trigger : function(type, event, data) {
if (type == 'completed') {
this._showText();
}
var callback = this.options[type];
if (callback != undefined && callback != null) {
callback(event, data);
}
},
destroy : function() {
// 释放控件
$(this.element).html("");
// In jQuery UI 1.8及以前用法
$.Widget.prototype.destroy.call(this);
// In jQuery UI 1.9及以后
}
});
/* 单选控件 js end */
})(jQuery);
html 页面部分
searchselect.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI 对话框(Dialog) - 默认功能</title>
<link rel="stylesheet" href="//apps.bdimg.com/libs/jqueryui/1.10.4/css/jquery-ui.min.css">
<script src="//apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//apps.bdimg.com/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="js/searchSelect.js"></script>
<link rel="stylesheet" href="css/searchSelectWidget.css"/>
<style>
</style>
<script>
$(function () {
$("#box").singleSelect({
inputId: 'singleIpt2',
inputHeight: "24px",
inputValue: null,
inputClass: 'result_input',
items: [
{id: '', name: '全部'},
{id: 'k2002', name: '这是文文文文文文本二'},
{id: 'k3003', name: '这是文文文文文文本三'},
{id: 'k4004', name: '这1文文文文文文本四'},
{id: 'k5005', name: '这1文文文文文文本五'},
{id: 'k6007', name: '这是文文文文文文本7'},
{id: 'k7008', name: '这是文文文文文文本8'},
{id: 'k8009', name: '这是文文文文文文本9'},
{id: 'k90010', name: '这是是是是是是文本10'},
{id: 'k0011', name: '这是是是是是是文文本11'},
{id: 'k0012', name: '这是是是是是是文本12'},
{id: 'k0013', name: '这是是是是是是文本13'},
{id: 'k0014', name: '这是是是是是是文本14'},
{id: 'k0009', name: '这是是是是是是文本15'},
{id: 'k00010', name: '这这这是文本16'},
{id: 'k00011', name: '这这这是文本17'},
{id: 'k00012', name: '这是文本本本本本18'},
{id: 'k00013', name: '这是文本本本本本19'},
{id: 'k10012', name: '这是是是是是是文本12'},
{id: 'k10013', name: '这是是是是是是文本13'},
{id: 'k01014', name: '这是是是是是是文本14'},
{id: 'k01009', name: '这是是是是是是文本15'},
{id: 'k001010', name: '这这这是文本16'},
{id: 'k001011', name: '这这这是文本17'},
{id: 'k001012', name: '这是文本本本本本18'},
{id: 'k001013', name: '这是文本本本本本19'},
{id: 'k001014', name: '这是文本本本本本20'},
{id: 'k01014', name: '这是文本本本本本114'},
{id: 'k010019', name: '这是文本本本本本115'},
{id: 'k0101010', name: '这是文文文文文本116'},
{id: 'k0101011', name: '这是文文文文文本117'},
{id: 'k0101012', name: '这是文文文文文本118'},
{id: 'k0101013', name: '这是文文文文文本119'},
{id: 'k0101014', name: '这是文文文文文本210'}
],
showType: 1,
title:'单项选择',
complete: function (event, data) {
}
});
});
</script>
</head>
<body>
<div id="box" class="input_box">
</div>
</body>
</html>
组件默认样式 singleSelectWidget.css
/*单选控件 style.css begin*/
/*单项 选择样式布局 部分本地图片不上传*/
.jd_single_select * {
margin: 0 !important;
padding: 0 !important;
font-size: 12px !important;
font-family: "Microsoft YaHei", 微软雅黑, "Microsoft JhengHei", 华文细黑, STHeiti, MingLiu !important;
color: #464c5b !important;
-webkit-font-smoothing: antialiased !important;
-moz-osx-font-smoothing: grayscale !important;
-webkit-text-size-adjust: none !important;
}
.jd_single_select .show_topbar {
box-sizing: border-box !important;
width: 100% !important;
height: 38px !important;
line-height: 38px !important;
font-size: 14px !important;
font-weight: 600 !important;
background-color: #f7f7f7 !important;
border-bottom: 1px solid #e4e9ed !important;
}
.jd_single_select .btn_close {
float: right !important;
width: 40px !important;
height: 40px !important;
cursor: pointer !important;
}
.jd_single_select .icon_close {
display: inline-block;
width: 16px !important;
height: 16px !important;
margin: 12px !important;
background: url("images/jd-widget/singleselect/closeTab.png") center center no-repeat !important;
background-size: cover !important;
cursor: pointer !important;
}
.jd_single_select .filter_box {
box-sizing: border-box !important;
width: 100% !important;
padding: 20px 30px 10px 10px !important;
}
.jd_single_select .filter_input {
box-sizing: border-box !important;
width: 325px !important;
height: 24px !important;
padding: 0 8px !important;
border: 1px solid #8fb7e6 !important;
border-radius: 3px !important;
}
/*显示共选择则数量*/
.jd_single_select .count_text {
display: inline-block !important;
padding-right: 0 !important;
margin-left: 8px !important;
text-align: right !important;
}
/*筛选 和 已选 列表项*/
.jd_single_select .box_items {
box-sizing: border-box !important;
width: 652px !important;
min-height: 294px !important;
padding: 6px 4px !important;
/*margin: 6px !important;*/
border: 1px solid #8fb7e6 !important;
background: #fff !important;
border-radius: 3px !important;
overflow-x: auto !important;
overflow-y: hidden !important;
display: flex !important;
display: -webkit-flex !important;
}
.jd_single_select .filter_list {
white-space: nowrap !important;
}
.jd_single_select .filter_list li {
padding: 0 8px 0 8px !important;
line-height: 28px !important;
border-bottom: none !important;
}
.jd_single_select .filter_list {
margin-right: 10px !important;
}
.jd_single_select .box_items .filter_list li:hover {
background-color: rgba(174, 174, 174, 0.67) !important;
border-radius: 3px !important;
cursor: pointer !important;
}
.jd_single_select .box_items .filter_list li.sel_active {
background: #4b71c2 !important;
color: #fff !important;
border-radius: 3px !important;
}
/*单选控件 style.css end*/
/*页面外部输入框样式*/
.input_box {
position: relative;
width: 160px;
height: 24px;
}
.result_input {
box-sizing: border-box !important;
height: 32px;
width: 100%;
padding-left: 4px;
padding-right: 12px;
vertical-align: middle !important;
border: 1px solid #d7dde4 !important;
border-radius: 3px !important;
box-shadow: none !important;
outline: none !important;
color: #464c5b;
font-size: 12px;
}
.input_box b.icon_search {
display: inline-block !important;
position: absolute !important;
right: 0px !important;
top: 50% !important;
margin-top: -10px;
width: 24px !important;
height: 24px !important;
background: url("images/jd-widget/singleselect/single_search.png") center bottom no-repeat !important;
cursor: pointer !important;
}
显示效果
![搜索输入操作框](https://i-blog.csdnimg.cn/blog_migrate/29b81b60325a8bff06dafd62279e3052.png)
![弹出框及内容样式](https://i-blog.csdnimg.cn/blog_migrate/8d23c93eb9bb96c28bbbd82516dba099.png)
![这是模糊筛选的效果](https://i-blog.csdnimg.cn/blog_migrate/8da19891231a20dc84ebafa69b107ca9.png)