简单易用,绑定一个div就能生成下拉列表
new Selector()的参数1:HTMLDivElement或div元素的id:,参数2(可选):选项数据的数组,参数3(可选):文本框值或选项改变时的回调函数(value, index, selector),下面有例子
方法介绍,除getValue()方法外的其他方法都支持链式调用Selector的自定义方法
方法 | 方法作用 | 其它说明 |
---|---|---|
setBoxCss(json) | 修改文本框样式 | 可传入任意div支持的样式 |
setPanelCss(json) | 修改下拉列表面板样式 | 可传入任意div支持的样式 |
setItemCss(json) | 修改下拉列表选项正常样式 | 可传入任意div支持的样式 |
setItemHoverCss(json) | 修改下拉列表选项正hover样式 | 可传入任意div支持的样式 |
setOptions(array,bool) | 设置选项 | 参数2为true代表临时设置,主要是过滤器用的 |
setCallback(function) | 设置文本框值改变或选项改变时的回调方法 | 回调有三个参数,对应值和索引和Selector本身引用,可在此调用它的方法 |
setFilter(function, bool) | 设置选项过滤器 | 回调返回选项值,返回false移除该选项,第一个参数传null不会修改过滤器,第二个参数可为true关闭过滤器 |
getOptsFromServer(json, function) | 通过url加载选项 | json是请求选项{url,method(可选),参数(可选)}回调作为数据适配器返回url请求响应的数据,默认适配器把data作为选项数据,可以在此对数据进行处理确保返回一个数组作为选项数据 |
updatePostParams(json) | 更新搜素参数,根据关键字重新搜索 | |
doFilter(string) | 主动过滤选项 | string是过滤关键字,在过滤器关闭时无效 |
showPanel() | 主动显示下拉面板 | |
hidePanel() | 主动隐藏下拉面板 | |
getValue() | 获取文本框的值 | 返回string不可以在其后链式调Selector其它自定义方法 |
setValue(string) | 设置文本框的值 |
效果图:
注:需依赖jquery,我用的是jquery1.11.3.min.js
Selectord代码
function Selector(id, options, callback) {
this.options = options || []; // 选项数据数
this.tempOptions = [];
this.callback = callback || function () {}; // 选项改变或文本框内容改变时的回调处理函数
this.urlOp = {}; // 请求,包含地址:url,请求方式:method,参数:data
this.dataAdapter = function () {}; // 数据适配器,如果返回数据不是数组需用此方法转化为数组做为选项数据
this.runFilter = false; // 文本输入时是否对选项进行过滤
this.filter = function (value, key) {
value = value || '';
key = key || '';
return value.indexOf(key) >= 0 || key.indexOf(value) >= 0;
}; // 选项过滤器,默认关闭
if(id && id.constructor == HTMLDivElement) {
this.ele = id;
} else {
this.ele = document.getElementById(id);
}
if(!this.ele || this.ele.constructor != HTMLDivElement) {
console.error('error id of div element bing on selector');
return {};
}
if(this.ele.tagName != 'DIV') {
console.error('please bind on div element');
return {};
}
this.defBoxCss = {
'padding-right':'20px',
'background':'url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8cmVjdCB4PSItMSIgeT0iLTEiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyMiIgaWQ9ImNhbnZhc19iYWNrZ3JvdW5kIiBmaWxsPSJub25lIi8+CiA8L2c+CiA8Zz4KICA8cG9seWdvbiBwb2ludHM9IjEyLjcxNDYwNzY4NTgwNDM2Nyw3LjYyOTAyMjU5ODI2NjYwMiA4LjI4Mzk2NjUxMTQ4Nzk2LDEzLjA2OTEwMzI0MDk2Njc5NyAzLjg1MzMyNzcyMTM1NzM0NTYsNy42MjkwMjI1OTgyNjY2MDIgIiBpZD0ic3ZnXzEiIHN0cm9rZT0ibnVsbCIvPgogPC9nPgo8L3N2Zz4=) no-repeat 100% center'
};
this.defPanelCss = {
'position': 'absolute',
'background-color': '#fff',
'z-index': '999999999',
'padding': '1px',
'transition': 'width 0.5s',
'overflow': 'auto'
};
this.defListItemCss = {
'background-color': '#fff',
'height': '30px',
'veritical-align': 'middle',
'padding' : '3px',
'margin-top': '1px',
'cursor': 'pointer'
};
this.defListItemHoverCss = {
'background-color': '#0ebebe'
};
var w = $(this.ele).innerWidth();
var h = $(this.ele).innerHeight();
this.input = document.createElement('input');
$(this.selectorListPanel).css(this.defPanelCss);
this.input.style.width = w+'px';
this.input.style.height = h+'px';
this.input.style.padding = '3px';
$(this.input).css(this.defBoxCss);
this.ele.appendChild(this.input);
this.selectorListPanel = document.createElement('div');
$(this.selectorListPanel).css(this.defPanelCss);
this.selectorListPanel.style.position = 'fixed';
this.selectorListPanel.style.display = 'none';
this.selectorListPanel.tabIndex = '0';
this.ele.appendChild(this.selectorListPanel);
this.listItems = [];
this.index = 0;
var value = this.input.value || '';
var obj = this;
var hoverIndex = 0;
this.input.addEventListener('blur', function () {
if(value || obj.options[hoverIndex] == value || obj.tempOptions[hoverIndex] == value) {
obj.selected(hoverIndex);
if(obj.callback && obj.callback.constructor == Function) {
obj.callback(value, obj.index, obj);
obj.doFilter(value);
}
}
obj.selectorListPanel.style.display = 'none';
});
this.input.addEventListener('focus', function (e) {
obj.showPanel();
});
this.input.addEventListener('input', function () {
value = obj.input.value;
if(obj.callback && obj.callback.constructor == Function) {
obj.callback(value, -1, obj);
obj.doFilter(value);
}
});
this.setBoxCss = function (css) {
for (var p in css) {
obj.defBoxCss[p] = css[p];
}
$(this.input).css(obj.defBoxCss);
return obj;
};
this.setPanelCss = function (css) {
for (var p in css) {
obj.defPanelCss[p] = css[p];
}
$(obj.selectorListPanel).css(obj.defPanelCss);
return obj;
};
this.setItemCss = function(css) {
for (var p in css) {
obj.defListItemCss[p] = css[p];
}
obj.setOptions(obj.options);
return obj;
}
this.setItemHoverCss = function(hoverCss) {
for (var p in hoverCss) {
obj.defListItemHoverCss[p] = hoverCss[p];
}
return obj;
};
this.setOptions = function (opts, isTemp) {
if(!opts || opts.constructor != Array) {
return obj;
}
if(!isTemp) {
obj.options = opts.slice(0);
} else {
obj.tempOptions = opts.slice(0);
}
obj.selectorListPanel.innerHTML = '';
obj.listItems = [];
for(var i in opts) {
var listItem = document.createElement('div');
$(listItem).css(obj.defListItemCss);
listItem.textContent = opts[i];
listItem.addEventListener('click', function (e) {
obj.selected(hoverIndex);
obj.selectorListPanel.style.display = 'none';
});
listItem.addEventListener('mouseover', function (e) {
$(this).css(obj.defListItemHoverCss);
if(!obj.defListItemHoverCss['line-height']) {
this.style.lineHeight = listItem.clientHeight + 'px';
}
value = this.textContent;
hoverIndex = this.getAttribute('index');
});
listItem.addEventListener('mouseout', function (e) {
if(obj.index == this.getAttribute('index')) {
return;
}
$(this).css(obj.defListItemCss);
value = obj.input.value;
});
listItem.setAttribute('index', i);
obj.selectorListPanel.appendChild(listItem);
obj.listItems.push(listItem);
}
if(!isTemp && !obj.input.value && opts.length > 0) {
obj.selected(0);
}
return obj;
};
this.setCallback = function(calllback){
if(calllback && calllback.constructor == Function) {
obj.callback = calllback;
} else {
console.error('Selector ERR: callback not is Function');
}
return obj;
};
this.setFilter = function(filter, isOff) {
obj.runFilter = !isOff;
if(filter && filter) {
obj.filter = filter;
}
return obj;
}
this.getOptsFromServer = function (op, dataAdapter) {
if(!op) {
console.error('Selector ERR: invalid parameter');
return obj;
}
obj.urlOp = op;
$.ajax({
url: op.url,
type: op.method || 'GET',
dataType: 'json',
data: op.data || {},
async: false,
success: function (data) {
var arr = null;
if(dataAdapter && dataAdapter.constructor == Function) {
obj.dataAdapter = dataAdapter;
arr = obj.dataAdapter(data);
} else {
arr = data;
}
if(arr && arr.dataAdapter.constructor == Array)
{
obj.setOptions(arr);
} else {
console.error('Selector ERR: invalid data');
}
},
error: function (err) {
console.error('Selector ERR:');
console.error(err);
}
});
return obj;
};
//用以搜索
this.updatePostParams = function(data) {
obj.urlOp.data = data;
obj.getOptsFromServer(obj.urlOp, obj.dataAdapter);
}
this.selected = function(idx) {
if(idx >= 0 && idx < obj.options.length) {
$(obj.listItems[obj.index]).css(obj.defListItemCss);
$(obj.listItems[idx]).css(obj.defListItemHoverCss);
obj.input.value = value = this.options[idx];
obj.input.value = obj.listItems[idx].textContent;
obj.index = idx;
}
return obj;
};
this.getValue = function () {
return obj.input.value;
};
this.setValue = function (text) {
obj.input.value = text;
};
this.showPanel= function() {
if(obj.options.length == 0) {
return obj;
}
var w = $(obj.input).innerWidth();
var h = $(obj.input).innerHeight();
var ch = this.ele.clientHeight;
var left = $(obj.input).offset().left - document.documentElement.scrollLeft;
var top = $(obj.input).offset().top - document.documentElement.scrollTop;
var panelHeight = $(this.selectorListPanel).height();
obj.selectorListPanel.style.width = w+'px';
obj.selectorListPanel.style.maxHeight = $(window).height()/2+'px';
var panelTop = top+5+h;
obj.selectorListPanel.style.top = panelTop+'px';
obj.selectorListPanel.style.boxShadow= '1px 1px 3px rgba(1, 1, 1, 0.77)';
if(panelTop+panelHeight > $(window).height()) {
var panelTop = top-5-$(obj.selectorListPanel).height();
obj.selectorListPanel.style.top = panelTop+'px';
obj.selectorListPanel.style.boxShadow= '1px -1px 3px rgba(1, 1, 1, 0.77)';
}
obj.selectorListPanel.style.display = 'block';
return obj;
};
this.hidePanel = function() {
obj.selectorListPanel.style.display = 'none';
}
this.doFilter = function (key) {
if(obj.runFilter && obj.filter && obj.filter.constructor == Function) {
obj.setOptions(obj.options.filter(function (item) {
return obj.filter(item, key);
}), true);
obj.index = hoverIndex = 0;
obj.showPanel();
}
return obj;
}
window.addEventListener('resize', function (ev) {
if(obj.selectorListPanel.style.display == 'block') {
obj.showPanel();
}
});
window.addEventListener('scroll', function (ev) {
if(obj.selectorListPanel.style.display == 'block') {
obj.showPanel();
}
});
this.setOptions(obj.options);
}
下面是包含示例代码和说明的网页源码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<style type="text/css">
.sele {
margin-left: 400px;
width: 200px;
height: 30px;
margin-top: 100px;
}
</style>
</head>
<body>
<div style="height: 600px;background-color: #efefef; overflow: scroll;">
<div>简单易用,绑定一个div就能生成下拉列表</div>
<div>new Selector()的参数1:HTMLDivElement或div元素的id:,参数2:选项数据的数组,参数3:文本框值或选项改变时的回调函数(value, index),下面有例子</div>
<table border="1" cellpadding="0">
<title>Selector的方法介绍,除getValue()方法外的其他方法都支持链式调用Selector的自定义方法</title>
<thead>
<th>方法</th>
<th>方法作用</th>
<th>其它说明</th>
</thead>
<tbody>
<tr>
<td>setBoxCss(json)</td>
<td>修改文本框样式</td>
<td>可传入任意div支持的对象</td>
</tr>
<tr>
<td>setPanelCss(json)</td>
<td>修改下拉列表面板样式</td>
<td>可传入任意div支持的对象</td>
</tr>
<tr>
<td>setItemCss(json)</td>
<td>修改下拉列表选项正常样式</td>
<td>可传入任意div支持的对象</td>
</tr>
<tr>
<td>setItemHoverCss(json)</td>
<td>修改下拉列表选项正hover样式</td>
<td>可传入任意div支持的对象</td>
</tr>
<tr>
<td>setOptions(array,bool)</td>
<td>设置选项</td>
<td>参数2为true代表临时设置,主要是过滤器用的</td>
</tr>
<tr>
<td>setCallback(function)</td>
<td>设置文本框值改变或选项改变时的回调方法</td>
<td>回调有三个参数,对应值和索引和Selector本身引用,可在此调用它的方法</td>
</tr>
<tr>
<td>setFilter(function, bool)</td>
<td>设置选项过滤器</td>
<td>回调返回选项值,返回false移除该选项,第一个参数传null不会修改过滤器,第二个参数可为true关闭过滤器</td>
</tr>
<tr>
<td>getOptsFromServer(json, function)</td>
<td>通过url加载选项</td>
<td>json是请求选项{url,method(可选),参数(可选)}回调作为数据适配器返回url请求响应的数据,默认适配器把data作为选项数据,可以在此对数据进行处理确保返回一个数组作为选项数据</td>
</tr>
<tr>
<td>updatePostParams(json)</td>
<td>更新搜素参数,根据关键字重新搜索</td>
</tr>
<tr>
<td>doFilter(string)</td>
<td>主动过滤选项</td>
<td>string是过滤关键字,在过滤器关闭时无效</td>
</tr>
<tr>
<td>showPanel()</td>
<td>主动显示下拉面板</td>
</tr>
<tr>
<td>hidePanel()</td>
<td>主动隐藏下拉面板</td>
</tr>
<tr>
<td>getValue()</td>
<td>获取文本框的值</td>
<td>返回string不可以在其后链式调Selector其它自定义方法</td>
</tr>
<tr>
<td>setValue(string)</td>
<td>设置文本框的值</td>
<td></td>
</tr>
</tbody>
</table>
<h3>注:需依赖jquary</h3>
<h5>Selector使用例子1</h5>
<pre>
//Selector的参数1:HTMLDivElement或div元素的id:,参数2:选项数据的数组,参数3:文本框值或选项改变时的回调函数(value, index)
var st1 = new Selector(s1, ['a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7'], function (value, index, selector) {
console.log(value, index);
}).selected(3);
//重置opations
//st1.setOptions(['a','v','c']);
</pre>
<h5>Selector使用例子2</h5>
<pre>
new Selector('s2').setBoxCss({'width':'300px', 'height':'50px'}).setOptions(['1','2','3','4'])
.setItemCss({'height':'60px'}).setItemHoverCss({'background':'#0d71bb'})
.setCallback(function (value, index) {
console.log(value, index);
});
</pre>
<h5>Selector使用例子3</h5>
<pre>
new Selector('s3').getOptsFromServer({'url':'https:xxxx'}).setCallback(function (value, index) {
console.log(value, index);
});
</pre>
<h5>Selector使用例子4(搜索)</h5>
<pre>
//搜索例子
new Selector('s4').getOptsFromServer({'url':'https:xxxx'}, function (data) {
return data.list; //数据适配器对data进行处理,返回数组做为选项
}).setCallback(function (value, index, selector) { //选项发送变化
selector.updatePostParams({key:value}); //更新参数重新请求
console.log(value, index);
});
</pre>
<h5>Selector使用例子5(使用默认过滤器和自定义选项过滤器)</h5>
<pre>
new Selector('s5', ['a1', 'a2', 'a3', 'a4']).setCallback(function (v,i) {
console.log(v+','+i);
}).selected(1).setFilter(null); //打开默认选项过滤器
new Selector(s6, ['','a1', 'a2', 'a3', 'a4']).setCallback(function (v,i) {
console.log(v+','+i);
}).setFilter(function (item, key) { //选项过滤器
return (item || '').indexOf(key) >= 0;
});
</pre>
</div>
<div id='s1' class="sele"></div>
<div id='s2' class="sele"></div>
<div id='s3' class="sele"></div>
<div id='s4' class="sele"></div>
<div id='s5' class="sele"></div>
<div id='s6' class="sele"></div>
<div style="height: 1000px; width: 20px;background-color: #0d71bb"></div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
new Selector(s1, ['a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7']).setCallback(function (v,i) {
console.log(v+','+i);
}).selected(2);
new Selector('s2').setOptions(['1','2','3','4']).setCallback(function (value, index) {
console.log(value, index);
}).setBoxCss({'width':'300px', 'height':'50px', 'border-radius':'5px'}).setItemCss({'height':'60px'}).setItemHoverCss({'background':'#75b4bb'});
new Selector('s3').getOptsFromServer({url:'https:xxxx', method:'post', data:{key:''}}).setCallback(function (value, index) {
console.log(value, index);
});
//搜索例子
new Selector('s4').getOptsFromServer({'url':'https:xxxx'}, function (data) {
return data.list; //数据适配器对data进行处理,返回数组做为选项
}).setCallback(function (value, index, selector) { //选项发送变化
selector.updatePostParams({key:value}); //更新参数重新请求
console.log(value, index);
});
new Selector('s5', ['a1', 'a2', 'a3', 'a4']).setCallback(function (v,i) {
console.log(v+','+i);
}).selected(2).setFilter(null); //打开默认选项过滤器
new Selector(s6, ['a1', 'a2', 'a3', 'a4']).setCallback(function (v,i) {
console.log(v+','+i);
}).setFilter(function (item, key) { //自定义选项过滤器
return (item || '').indexOf(key) >= 0;
});
function Selector(id, options, callback) {
this.options = options || []; // 选项数据数
this.tempOptions = [];
this.callback = callback || function () {}; // 选项改变或文本框内容改变时的回调处理函数
this.urlOp = {}; // 请求,包含地址:url,请求方式:method,参数:data
this.dataAdapter = function () {}; // 数据适配器,如果返回数据不是数组需用此方法转化为数组做为选项数据
this.runFilter = false; // 文本输入时是否对选项进行过滤
this.filter = function (value, key) {
value = value || '';
key = key || '';
return value.indexOf(key) >= 0 || key.indexOf(value) >= 0;
}; // 选项过滤器,默认关闭
if(id && id.constructor == HTMLDivElement) {
this.ele = id;
} else {
this.ele = document.getElementById(id);
}
if(!this.ele || this.ele.constructor != HTMLDivElement) {
console.error('error id of div element bing on selector');
return {};
}
if(this.ele.tagName != 'DIV') {
console.error('please bind on div element');
return {};
}
this.defBoxCss = {
'padding-right':'20px',
'background':'url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjIiIGhlaWdodD0iMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8cmVjdCB4PSItMSIgeT0iLTEiIHdpZHRoPSIyNCIgaGVpZ2h0PSIyMiIgaWQ9ImNhbnZhc19iYWNrZ3JvdW5kIiBmaWxsPSJub25lIi8+CiA8L2c+CiA8Zz4KICA8cG9seWdvbiBwb2ludHM9IjEyLjcxNDYwNzY4NTgwNDM2Nyw3LjYyOTAyMjU5ODI2NjYwMiA4LjI4Mzk2NjUxMTQ4Nzk2LDEzLjA2OTEwMzI0MDk2Njc5NyAzLjg1MzMyNzcyMTM1NzM0NTYsNy42MjkwMjI1OTgyNjY2MDIgIiBpZD0ic3ZnXzEiIHN0cm9rZT0ibnVsbCIvPgogPC9nPgo8L3N2Zz4=) no-repeat 100% center'
};
this.defPanelCss = {
'position': 'absolute',
'background-color': '#fff',
'z-index': '999999999',
'padding': '1px',
'transition': 'width 0.5s',
'overflow': 'auto'
};
this.defListItemCss = {
'background-color': '#fff',
'height': '30px',
'veritical-align': 'middle',
'padding' : '3px',
'margin-top': '1px',
'cursor': 'pointer'
};
this.defListItemHoverCss = {
'background-color': '#0ebebe'
};
var w = $(this.ele).innerWidth();
var h = $(this.ele).innerHeight();
this.input = document.createElement('input');
$(this.selectorListPanel).css(this.defPanelCss);
this.input.style.width = w+'px';
this.input.style.height = h+'px';
this.input.style.padding = '3px';
$(this.input).css(this.defBoxCss);
this.ele.appendChild(this.input);
this.selectorListPanel = document.createElement('div');
$(this.selectorListPanel).css(this.defPanelCss);
this.selectorListPanel.style.position = 'fixed';
this.selectorListPanel.style.display = 'none';
this.selectorListPanel.tabIndex = '0';
this.ele.appendChild(this.selectorListPanel);
this.listItems = [];
this.index = 0;
var value = this.input.value || '';
var obj = this;
var hoverIndex = 0;
this.input.addEventListener('blur', function () {
if(value || obj.options[hoverIndex] == value || obj.tempOptions[hoverIndex] == value) {
obj.selected(hoverIndex);
if(obj.callback && obj.callback.constructor == Function) {
obj.callback(value, obj.index, obj);
obj.doFilter(value);
}
}
obj.selectorListPanel.style.display = 'none';
});
this.input.addEventListener('focus', function (e) {
obj.showPanel();
});
this.input.addEventListener('input', function () {
value = obj.input.value;
if(obj.callback && obj.callback.constructor == Function) {
obj.callback(value, -1, obj);
obj.doFilter(value);
}
});
this.setBoxCss = function (css) {
for (var p in css) {
obj.defBoxCss[p] = css[p];
}
$(this.input).css(obj.defBoxCss);
return obj;
};
this.setPanelCss = function (css) {
for (var p in css) {
obj.defPanelCss[p] = css[p];
}
$(obj.selectorListPanel).css(obj.defPanelCss);
return obj;
};
this.setItemCss = function(css) {
for (var p in css) {
obj.defListItemCss[p] = css[p];
}
obj.setOptions(obj.options);
return obj;
}
this.setItemHoverCss = function(hoverCss) {
for (var p in hoverCss) {
obj.defListItemHoverCss[p] = hoverCss[p];
}
return obj;
};
this.setOptions = function (opts, isTemp) {
if(!opts || opts.constructor != Array) {
return obj;
}
if(!isTemp) {
obj.options = opts.slice(0);
} else {
obj.tempOptions = opts.slice(0);
}
obj.selectorListPanel.innerHTML = '';
obj.listItems = [];
for(var i in opts) {
var listItem = document.createElement('div');
$(listItem).css(obj.defListItemCss);
listItem.textContent = opts[i];
listItem.addEventListener('click', function (e) {
obj.selected(hoverIndex);
obj.selectorListPanel.style.display = 'none';
});
listItem.addEventListener('mouseover', function (e) {
$(this).css(obj.defListItemHoverCss);
if(!obj.defListItemHoverCss['line-height']) {
this.style.lineHeight = listItem.clientHeight + 'px';
}
value = this.textContent;
hoverIndex = this.getAttribute('index');
});
listItem.addEventListener('mouseout', function (e) {
if(obj.index == this.getAttribute('index')) {
return;
}
$(this).css(obj.defListItemCss);
value = obj.input.value;
});
listItem.setAttribute('index', i);
obj.selectorListPanel.appendChild(listItem);
obj.listItems.push(listItem);
}
if(!isTemp && !obj.input.value && opts.length > 0) {
obj.selected(0);
}
return obj;
};
this.setCallback = function(calllback){
if(calllback && calllback.constructor == Function) {
obj.callback = calllback;
} else {
console.error('Selector ERR: callback not is Function');
}
return obj;
};
this.setFilter = function(filter, isOff) {
obj.runFilter = !isOff;
if(filter && filter) {
obj.filter = filter;
}
return obj;
}
this.getOptsFromServer = function (op, dataAdapter) {
if(!op) {
console.error('Selector ERR: invalid parameter');
return obj;
}
obj.urlOp = op;
$.ajax({
url: op.url,
type: op.method || 'GET',
dataType: 'json',
data: op.data || {},
async: false,
success: function (data) {
var arr = null;
if(dataAdapter && dataAdapter.constructor == Function) {
obj.dataAdapter = dataAdapter;
arr = obj.dataAdapter(data);
} else {
arr = data;
}
if(arr && arr.dataAdapter.constructor == Array)
{
obj.setOptions(arr);
} else {
console.error('Selector ERR: invalid data');
}
},
error: function (err) {
console.error('Selector ERR:');
console.error(err);
}
});
return obj;
};
//用以搜索
this.updatePostParams = function(data) {
obj.urlOp.data = data;
obj.getOptsFromServer(obj.urlOp, obj.dataAdapter);
}
this.selected = function(idx) {
if(idx >= 0 && idx < obj.options.length) {
$(obj.listItems[obj.index]).css(obj.defListItemCss);
$(obj.listItems[idx]).css(obj.defListItemHoverCss);
obj.input.value = value = this.options[idx];
obj.input.value = obj.listItems[idx].textContent;
obj.index = idx;
}
return obj;
};
this.getValue = function () {
return obj.input.value;
};
this.setValue = function (text) {
obj.input.value = text;
};
this.showPanel= function() {
if(obj.options.length == 0) {
return obj;
}
var w = $(obj.input).innerWidth();
var h = $(obj.input).innerHeight();
var ch = this.ele.clientHeight;
var left = $(obj.input).offset().left - document.documentElement.scrollLeft;
var top = $(obj.input).offset().top - document.documentElement.scrollTop;
var panelHeight = $(this.selectorListPanel).height();
obj.selectorListPanel.style.width = w+'px';
obj.selectorListPanel.style.maxHeight = $(window).height()/2+'px';
var panelTop = top+5+h;
obj.selectorListPanel.style.top = panelTop+'px';
obj.selectorListPanel.style.boxShadow= '1px 1px 3px rgba(1, 1, 1, 0.77)';
if(panelTop+panelHeight > $(window).height()) {
var panelTop = top-5-$(obj.selectorListPanel).height();
obj.selectorListPanel.style.top = panelTop+'px';
obj.selectorListPanel.style.boxShadow= '1px -1px 3px rgba(1, 1, 1, 0.77)';
}
obj.selectorListPanel.style.display = 'block';
return obj;
};
this.hidePanel = function() {
obj.selectorListPanel.style.display = 'none';
}
this.doFilter = function (key) {
if(obj.runFilter && obj.filter && obj.filter.constructor == Function) {
obj.setOptions(obj.options.filter(function (item) {
return obj.filter(item, key);
}), true);
obj.index = hoverIndex = 0;
obj.showPanel();
}
return obj;
}
window.addEventListener('resize', function (ev) {
if(obj.selectorListPanel.style.display == 'block') {
obj.showPanel();
}
});
window.addEventListener('scroll', function (ev) {
if(obj.selectorListPanel.style.display == 'block') {
obj.showPanel();
}
});
this.setOptions(obj.options);
}
</script>
</body>
</html>