Skip to content

Commit f6fbb8a

Browse files
committed
Compute FileUpload value on the frontend
1 parent 97cd0f1 commit f6fbb8a

File tree

3 files changed

+12
-48
lines changed

3 files changed

+12
-48
lines changed

ipywidgets/widgets/widget_upload.py

+2-25
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,7 @@
1515
from .widget_core import CoreWidget
1616
from .widget_button import ButtonStyle
1717
from .widget import register, widget_serialization
18-
from .trait_types import bytes_serialization, InstanceDict
19-
20-
def content_from_json(value, widget):
21-
"""
22-
deserialize file content
23-
"""
24-
from_json = bytes_serialization['from_json']
25-
output = [from_json(e, None) for e in value]
26-
return output
18+
from .trait_types import InstanceDict
2719

2820

2921
@register
@@ -33,11 +25,6 @@ class FileUpload(DescriptionWidget, ValueWidget, CoreWidget):
3325
"""
3426
_model_name = Unicode('FileUploadModel').tag(sync=True)
3527
_view_name = Unicode('FileUploadView').tag(sync=True)
36-
_counter = Int(read_only=True).tag(sync=True)
37-
_metadata = List(Dict(), read_only=True, help='List of file metadata').tag(sync=True)
38-
_data = List(Bytes(), read_only=True, help='List of file content (bytes)').tag(
39-
sync=True, from_json=content_from_json
40-
)
4128

4229
accept = Unicode(help='File types to accept, empty string for all').tag(sync=True)
4330
multiple = Bool(help='If True, allow for multiple files upload').tag(sync=True)
@@ -48,17 +35,7 @@ class FileUpload(DescriptionWidget, ValueWidget, CoreWidget):
4835
help="""Use a predefined styling for the button.""").tag(sync=True)
4936
style = InstanceDict(ButtonStyle).tag(sync=True, **widget_serialization)
5037
error = Unicode(help='Error message').tag(sync=True)
51-
value = Dict(read_only=True)
52-
53-
@observe('_counter')
54-
def on_incr_counter(self, change):
55-
res = {}
56-
msg = 'Error: length of metadata and data must be equal'
57-
assert len(self._metadata) == len(self._data), msg
58-
for metadata, content in zip(self._metadata, self._data):
59-
name = metadata['name']
60-
res[name] = {'metadata': metadata, 'content': content}
61-
self.set_trait('value', res)
38+
value = List(Dict()).tag(sync=True)
6239

6340
@default('description')
6441
def _default_description(self):

packages/controls/src/widget_upload.ts

+9-20
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,18 @@ export class FileUploadModel extends CoreDOMWidgetModel {
1212
_model_name: 'FileUploadModel',
1313
_view_name: 'FileUploadView',
1414

15-
_counter: 0,
16-
_file_count: 0,
17-
_data: [],
18-
_metadata: [],
1915
accept: '',
2016
description: 'Upload',
2117
tooltip: '',
2218
disabled: false,
2319
icon: 'upload',
2420
button_style: '',
2521
multiple: false,
22+
value: [],
2623
error: '',
2724
style: null
2825
});
2926
}
30-
31-
static serializers = {
32-
...CoreDOMWidgetModel.serializers,
33-
_data: { serialize: (buffers: any) => { return [...buffers]; } },
34-
};
3527
}
3628

3729
export class FileUploadView extends DOMWidgetView {
@@ -97,18 +89,14 @@ export class FileUploadView extends DOMWidgetView {
9789

9890
Promise.all(promisesFile)
9991
.then(contents => {
100-
const metadata: any[] = [];
101-
const li_buffer: any[] = [];
102-
contents.forEach(c => {
103-
metadata.push(c.metadata);
104-
li_buffer.push(c.buffer);
92+
const value = contents.map(c => {
93+
return {
94+
metadata: c.metadata,
95+
content: c.buffer
96+
};
10597
});
106-
let counter = this.model.get('_counter');
10798
this.model.set({
108-
_counter: counter + contents.length,
109-
_file_count: contents.length,
110-
_metadata: metadata,
111-
_data: li_buffer,
99+
value,
112100
error: '',
113101
});
114102
this.touch();
@@ -131,7 +119,8 @@ export class FileUploadView extends DOMWidgetView {
131119
this.el.disabled = this.model.get('disabled');
132120
this.el.setAttribute('title', this.model.get('tooltip'));
133121

134-
let description = `${this.model.get('description')} (${this.model.get('_file_count')})`;
122+
const value: [] = this.model.get('value');
123+
let description = `${this.model.get('description')} (${value.length})`;
135124
let icon = this.model.get('icon');
136125
if (description.length || icon.length) {
137126
this.el.textContent = '';

packages/schema/jupyterwidgetmodels.latest.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -388,10 +388,7 @@ Attribute | Type | Default | Help
388388

389389
Attribute | Type | Default | Help
390390
-----------------|------------------|------------------|----
391-
`_counter` | number (integer) | `0` |
392-
`_data` | array | `[]` | List of file content (bytes)
393391
`_dom_classes` | array of string | `[]` | CSS classes applied to widget DOM element
394-
`_metadata` | array | `[]` | List of file metadata
395392
`_model_module` | string | `'@jupyter-widgets/controls'` |
396393
`_model_module_version` | string | `'1.5.0'` |
397394
`_model_name` | string | `'FileUploadModel'` |
@@ -409,6 +406,7 @@ Attribute | Type | Default | Help
409406
`multiple` | boolean | `false` | If True, allow for multiple files upload
410407
`style` | reference to ButtonStyle widget | reference to new instance |
411408
`tabbable` | `null` or boolean | `null` | Is widget tabbable?
409+
`value` | array | `[]` |
412410

413411
### FloatLogSliderModel (@jupyter-widgets/controls, 1.5.0); FloatLogSliderView (@jupyter-widgets/controls, 1.5.0)
414412

0 commit comments

Comments
 (0)