From 00da577fdff33f26577eab3d9436f99728da55b1 Mon Sep 17 00:00:00 2001 From: Kent Tong Date: Thu, 28 Jul 2022 20:07:28 +0800 Subject: [PATCH 1/2] bug fix: supporting multiple file input elements --- examples/multiuploads.py | 15 ++++++++++ justpy/templates/js/html_component.js | 40 +++++++++++++-------------- 2 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 examples/multiuploads.py diff --git a/examples/multiuploads.py b/examples/multiuploads.py new file mode 100644 index 00000000..724da530 --- /dev/null +++ b/examples/multiuploads.py @@ -0,0 +1,15 @@ +from justpy import * + +def on_submit(c, msg): + print(len(msg.form_data[0]["files"][0]["file_content"])) + print(len(msg.form_data[1]["files"][0]["file_content"])) + +def multi_uploads(): + wp=WebPage() + form=Form(a=wp, submit=on_submit) + Input(type="file", name="f1", a=form) + Input(type="file", name="f2", a=form) + Input(type="submit", value="OK", a=form) + return wp + +justpy(multi_uploads) \ No newline at end of file diff --git a/justpy/templates/js/html_component.js b/justpy/templates/js/html_component.js index 64bea2a4..6ba33ab9 100644 --- a/justpy/templates/js/html_component.js +++ b/justpy/templates/js/html_component.js @@ -81,11 +81,7 @@ Vue.component('html_component', { event.stopPropagation(); var form_elements_list = []; var form_elements = form_reference.elements; - var reader = new FileReader(); - var file_readers = []; - var reader_ready = []; - var file_content = []; - var file_element_position = null; + var uploaders=[]; for (var i = 0; i < form_elements.length; i++) { var attributes = form_elements[i].attributes; @@ -103,15 +99,15 @@ Vue.component('html_component', { attr_dict['id'] = form_elements[i].id; if ((attr_dict['html_tag'] == 'input') && (input_type == 'file') && (files_chosen[attr_dict['id']])) { - file_element_position = i; - reader_ready = []; + let uploader={ file_readers: [], file_content:[], file_element_position: i, reader_ready: [] }; + uploaders.push(uploader); attr_dict['files'] = []; const file_list = files_chosen[attr_dict['id']]; const num_files = file_list.length; for (let j = 0; j < num_files; j++) { - reader_ready.push(false); - file_content.push('pending'); - file_readers.push(new FileReader()); + uploader.reader_ready.push(false); + uploader.file_content.push('pending'); + uploader.file_readers.push(new FileReader()); attr_dict['files'].push({ file_content: 'pending', name: file_list[j].name, @@ -121,11 +117,12 @@ Vue.component('html_component', { }); } for (let j = 0; j < num_files; j++) { - file_readers[j].onload = function (e) { - file_content[j] = e.target.result.substring(e.target.result.indexOf(",") + 1); - reader_ready[j] = true; + uploader.file_readers[j].onload = function (e) { + console.log("loaded"); + uploader.file_content[j] = e.target.result.substring(e.target.result.indexOf(",") + 1); + uploader.reader_ready[j] = true; }; - file_readers[j].readAsDataURL(file_list[j]); + uploader.file_readers[j].readAsDataURL(file_list[j]); } } @@ -133,13 +130,16 @@ Vue.component('html_component', { } function check_readers() { - if (reader_ready.every(function (x) { + reader_ready_all=uploaders.flatMap((uploader)=> uploader.reader_ready); + if (reader_ready_all.every(function (x) { return x })) { - const file_element = form_elements_list[file_element_position]; + for (uploader of uploaders) { + const file_element = form_elements_list[uploader.file_element_position]; - for (let i = 0; i < file_element.files.length; i++) { - file_element.files[i].file_content = file_content[i]; + for (let i = 0; i < file_element.files.length; i++) { + file_element.files[i].file_content = uploader.file_content[i]; + } } eventHandler(props, event, form_elements_list); return; @@ -149,7 +149,7 @@ Vue.component('html_component', { setTimeout(check_readers, 300); } - if (file_element_position === null) { + if (uploaders.length==0) { eventHandler(props, event, form_elements_list); } else { check_readers(); @@ -334,4 +334,4 @@ Vue.component('html_component', { } }); -// {% endraw %} \ No newline at end of file +// {% endraw %} From 2704b13fd1f156f57d403573ad53604ba103eed6 Mon Sep 17 00:00:00 2001 From: Kent Tong Date: Tue, 23 Aug 2022 20:40:28 +0800 Subject: [PATCH 2/2] make the example nicer --- examples/multiuploads.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/examples/multiuploads.py b/examples/multiuploads.py index 724da530..fd22c488 100644 --- a/examples/multiuploads.py +++ b/examples/multiuploads.py @@ -1,15 +1,22 @@ from justpy import * -def on_submit(c, msg): - print(len(msg.form_data[0]["files"][0]["file_content"])) - print(len(msg.form_data[1]["files"][0]["file_content"])) +def handle_submit(c, msg): + fl=msg.page.file_list + fl.components.clear() + for fd in msg.form_data: + if "files" in fd: + for f in fd["files"]: + Li(text=f"File uploaded: {f['name']} of {len(f['file_content'])}", a=fl) -def multi_uploads(): - wp=WebPage() - form=Form(a=wp, submit=on_submit) - Input(type="file", name="f1", a=form) - Input(type="file", name="f2", a=form) - Input(type="submit", value="OK", a=form) - return wp +def p1(): + wp=WebPage() + f=Form(submit=handle_submit, a=wp) + Input(name="f1", type="file", a=f) + Input(name="f2", type="file", a=f) + Input(type="submit", value="OK", a=f) + wp.file_list=Ol(a=wp) + return wp + -justpy(multi_uploads) \ No newline at end of file +WebPage.tailwind=False +justpy(p1, start_server=(__name__=="__main__"))