Skip to content

Commit b930715

Browse files
author
Tim Shawver
committed
Adding a 'change_selection' method which allows changed the selected row (or rows) in the grid.
1 parent 1dc1f1d commit b930715

3 files changed

Lines changed: 87 additions & 21 deletions

File tree

js/src/qgrid.widget.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class QgridView extends widgets.DOMWidgetView {
215215
this.sort_in_progress = false;
216216
this.sort_indicator = null;
217217
this.resizing_column = false;
218+
this.ignore_selection_changed = false;
218219

219220
var number_type_info = {
220221
filter: slider_filter.SliderFilter,
@@ -342,6 +343,10 @@ class QgridView extends widgets.DOMWidgetView {
342343
delete slick_column.width;
343344
}
344345

346+
if (cur_column.maxWidth == null){
347+
delete slick_column.maxWidth;
348+
}
349+
345350
// don't allow editing index columns
346351
if (cur_column.is_index) {
347352
slick_column.editor = editors.IndexEditor;
@@ -522,8 +527,10 @@ class QgridView extends widgets.DOMWidgetView {
522527
});
523528

524529
this.slick_grid.onSelectedRowsChanged.subscribe((e, args) => {
525-
var msg = {'rows': args.rows, 'type': 'change_selection'};
526-
this.send(msg);
530+
if (!this.ignore_selection_changed) {
531+
var msg = {'rows': args.rows, 'type': 'change_selection'};
532+
this.send(msg);
533+
}
527534
});
528535

529536
setTimeout(() => {
@@ -739,6 +746,13 @@ class QgridView extends widgets.DOMWidgetView {
739746
} else {
740747
this.slick_grid.setOptions({'editable': false});
741748
}
749+
} else if (msg.type == 'change_selection') {
750+
this.ignore_selection_changed = true;
751+
this.slick_grid.setSelectedRows(msg.rows);
752+
if (msg.rows && msg.rows.length > 0) {
753+
this.slick_grid.scrollRowIntoView(msg.rows[0]);
754+
}
755+
this.ignore_selection_changed = false;
742756
} else if (msg.col_info) {
743757
var filter = this.filters[msg.col_info.name];
744758
filter.handle_msg(msg);

qgrid/grid.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,19 +1396,7 @@ def _handle_qgrid_msg_helper(self, content):
13961396
})
13971397
return
13981398
elif content['type'] == 'change_selection':
1399-
old_selection = self._selected_rows
1400-
self._selected_rows = content['rows']
1401-
1402-
# if the selection didn't change, just return without firing
1403-
# the event
1404-
if old_selection == self._selected_rows:
1405-
return
1406-
1407-
self._notify_listeners({
1408-
'name': 'selection_changed',
1409-
'old': old_selection,
1410-
'new': self._selected_rows
1411-
})
1399+
self._change_selection(content['rows'], 'gui')
14121400
elif content['type'] == 'change_viewport':
14131401
old_viewport_range = self._viewport_range
14141402
self._viewport_range = (content['top'], content['bottom'])
@@ -1699,6 +1687,47 @@ def _remove_rows(self, rows=None):
16991687
self._update_table(triggered_by='remove_row')
17001688
return selected_names
17011689

1690+
def change_selection(self, rows=[]):
1691+
"""
1692+
Select a row (or rows) in the UI. The indices of the
1693+
rows to select are provided via the optional ``rows`` argument.
1694+
1695+
Parameters
1696+
----------
1697+
rows : list (default: [])
1698+
A list of indices of the rows to select. For a multi-indexed
1699+
DataFrame, each index in the list should be a tuple, with each
1700+
value in each tuple corresponding to a level of the MultiIndex.
1701+
The default value of ``[]`` results in the no rows being
1702+
selected (i.e. it clears the selection).
1703+
"""
1704+
new_selection = \
1705+
list(map(lambda x: self._df.index.get_loc(x), rows))
1706+
1707+
self._change_selection(new_selection, 'api', send_msg_to_js=True)
1708+
1709+
def _change_selection(self, rows, source, send_msg_to_js=False):
1710+
old_selection = self._selected_rows
1711+
self._selected_rows = rows
1712+
1713+
# if the selection didn't change, just return without firing
1714+
# the event
1715+
if old_selection == self._selected_rows:
1716+
return
1717+
1718+
if send_msg_to_js:
1719+
data_to_send = {
1720+
'type': 'change_selection',
1721+
'rows': rows
1722+
}
1723+
self.send(data_to_send)
1724+
1725+
self._notify_listeners({
1726+
'name': 'selection_changed',
1727+
'old': old_selection,
1728+
'new': self._selected_rows,
1729+
'source': source
1730+
})
17021731

17031732
# Alias for legacy support, since we changed the capitalization
17041733
QGridWidget = QgridWidget

qgrid/tests/test_grid.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ def create_df():
2121
})
2222

2323

24-
def create_large_df():
25-
large_df = pd.DataFrame(np.random.randn(10000, 4), columns=list('ABCD'))
24+
def create_large_df(size=10000):
25+
large_df = pd.DataFrame(np.random.randn(size, 4), columns=list('ABCD'))
2626
large_df['B (as str)'] = large_df['B'].map(lambda x: str(x))
2727
return large_df
2828

@@ -179,7 +179,8 @@ def test_remove_row_button():
179179
{
180180
'name': 'selection_changed',
181181
'old': [],
182-
'new': selected_rows
182+
'new': selected_rows,
183+
'source': 'gui'
183184
},
184185
{
185186
'name': 'row_removed',
@@ -679,29 +680,51 @@ def test_change_filter_viewport():
679680

680681

681682
def test_change_selection():
682-
widget = QgridWidget(df=create_df())
683+
widget = QgridWidget(df=create_large_df(size=10))
683684
event_history = init_event_history('selection_changed', widget=widget)
684685

685686
widget._handle_qgrid_msg_helper({
686687
'type': 'change_selection',
687688
'rows': [5]
688689
})
690+
assert widget._selected_rows == [5]
689691

690692
widget._handle_qgrid_msg_helper({
691693
'type': 'change_selection',
692694
'rows': [7, 8]
693695
})
696+
assert widget._selected_rows == [7, 8]
697+
698+
widget.change_selection([3, 5, 6])
699+
assert widget._selected_rows == [3, 5, 6]
700+
701+
widget.change_selection()
702+
assert widget._selected_rows == []
694703

695704
assert event_history == [
696705
{
697706
'name': 'selection_changed',
698707
'old': [],
699-
'new': [5]
708+
'new': [5],
709+
'source': 'gui'
700710
},
701711
{
702712
'name': 'selection_changed',
703713
'old': [5],
704-
'new': [7, 8]
714+
'new': [7, 8],
715+
'source': 'gui'
716+
},
717+
{
718+
'name': 'selection_changed',
719+
'old': [7, 8],
720+
'new': [3, 5, 6],
721+
'source': 'api'
722+
},
723+
{
724+
'name': 'selection_changed',
725+
'old': [3, 5, 6],
726+
'new': [],
727+
'source': 'api'
705728
},
706729
]
707730

0 commit comments

Comments
 (0)