From dfdcd9da4a36f50dd085a60ca7d424ea27fd5a96 Mon Sep 17 00:00:00 2001 From: Massimo Date: Sat, 26 Aug 2023 16:58:43 +0200 Subject: [PATCH] added folder-select example and cleaned up code --- docs-src/0.4/en/reference/user_input.md | 16 ++++++++----- src/doc_examples/input_fileengine.rs | 4 +++- src/doc_examples/input_fileengine_async.rs | 6 ++--- src/doc_examples/input_fileengine_folder.rs | 26 +++++++++++++++++++++ 4 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 src/doc_examples/input_fileengine_folder.rs diff --git a/docs-src/0.4/en/reference/user_input.md b/docs-src/0.4/en/reference/user_input.md index 2b0c94388..70dc58a08 100644 --- a/docs-src/0.4/en/reference/user_input.md +++ b/docs-src/0.4/en/reference/user_input.md @@ -43,22 +43,26 @@ Submitted! UiEvent { data: FormData { value: "", values: {"age": "very old", "da ``` ## Handling files -You can insert a file picker by using an input element e.g. `input {"type":"file"}`. This element supports the `multiple` attribute, to let you pick more files at the same time. You can select an entire folder by adding the `directory` attribute. - -> Dioxus will map this attribute to browser specific attributes. Because there is no standardized way to allow a directory to be selected. +You can insert a file picker by using an input element of type `file`. This element supports the `multiple` attribute, to let you pick more files at the same time. You can select a folder by adding the `directory` attribute: Dioxus will map this attribute to browser specific attributes, because there is no standardized way to allow a directory to be selected. `type` is a Rust keyword, so when specifying the type of the input field, you have to write it as `r#type:"file"`. Extracting the selected files is a bit different from what you may typically use in Javascript. -The `FormData` event contains a `files` field with data about the uploaded files. This field has a `FileEngine` struct which lets you fetch the filenames selected by the user. This example saves the filenames of the selected files to a `Vec`: +The `FormData` event contains a `files` field with data about the uploaded files. This field contains a `FileEngine` struct which lets you fetch the filenames selected by the user. This example saves the filenames of the selected files to a `Vec`: ```rust, no_run {{#include src/doc_examples/input_fileengine.rs:component}} ``` -If you're planning to read the file content, you need to do it asynchronously, to keep the rest of the UI interactive. This example loads the content of the selected files in an async closure: +If you're planning to read the file content, you need to do it asynchronously, to keep the rest of the UI interactive. This example event handler loads the content of the selected files in an async closure: + +```rust, no_run +{{#include src/doc_examples/input_fileengine_async.rs:onchange_event}} +``` + +Lastly, this example shows you how to select a folder, by setting the `directory` attribute to `true`. ```rust, no_run -{{#include src/doc_examples/input_fileengine_async.rs:component}} +{{#include src/doc_examples/input_fileengine_folder.rs:rsx}} ``` \ No newline at end of file diff --git a/src/doc_examples/input_fileengine.rs b/src/doc_examples/input_fileengine.rs index 2fac9b4df..cdb9fd7f4 100644 --- a/src/doc_examples/input_fileengine.rs +++ b/src/doc_examples/input_fileengine.rs @@ -3,14 +3,15 @@ use dioxus::prelude::*; // ANCHOR: component pub fn App(cx: Scope) -> Element { + // ANCHOR: rsx let filenames: &UseRef> = use_ref(cx, Vec::new); - cx.render(rsx! { input { // tell the input to pick a file r#type:"file", // list the accepted extensions accept: ".txt, .rs", + // pick multiple files multiple: true, onchange: |evt| { if let Some(file_engine) = &evt.files { @@ -22,5 +23,6 @@ pub fn App(cx: Scope) -> Element { } } }) + // ANCHOR_END: rsx } // ANCHOR_END: component diff --git a/src/doc_examples/input_fileengine_async.rs b/src/doc_examples/input_fileengine_async.rs index 514688e0c..3da36ed65 100644 --- a/src/doc_examples/input_fileengine_async.rs +++ b/src/doc_examples/input_fileengine_async.rs @@ -7,13 +7,10 @@ pub fn App(cx: Scope) -> Element { cx.render(rsx! { input { - // we tell the component what to render - value: "{name}", - // tell the input to pick a file r#type:"file", - // list the accepted extensions accept: ".txt, .rs", multiple: true, + // ANCHOR: onchange_event onchange: |evt| { // A helper macro to use hooks in async environments to_owned![files_uploaded]; @@ -30,6 +27,7 @@ pub fn App(cx: Scope) -> Element { } } } + // ANCHOR_END: onchange_event } }) } diff --git a/src/doc_examples/input_fileengine_folder.rs b/src/doc_examples/input_fileengine_folder.rs new file mode 100644 index 000000000..15d8228d6 --- /dev/null +++ b/src/doc_examples/input_fileengine_folder.rs @@ -0,0 +1,26 @@ +#![allow(non_snake_case)] +use dioxus::prelude::*; + +// ANCHOR: component +pub fn App(cx: Scope) -> Element { + let filenames: &UseRef> = use_ref(cx, Vec::new); + cx.render(rsx! { + // ANCHOR: rsx + input { + r#type:"file", + // Select a folder by setting the directory attribute + directory: true, + onchange: |evt| { + if let Some(file_engine) = &evt.files { + let files = file_engine.files(); + for file_name in &files { + println!("{}", file_name); + // Do something with the folder path + } + } + } + } + // ANCHOR_END: rsx + }) +} +// ANCHOR_END: component