Skip to content

Commit 414c25a

Browse files
committed
autocomplete增加本地数据支持
1 parent c267d95 commit 414c25a

File tree

6 files changed

+116
-59
lines changed

6 files changed

+116
-59
lines changed

autocomplete/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
.ac-list-container { z-index: 10; display: none; position: absolute; width: 300px; margin-top: 10px; background-color: #fff; border: 1px solid #eee; border-radius: 0 0 5px 5px; box-shadow: 3px 3px 3px #ccc; }
1616
.ac-item a { display: block; padding: 0 40px 0 10px; line-height: 36px; text-align: left; }
1717
.ac-item a:hover, .ac-selected { background-color: #ddd; }
18+
.ac-empty { padding: 30px 0; text-align: center; color: #ccc; }
1819

1920
.sub-title { display: block; margin-top: 30px; font-size: 20px; }
2021
</style>

autocomplete/js/ajax.js

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
var emptyFn = function(){};
2+
13
function ajax(options) {
24

35
options = options || {};

autocomplete/js/autocomplete.js

+54-14
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ AutoComplete.prototype = {
7373
var instance = this,
7474
options = this.options,
7575
value = input.value,
76-
url = options.url.replace('{0}', value);
76+
url ;
7777

7878
if(this.timerID)
7979
clearTimeout(this.timerID);
@@ -84,29 +84,28 @@ AutoComplete.prototype = {
8484
return;
8585
}
8686

87+
// 如果是本地数据直接用函数过滤
88+
if(utils.isArray(options.data)){
89+
var filterData = options.filter(options.data, value);
90+
this.render(filterData);
91+
return;
92+
}
93+
94+
url = options.data.replace('{0}', value);
95+
8796
// 使用定时器来减少服务器压力
8897
this.timerID = setTimeout(function(){
8998
ajax({
9099
type: 'get',
91100
url: url,
92101
done: function(text){
93102
try{
94-
var data = instance.data = options.formatData(JSON.parse(text)),
95-
listItemsHtml = data.map(function(item){
96-
return options.buildItem(item);
97-
}).join('');
98-
99-
instance.list.innerHTML = listItemsHtml;
100-
101-
slice.call(instance.list.childNodes).forEach(function(item, i){
102-
item.className = [options.itemClass, (i % 2 === 0 ? options.oddClass : options.evenClass)].join(' ');
103-
item.setAttribute('data-index', i);
104-
});
103+
var data = instance.data = options.formatData(JSON.parse(text));
104+
instance.render(data);
105105
}catch(e){
106106
instance.list.innerHTML = instance.emptyTemplate;
107+
instance.listContainer.style.display = 'block';
107108
}
108-
109-
instance.listContainer.style.display = 'block';
110109
},
111110
fail: function(){
112111
instance.list.innerHTML = instance.emptyTemplate;
@@ -119,15 +118,18 @@ AutoComplete.prototype = {
119118
var options = this.options,
120119
selectedItem = event.target.classList.contains(options.itemClass) ? event.target : event.target.parentNode;
121120

121+
// 找到 有item标识的节点
122122
if(!selectedItem.classList.contains(options.itemClass))
123123
event.stopPropagation();
124124

125+
// 找到数据并转换数据
125126
var selectedData = this.data[selectedItem.getAttribute('data-index')],
126127
inputValue = options.formatSelectedData(selectedData); // 格式化选中的值
127128

128129
this.input.value = inputValue;
129130
this.list.style.visibility = 'hidden';
130131

132+
// 去除之前选中节点的选中class,给现在选中的节点加class
131133
slice.call(this.list.childNodes).forEach(function(item){
132134
item.classList.remove(options.selectedClass);
133135
});
@@ -136,6 +138,28 @@ AutoComplete.prototype = {
136138
selectedItem.classList.add(options.selectedClass);
137139
this.trigger('selected', selectedData);
138140

141+
},
142+
render: function(data){
143+
var options = this.options,
144+
list = this.list;
145+
146+
if(data.length > 0){
147+
var listItemsHtml = data.map(function(item){
148+
return options.buildItem(item);
149+
}).join('');
150+
151+
list.innerHTML = listItemsHtml;
152+
153+
// 给数据列表加标识,加样式
154+
slice.call(list.childNodes).forEach(function(item, i){
155+
item.className = [options.itemClass, (i % 2 === 0 ? options.oddClass : options.evenClass)].join(' ');
156+
item.setAttribute('data-index', i);
157+
});
158+
}else{
159+
list.innerHTML = this.emptyTemplate;
160+
}
161+
162+
this.listContainer.style.display = 'block';
139163
}
140164
}
141165

@@ -166,6 +190,22 @@ AutoComplete.defaults = {
166190
formatSelectedData: function(origialData){
167191
return origialData;
168192
},
193+
filter: function(data, value){
194+
var filterData = [],
195+
i = 0,
196+
l = data.length,
197+
item;
198+
199+
for(; i<l; i++){
200+
item = data[i];
201+
202+
if(new RegExp(value).test(item, 'gi'))
203+
filterData.push(item);
204+
}
205+
206+
return filterData;
207+
208+
}, // 过滤
169209
created: emptyFn, // 控件创建后触发
170210
selected: emptyFn // 选择后触发
171211
};
+12-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
var AutoComplete = require('./autocomplete');
1+
var ajax = require('./ajax'),
2+
AutoComplete = require('./autocomplete');
23

3-
new AutoComplete({
4-
el : '#keyword',
5-
url : 'data/data.json?keyword={0}'
4+
ajax.get({
5+
url: './data/data.json',
6+
done: function(jsonText){
7+
var data = JSON.parse(jsonText);
8+
9+
new AutoComplete({
10+
el : '#keyword',
11+
data : data
12+
});
13+
}
614
});

autocomplete/js/utils.js

+46-40
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,54 @@
1-
var _extend = (function() {
2-
var toString = Object.prototype.toString,
3-
slice = [].slice,
4-
isType = function(type, input){
5-
6-
if(input)
7-
return toString.call(input).slice(8, -1).toLowerCase() === type;
8-
else
9-
return function(input){
10-
return isType(type, input);
11-
};
12-
},
13-
isObject = isType('object');
14-
15-
return function(obj1, obj2){
16-
17-
if(arguments.length === 2){
18-
for(var key in obj2){
19-
var newValue = obj2[key];
20-
21-
if(newValue != null){
22-
if(isObject(newValue)){
23-
24-
if(!obj1.hasOwnProperty(key))
25-
obj1[key] = {};
26-
27-
_extend(obj1[key], newValue);
28-
}
29-
else{
30-
obj1[key] = newValue;
31-
}
1+
var toString = Object.prototype.toString,
2+
slice = Array.prototype.slice,
3+
isType = function(type, input){
4+
5+
if(input){
6+
7+
if(type === 'object' && input === null)
8+
return false;
9+
10+
return toString.call(input).slice(8, -1).toLowerCase() === type;
11+
}
12+
else
13+
return function(input){
14+
return isType(type, input);
15+
};
16+
},
17+
isObject = isType('object'),
18+
isArray = Array.isArray ? Array.isArray : isType('array');
19+
20+
function _extend(obj1, obj2){
21+
22+
if(arguments.length === 2){
23+
for(var key in obj2){
24+
var newValue = obj2[key];
25+
26+
if(newValue != null){
27+
if(isObject(newValue)){
28+
29+
if(!obj1.hasOwnProperty(key))
30+
obj1[key] = {};
31+
32+
_extend(obj1[key], newValue);
33+
}
34+
else{
35+
obj1[key] = newValue;
3236
}
3337
}
34-
}else if(arguments.length > 2){
35-
var objList = slice.call(arguments, 1);
38+
}
39+
}else if(arguments.length > 2){
40+
var objList = slice.call(arguments, 1);
3641

37-
for(var i=0, l=objList.length; i<l; i++){
38-
_extend(obj1, objList[i]);
39-
}
42+
for(var i=0, l=objList.length; i<l; i++){
43+
_extend(obj1, objList[i]);
4044
}
45+
}
4146

42-
return obj1;
43-
};
44-
})();
47+
return obj1;
48+
}
4549

4650
module.exports = {
47-
extend: _extend
51+
extend: _extend,
52+
isObject: isObject,
53+
isArray: isArray
4854
};

package/autocompleteExample.package.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)