file_upload.rs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //! This example shows how to use the `file` methods on FormEvent and DragEvent to handle file uploads and drops.
  2. //!
  3. //! Dioxus intercepts these events and provides a Rusty interface to the file data. Since we want this interface to
  4. //! be crossplatform,
  5. use std::sync::Arc;
  6. use dioxus::prelude::*;
  7. use dioxus::{html::HasFileData, prelude::dioxus_elements::FileEngine};
  8. fn main() {
  9. launch(app);
  10. }
  11. struct UploadedFile {
  12. name: String,
  13. contents: String,
  14. }
  15. fn app() -> Element {
  16. let mut enable_directory_upload = use_signal(|| false);
  17. let mut files_uploaded = use_signal(|| Vec::new() as Vec<UploadedFile>);
  18. let read_files = move |file_engine: Arc<dyn FileEngine>| async move {
  19. let files = file_engine.files();
  20. for file_name in &files {
  21. if let Some(contents) = file_engine.read_file_to_string(file_name).await {
  22. files_uploaded.write().push(UploadedFile {
  23. name: file_name.clone(),
  24. contents,
  25. });
  26. }
  27. }
  28. };
  29. let upload_files = move |evt: FormEvent| async move {
  30. if let Some(file_engine) = evt.files() {
  31. read_files(file_engine).await;
  32. }
  33. };
  34. let handle_file_drop = move |evt: DragEvent| async move {
  35. if let Some(file_engine) = evt.files() {
  36. read_files(file_engine).await;
  37. }
  38. };
  39. rsx! {
  40. style { {include_str!("./assets/file_upload.css")} }
  41. h1 { "File Upload Example" }
  42. p { "Drop a .txt, .rs, or .js file here to read it" }
  43. div {
  44. label { r#for: "directory-upload", "Enable directory upload" }
  45. input {
  46. r#type: "checkbox",
  47. id: "directory-upload",
  48. checked: enable_directory_upload,
  49. oninput: move |evt| enable_directory_upload.set(evt.checked()),
  50. },
  51. }
  52. div {
  53. label { r#for: "textreader", "Upload text/rust files and read them" }
  54. input {
  55. r#type: "file",
  56. accept: ".txt,.rs,.js",
  57. multiple: true,
  58. name: "textreader",
  59. directory: enable_directory_upload,
  60. onchange: upload_files,
  61. }
  62. }
  63. div {
  64. // cheating with a little bit of JS...
  65. "ondragover": "this.style.backgroundColor='#88FF88';",
  66. "ondragleave": "this.style.backgroundColor='#FFFFFF';",
  67. "ondrop": "this.style.backgroundColor='#FFFFFF';",
  68. id: "drop-zone",
  69. prevent_default: "ondragover",
  70. prevent_default: "ondrop",
  71. ondrop: handle_file_drop,
  72. "Drop files here"
  73. }
  74. ul {
  75. for file in files_uploaded.read().iter().rev() {
  76. li {
  77. span { "{file.name}" }
  78. pre { "{file.contents}" }
  79. }
  80. }
  81. }
  82. }
  83. }