Skip to content

Commit

Permalink
added folder-select example and cleaned up code
Browse files Browse the repository at this point in the history
  • Loading branch information
MassiminoilTrace committed Aug 26, 2023
1 parent 74e4ef8 commit dfdcd9d
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 11 deletions.
16 changes: 10 additions & 6 deletions docs-src/0.4/en/reference/user_input.md
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
```
4 changes: 3 additions & 1 deletion src/doc_examples/input_fileengine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ use dioxus::prelude::*;

// ANCHOR: component
pub fn App(cx: Scope) -> Element {
// ANCHOR: rsx
let filenames: &UseRef<Vec<String>> = 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 {
Expand All @@ -22,5 +23,6 @@ pub fn App(cx: Scope) -> Element {
}
}
})
// ANCHOR_END: rsx
}
// ANCHOR_END: component
6 changes: 2 additions & 4 deletions src/doc_examples/input_fileengine_async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -30,6 +27,7 @@ pub fn App(cx: Scope) -> Element {
}
}
}
// ANCHOR_END: onchange_event
}
})
}
Expand Down
26 changes: 26 additions & 0 deletions src/doc_examples/input_fileengine_folder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;

// ANCHOR: component
pub fn App(cx: Scope) -> Element {
let filenames: &UseRef<Vec<String>> = 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

0 comments on commit dfdcd9d

Please sign in to comment.