From 9df3ff8d633a18e934d4e62b0e2e718620760552 Mon Sep 17 00:00:00 2001 From: jelemux Date: Tue, 9 Feb 2021 22:38:40 +0100 Subject: add file input field, include file as data url in vcard --- src/viewmodel/mod.rs | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) (limited to 'src/viewmodel/mod.rs') diff --git a/src/viewmodel/mod.rs b/src/viewmodel/mod.rs index 75ed1d2..044dbad 100644 --- a/src/viewmodel/mod.rs +++ b/src/viewmodel/mod.rs @@ -1,3 +1,8 @@ +use wasm_bindgen::closure::Closure; +use web_sys::FileReader; +use wasm_bindgen::JsCast; +use yew::services::ConsoleService; +use crate::viewmodel::utility::File; use yew::prelude::*; use crate::view::VCardPropertyInputComponent; @@ -50,7 +55,13 @@ pub enum VCardPropertyInputField { placeholder: Option, oninput: Callback, value: String, - typ: String + typ: String, + }, + File { + label: String, + name: String, + callback: Callback>, + value: Option, }, CheckBox { label: String, @@ -72,6 +83,12 @@ impl VCardPropertyInputField { value: _, typ, } => Self::text_field_input(label, id, placeholder, oninput, typ), + Self::File { + label, + name, + callback, + value, + } => Self::file_field_input(label, name, callback, value), Self::CheckBox { label, id, @@ -99,6 +116,82 @@ impl VCardPropertyInputField { } } + /// Returns an `Html` representation of a file input field with the given parameters. + fn file_field_input(label: &str, name: &str, callback: &Callback>, file: &Option) -> Html { + let callback = callback.clone(); + let onchange = Callback::<()>::default(); + let onchange = onchange.reform(move |c: ChangeData| + if let ChangeData::Files(files) = c { + match files.item(0) { + Some(file) => { + let file_reader = FileReader::new().unwrap(); + match file_reader.read_as_data_url(&file) { + Ok(_) => (), + Err(_) => ConsoleService::warn("Error: Couldn't get file as data url."), + }; + + let callback = callback.clone(); + let onload = Closure::wrap(Box::new(move |event: Event|{ + let file_reader: FileReader = event.target().unwrap().dyn_into().unwrap(); + let data_url: Option = file_reader.result().unwrap().as_string(); + match data_url { + Some(content) => callback.emit( + Some(File { + name: file.name(), + content, + }) + ), + None => { + ConsoleService::warn("Couldn't get data url as string."); + callback.emit(None); + }, + }; + }) as Box); + + file_reader.set_onload(Some(onload.as_ref().unchecked_ref())); + onload.forget(); + }, + None => callback.emit(None), + } + } else { + callback.emit(None); + } + ); + html!{ +
+ +
+ +
+
+ } + } /// Returns an `Html` representation of a checkbox input field with the given parameters. fn checkbox_field_input(label: &str, id: &Option, checked: &bool, onclick: &Callback) -> Html { html!{ -- cgit v1.2.3