-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathsg-datalist.js
127 lines (108 loc) · 3.25 KB
/
sg-datalist.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
modules.define(
'sg-datalist',
['i-bem-dom', 'menu', 'BEMHTML'],
function(provide, BemDom, Menu, BEMHTML) {
provide(BemDom.decl(this.name, {
onSetMod : {
'js' : {
'inited' : function() {
this._dataprovider = null;
this._events(this._menu = this.findMixedBlock(Menu))
.on({
'item-hover' : this._onMenuItemHover,
'item-click' : this._onMenuItemClick
}, this);
}
},
'focused' : function(modName, modVal) {
this._menu.setMod(modName, modVal);
}
},
getDataProvider : function() {
if(this._dataprovider === null) {
throw new Error('dataprovider was not set');
}
return this._dataprovider;
},
setDataProvider : function(dataprovider) {
this._setDataProvider(dataprovider);
return this;
},
_setDataProvider : function(dataprovider) {
if(this._dataprovider !== null) {
throw new Error('dataprovider can\'t be set twice');
}
this._dataprovider = dataprovider.on({
'data' : this._onProviderGotData,
'error' : this._onProviderGotError
}, this);
},
requestData : function(params) {
this.getDataProvider().get(params).done();
return this;
},
// TODO: move to menu
hoverNextItem : function(dir) {
var items = this._menu.getItems(),
len = items.length;
if(!len) return;
var hoveredIdx = items.indexOf(this._menu._hoveredItem), // FIXME: `this._menu._hoveredItem`
nextIdx = hoveredIdx,
i = 0;
do {
nextIdx += dir;
nextIdx = nextIdx < 0? len - 1 : nextIdx >= len? 0 : nextIdx;
if(++i === len + 1) {
return; // if we have no next item to hover
}
} while(items[nextIdx].hasMod('disabled'));
items[nextIdx].setMod('hovered');
},
/**
* @param {Array} items
* @returns {String}
*/
buildItems : function(items) {
return BEMHTML.apply(this._buildItemsBemjson(items));
},
/**
* @param {Array} items
* @return {Array}
* @protected
*/
_buildItemsBemjson : function(items) {
var mods = this._menu.getMods();
return items.map(function(item) {
return {
block : 'menu-item',
mods : {
theme : mods.theme,
disabled : mods.disabled
},
val : item.val,
content : item.text
};
});
},
_updateMenu : function(items) {
this._menu.setContent(items.length? this.buildItems(items) : '');
},
_onMenuItemHover : function(e, data) {
this._emit('item-hover', data);
},
_onMenuItemClick : function(e, data) {
this._emit('item-click', data);
},
_onProviderGotData : function(e, data) {
this
._emit('items', data)
._updateMenu(data.result);
},
_onProviderGotError : function(e, data) {
// TODO: _onProviderGotError
this._emit('error', data);
}
}, {
lazyInit : true
}));
});