Skip to content

Commit 5065a59

Browse files
authored
Merge pull request #94 from martinRenou/add_searching
Add search plugin
2 parents e285b95 + 925a273 commit 5065a59

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

examples/searching.ipynb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"metadata": {
7+
"scrolled": true
8+
},
9+
"outputs": [],
10+
"source": [
11+
"import numpy as np\n",
12+
"import pandas as pd\n",
13+
"from ipysheet import from_dataframe\n",
14+
"from ipywidgets import Text, VBox, link\n",
15+
"\n",
16+
"df = pd.DataFrame({'A': 1.,\n",
17+
" 'B': pd.Timestamp('20130102'),\n",
18+
" 'C': pd.Series(1, index=list(range(4)), dtype='float32'),\n",
19+
" 'D': np.array([False, True, False, False], dtype='bool'),\n",
20+
" 'E': pd.Categorical([\"test\", \"train\", \"test\", \"train\"]),\n",
21+
" 'F': 'foo'})\n",
22+
"\n",
23+
"df.loc[[0, 2], ['B']] = np.nan\n",
24+
"\n",
25+
"\n",
26+
"s = from_dataframe(df)\n",
27+
"\n",
28+
"search_box = Text(description='Search:')\n",
29+
"link((search_box, 'value'), (s, 'search_token'))\n",
30+
"\n",
31+
"VBox((search_box, s))"
32+
]
33+
}
34+
],
35+
"metadata": {
36+
"kernelspec": {
37+
"display_name": "Python 3",
38+
"language": "python",
39+
"name": "python3"
40+
},
41+
"language_info": {
42+
"codemirror_mode": {
43+
"name": "ipython",
44+
"version": 3
45+
},
46+
"file_extension": ".py",
47+
"mimetype": "text/x-python",
48+
"name": "python",
49+
"nbconvert_exporter": "python",
50+
"pygments_lexer": "ipython3",
51+
"version": "3.7.1"
52+
}
53+
},
54+
"nbformat": 4,
55+
"nbformat_minor": 2
56+
}

ipysheet/sheet.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Cell(widgets.Widget):
1515
_model_module = Unicode('ipysheet').tag(sync=True)
1616
# _view_module_version = Unicode('^0.1.0').tag(sync=True)
1717
_model_module_version = Unicode(semver_range_frontend).tag(sync=True)
18+
1819
# value = Union([Bool(), Unicode(), Float(), Int()], allow_none=True, default_value=None).tag(sync=True)
1920
value = Any().tag(sync=True, **create_value_serializer('value'))
2021
row_start = CInt(3).tag(sync=True)
@@ -85,6 +86,7 @@ class Sheet(widgets.DOMWidget):
8586
_model_module = Unicode('ipysheet').tag(sync=True)
8687
_view_module_version = Unicode(semver_range_frontend).tag(sync=True)
8788
_model_module_version = Unicode(semver_range_frontend).tag(sync=True)
89+
8890
rows = CInt(3).tag(sync=True)
8991
columns = CInt(4).tag(sync=True)
9092
cells = Tuple().tag(sync=True, **widgets.widget_serialization)
@@ -95,6 +97,7 @@ class Sheet(widgets.DOMWidget):
9597
column_width = Union([CInt(), List(CInt())], default_value=None, allow_none=True).tag(sync=True)
9698
column_resizing = Bool(True).tag(sync=True)
9799
row_resizing = Bool(True).tag(sync=True)
100+
search_token = Unicode('').tag(sync=True)
98101

99102
def __getitem__(self, item):
100103
'''Gets a previously created cell at row and column

js/src/sheet.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ let SheetModel = widgets.DOMWidgetModel.extend({
6161
stretch_headers: 'all',
6262
column_width: null,
6363
column_resizing: true,
64-
row_resizing: true
64+
row_resizing: true,
65+
search_token: ''
6566
});
6667
},
6768
initialize : function () {
@@ -274,6 +275,8 @@ let SheetView = widgets.DOMWidgetView.extend({
274275
this.model.on('change:column_headers change:row_headers', this._update_hot_settings, this);
275276
this.model.on('change:stretch_headers change:column_width', this._update_hot_settings, this);
276277
this.model.on('change:column_resizing change:row_resizing', this._update_hot_settings, this);
278+
this.model.on('change:search_token', this._search, this);
279+
this._search()
277280
});
278281
},
279282
processPhosphorMessage: function(msg) {
@@ -333,6 +336,7 @@ let SheetView = widgets.DOMWidgetView.extend({
333336
data: this._get_cell_data(),
334337
rowHeaders: true,
335338
colHeaders: true,
339+
search: true,
336340
cells: (...args) => this._cell(...args),
337341
afterChange: (changes, source) => { this._on_change(changes, source); },
338342
afterRemoveCol: (changes, source) => { this._on_change_grid(changes, source); },
@@ -352,6 +356,17 @@ let SheetView = widgets.DOMWidgetView.extend({
352356
manualRowResize: this.model.get('row_resizing')
353357
};
354358
},
359+
_search: function(render=true, ignore_empty_string=false) {
360+
let token = this.model.get('search_token');
361+
if (ignore_empty_string && token == '') {
362+
return;
363+
}
364+
365+
let res = this.hot.getPlugin('search').query(token);
366+
if (render) {
367+
this.hot.render();
368+
}
369+
},
355370
_get_cell_data: function() {
356371
return extract2d(this.model.data, 'value');
357372
},
@@ -434,6 +449,7 @@ let SheetView = widgets.DOMWidgetView.extend({
434449
colHeaders: this.model.get('column_headers'),
435450
rowHeaders: this.model.get('row_headers')
436451
});
452+
this._search(false, true);
437453
this.hot.render();
438454
resolve()
439455
})

js/src/test/test_sheet.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,32 @@ describe('sheet', function() {
230230
expect(data[0][2].options.style.backgrouncColor, 'effective backgrouncColor should be blue').to.equal('orange');
231231
expect(range.get('style').color, 'but the original should not be changed').to.equal('red');
232232
})
233+
it('should search at table creation', async function() {
234+
var cell = await make_cell.apply(this, [{value: [['Hello']]}]);
235+
this.sheet.set('search_token', 'Hell');
236+
var view = await make_view.call(this)
237+
await view._table_constructed;
238+
239+
expect(view.el.querySelector('td[class*="htSearchResult"]')).to.not.equal(null);
240+
})
241+
it('should search', async function() {
242+
var cell = await make_cell.apply(this, [{value: [['Hello']]}]);
243+
var view = await make_view.call(this)
244+
await view._table_constructed;
245+
246+
expect(view.el.querySelector('td[class*="htSearchResult"]')).to.equal(null);
247+
this.sheet.set('search_token', 'Hell');
248+
expect(view.el.querySelector('td[class*="htSearchResult"]')).to.not.equal(null);
249+
})
250+
it('should search after change', async function() {
251+
var cell = await make_cell.apply(this, [{value: [['Yop']]}]);
252+
var view = await make_view.call(this)
253+
await view._table_constructed;
254+
255+
this.sheet.set('search_token', 'Hell');
256+
expect(view.el.querySelector('td[class*="htSearchResult"]')).to.equal(null);
257+
cell.set('value', [['Hello']]);
258+
await view._last_data_set;
259+
expect(view.el.querySelector('td[class*="htSearchResult"]')).to.not.equal(null);
260+
})
233261
})

0 commit comments

Comments
 (0)