Skip to content

Commit 3d6b861

Browse files
committed
Added multiselect to ListView (#32)
1 parent 3e9a51c commit 3d6b861

File tree

1 file changed

+62
-21
lines changed

1 file changed

+62
-21
lines changed

src/components/ListView.js

+62-21
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ const createView = props => {
3939

4040
const cols = (paneIndex) => (row, rowIndex) => {
4141
const col = row.columns[paneIndex] || {};
42-
const selected = props.selectedIndex === rowIndex;
4342
const colIcon = col.icon ? h(Icon, col.icon) : null;
4443
const children = [h('span', {}, [typeof col === 'object' ? col.label : col])];
44+
const selected = props.multiselect
45+
? props.selectedIndex.indexOf(rowIndex) !== -1
46+
: props.selectedIndex === rowIndex;
4547

4648
if (colIcon) {
4749
children.unshift(colIcon);
@@ -51,11 +53,11 @@ const createView = props => {
5153
key: row.key,
5254
'data-has-icon': col.icon ? true : undefined,
5355
class: 'osjs-gui-list-view-cell' + (selected ? ' osjs__active' : ''),
54-
ontouchstart: (ev) => tapper(ev, () => props.onactivate({data: row.data, index: rowIndex, ev})),
55-
ondblclick: (ev) => props.onactivate({data: row.data, index: rowIndex, ev}),
56-
onclick: (ev) => props.onselect({data: row.data, index: rowIndex, ev}),
57-
oncontextmenu: (ev) => props.oncontextmenu({data: row.data, index: rowIndex, ev}),
58-
oncreate: (el) => props.oncreate({data: row.data, index: rowIndex, el})
56+
ontouchstart: (ev) => tapper(ev, () => props.onactivate({index: rowIndex, ev})),
57+
ondblclick: (ev) => props.onactivate({index: rowIndex, ev}),
58+
onclick: (ev) => props.onselect({index: rowIndex, ev}),
59+
oncontextmenu: (ev) => props.oncontextmenu({index: rowIndex, ev}),
60+
oncreate: (el) => props.oncreate({index: rowIndex, el})
5961
}, children);
6062
};
6163

@@ -79,7 +81,11 @@ const createView = props => {
7981
class: 'osjs-gui-list-view-wrapper',
8082
oncreate: el => (el.scrollTop = props.scrollTop),
8183
onupdate: el => {
82-
if (props.selectedIndex < 0) {
84+
const notSelected = props.multiselect
85+
? props.selectedIndex.length === 0
86+
: props.selectedIndex < 0;
87+
88+
if (notSelected) {
8389
el.scrollTop = props.scrollTop;
8490
}
8591
}
@@ -92,33 +98,68 @@ export const ListView = props => h(Element, Object.assign({
9298

9399
export const listView = ({
94100
component: (state, actions) => {
101+
102+
const createSelection = index => state.selectedIndex.indexOf(index) === -1
103+
? [...state.selectedIndex, index]
104+
: state.selectedIndex;
105+
106+
const getSelection = (index, ev) => {
107+
const selected = state.multiselect
108+
? (ev.shiftKey ? createSelection(index) : [index])
109+
: index;
110+
111+
const data = state.multiselect
112+
? selected.map(i => state.rows[i].data)
113+
: state.rows[selected].data;
114+
115+
return {selected, data};
116+
};
117+
118+
const clearCurrentSelection = (index, ev) => {
119+
const selected = state.multiselect
120+
? []
121+
: -1;
122+
123+
const data = state.multiselect
124+
? state.selectedIndex.map(i => state.rows[i].data)
125+
: state.rows[index].data;
126+
127+
return {selected, data};
128+
};
129+
95130
const newProps = Object.assign({
131+
multiselect: false,
96132
zebra: true,
97133
columns: [],
98134
rows: [],
99-
onselect: ({data, index, ev}) => {
100-
actions.select({data, index, ev});
101-
actions.setSelectedIndex(index);
135+
onselect: ({index, ev}) => {
136+
const {selected, data} = getSelection(index, ev);
137+
actions.select({data, index, ev, selected});
138+
actions.setSelectedIndex(selected);
102139
},
103-
onactivate: ({data, index, ev}) => {
104-
actions.activate({data, index, ev});
105-
actions.setSelectedIndex(-1);
140+
onactivate: ({index, ev}) => {
141+
const {selected, data} = clearCurrentSelection(index, ev);
142+
actions.activate({data, index, ev, selected});
143+
actions.setSelectedIndex(selected);
106144
},
107-
oncontextmenu: ({data, index, ev}) => {
145+
oncontextmenu: ({index, ev}) => {
146+
const {selected, data} = getSelection(index, ev);
147+
108148
actions.select({data, index, ev});
109-
actions.contextmenu({data, index, ev});
110-
actions.setSelectedIndex(index);
149+
actions.contextmenu({data, index, ev, selected});
150+
actions.setSelectedIndex(selected);
111151
},
112-
oncreate: (args) => {
113-
actions.created(args);
152+
oncreate: ({index, el}) => {
153+
const data = state.rows[index].data;
154+
actions.created({index, el, data});
114155
}
115156
}, state);
116157

117158
return (props = {}) => ListView(Object.assign(newProps, props));
118159
},
119160

120161
state: state => Object.assign({
121-
selectedIndex: -1,
162+
selectedIndex: state.multiselect ? [] : -1,
122163
scrollTop: 0
123164
}, state),
124165

@@ -129,7 +170,7 @@ export const listView = ({
129170
created: () => () => ({}),
130171
setRows: rows => ({rows}),
131172
setColumns: columns => ({columns}),
132-
setScrollTop: scrollTop => state => ({scrollTop}),
133-
setSelectedIndex: selectedIndex => state => ({selectedIndex})
173+
setScrollTop: scrollTop => ({scrollTop}),
174+
setSelectedIndex: selectedIndex => ({selectedIndex})
134175
}, actions || {})
135176
});

0 commit comments

Comments
 (0)