131 lines
4.3 KiB
JavaScript
131 lines
4.3 KiB
JavaScript
// Common selection mixin
|
|
var ListWithSelection = module.exports = {
|
|
// requires to override methods: this.deleteSelected(), this.getPageSize(), this.getItemOffset(index), this.getTotalItems()
|
|
getInitialState: function()
|
|
{
|
|
return {
|
|
selected: {}
|
|
};
|
|
},
|
|
isSelected: function(i)
|
|
{
|
|
return this.state.selected[i] || this.state.selected.begin !== undefined &&
|
|
this.state.selected.begin <= i && this.state.selected.end >= i;
|
|
},
|
|
onListKeyDown: function(ev)
|
|
{
|
|
if (!this.getTotalItems())
|
|
return;
|
|
if (ev.keyCode == 46) // delete
|
|
{
|
|
this.deleteSelected();
|
|
this.setState({ selected: {} });
|
|
ev.stopPropagation();
|
|
}
|
|
else if (ev.keyCode == 38 || ev.keyCode == 40 || ev.keyCode == 33 || ev.keyCode == 34) // up, down, pgup, pgdown
|
|
{
|
|
var sel = this.curSel, dir;
|
|
if (ev.keyCode < 35)
|
|
dir = (ev.keyCode == 34 ? 1 : -1) * this.getPageSize();
|
|
else
|
|
dir = (ev.keyCode == 40 ? 1 : -1);
|
|
if (sel !== null)
|
|
{
|
|
var nsel = sel+dir, n = this.getTotalItems();
|
|
if (nsel < 0)
|
|
nsel = 0;
|
|
if (nsel >= n)
|
|
nsel = n-1;
|
|
if (sel != nsel)
|
|
{
|
|
if (ev.shiftKey)
|
|
this.selectTo(nsel);
|
|
else
|
|
this.selectOne(nsel);
|
|
var pos = this.getItemOffset(nsel);
|
|
if (pos[0] + pos[1] > this.refs.scroll.scrollTop + this.refs.scroll.offsetHeight)
|
|
this.refs.scroll.scrollTop = pos[0] + pos[1] - this.refs.scroll.offsetHeight;
|
|
else if (pos[0] < this.refs.scroll.scrollTop + this.getScrollPaddingTop())
|
|
this.refs.scroll.scrollTop = pos[0] - this.getScrollPaddingTop();
|
|
ev.stopPropagation();
|
|
}
|
|
ev.preventDefault(); // prevent scroll
|
|
}
|
|
}
|
|
else if (ev.keyCode == 36) // home
|
|
{
|
|
if (ev.shiftKey)
|
|
{
|
|
this.selectTo(0);
|
|
this.refs.scroll.scrollTop = pos[0] - this.getScrollPaddingTop();
|
|
}
|
|
else
|
|
this.selectOne(0);
|
|
}
|
|
else if (ev.keyCode == 35) // end
|
|
{
|
|
var nsel = this.getTotalItems()-1;
|
|
if (ev.shiftKey)
|
|
{
|
|
this.selectTo(nsel);
|
|
var pos = this.getItemOffset(nsel);
|
|
this.refs.scroll.scrollTop = pos[0] + pos[1] - this.refs.scroll.offsetHeight;
|
|
}
|
|
else
|
|
this.selectOne(nsel);
|
|
}
|
|
},
|
|
selectTo: function(ns)
|
|
{
|
|
if (this.lastSel === undefined)
|
|
return this.selectOne(ns);
|
|
var sel = {};
|
|
var n = this.getTotalItems();
|
|
if (this.lastSel >= n)
|
|
this.lastSel = n-1;
|
|
if (ns < this.lastSel)
|
|
sel = { begin: ns, end: this.lastSel };
|
|
else if (ns > this.lastSel)
|
|
sel = { begin: this.lastSel, end: ns };
|
|
else
|
|
sel[ns] = true;
|
|
this.setState({ selected: sel });
|
|
this.curSel = ns;
|
|
if (this.onSelectCurrent)
|
|
this.onSelectCurrent(ns);
|
|
},
|
|
selectOne: function(ns)
|
|
{
|
|
var sel = {};
|
|
sel[ns] = true;
|
|
this.setState({ selected: sel });
|
|
this.lastSel = ns;
|
|
this.curSel = ns;
|
|
if (this.onSelectCurrent)
|
|
this.onSelectCurrent(ns);
|
|
},
|
|
onListItemClick: function(ev)
|
|
{
|
|
var t = ev.target;
|
|
while (t && !t.getAttribute('data-i'))
|
|
t = t.parentNode;
|
|
if (t)
|
|
{
|
|
var ns = parseInt(t.getAttribute('data-i'));
|
|
if (ev.shiftKey)
|
|
this.selectTo(ns);
|
|
else if (ev.ctrlKey)
|
|
{
|
|
this.state.selected[ns] = true;
|
|
this.curSel = ns;
|
|
if (this.onSelectCurrent)
|
|
this.onSelectCurrent(ns);
|
|
this.lastSel = this.lastSel === undefined ? ns : this.lastSel;
|
|
this.setState({ selected: this.state.selected });
|
|
}
|
|
else
|
|
this.selectOne(ns);
|
|
}
|
|
}
|
|
};
|