From ba506342b5d198e6d93a5e35f56dcce4b82bbba9 Mon Sep 17 00:00:00 2001 From: blorbb <88137137+blorbb@users.noreply.github.com> Date: Sun, 11 Feb 2024 15:54:59 +1100 Subject: [PATCH 1/3] various fixes to forms page --- src/view/05_forms.md | 84 +++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/src/view/05_forms.md b/src/view/05_forms.md index 11a0ca6..578dbf6 100644 --- a/src/view/05_forms.md +++ b/src/view/05_forms.md @@ -75,17 +75,36 @@ view! { In an "uncontrolled input," the browser controls the state of the input element. Rather than continuously updating a signal to hold its value, we use a [`NodeRef`](https://docs.rs/leptos/latest/leptos/struct.NodeRef.html) to access -the input once when we want to get its value. +the input when we want to get its value. -In this example, we only notify the framework when the `
` fires a `submit` -event. +In this example, we only notify the framework when the `` fires a `submit` event. +Note the use of the [`leptos::html`](https://docs.rs/leptos/latest/leptos/html/index.html#) module, which provides a bunch of types for every HTML element. ```rust let (name, set_name) = create_signal("Uncontrolled".to_string()); -let input_element: NodeRef = create_node_ref(); +let input_element: NodeRef = create_node_ref(); + +view! { + // on_submit defined below + + + +

"Name is: " {name}

+} ``` +The view should be pretty self-explanatory by now. Note two things: + +1. Unlike in the controlled input example, we use `value` (not `prop:value`). + This is because we’re just setting the initial value of the input, and letting + the browser control its state. (We could use `prop:value` instead.) +2. We use `node_ref=...` to fill the `NodeRef`. (Older examples sometimes use `_ref`. + They are the same thing, but `node_ref` has better rust-analyzer support.) + `NodeRef` is a kind of reactive smart pointer: we can use it to access the underlying DOM node. Its value will be set when the element is rendered. @@ -98,8 +117,9 @@ let on_submit = move |ev: SubmitEvent| { let value = input_element() // event handlers can only fire after the view // is mounted to the DOM, so the `NodeRef` will be `Some` - .expect(" to exist") - // `NodeRef` implements `Deref` for the DOM element type + .expect(" should be mounted") + // `leptos::HtmlElement` implements `Deref` + // to a `web_sys::HtmlInputElement`. // this means we can call`HtmlInputElement::value()` // to get the current value of the input .value(); @@ -109,33 +129,15 @@ let on_submit = move |ev: SubmitEvent| { Our `on_submit` handler will access the input’s value and use it to call `set_name`. To access the DOM node stored in the `NodeRef`, we can simply call it as a function -(or using `.get()`). This will return `Option`, but we -know it will already have been filled when we rendered the view, so it’s safe to -unwrap here. +(or using `.get()`). This will return `Option>`, but we +know that the element has already been mounted (how else did you fire this event!), so +it's safe to unwrap here. We can then call `.value()` to get the value out of the input, because `NodeRef` gives us access to a correctly-typed HTML element. -```rust -view! { -
- - -
-

"Name is: " {name}

-} -``` - -The view should be pretty self-explanatory by now. Note two things: - -1. Unlike in the controlled input example, we use `value` (not `prop:value`). - This is because we’re just setting the initial value of the input, and letting - the browser control its state. (We could use `prop:value` instead.) -2. We use `node_ref` to fill the `NodeRef`. (Older examples sometimes use `_ref`. - They are the same thing, but `node_ref` has better rust-analyzer support.) +Take a look at [`web_sys` and `HtmlElement`](../web_sys.md) to learn more about using a `leptos::HtmlElement`. +Also see the full CodeSandbox example at the end of this page. ## Special Cases: ` } ``` ### `` element also does not have a `value` attribute, _or_ a `value` property. +The ``; if you try this in Leptos (or vanilla JavaScript) it won’t work. -Instead, use the `selected` field: +To use the `selected` field: ```rust let (value, set_value) = create_signal("B".to_string()); @@ -199,6 +201,7 @@ view! { ``` That's somewhat repetitive, but can easily be refactored: + ```rust #[component] pub fn App() -> impl IntoView { @@ -228,6 +231,13 @@ pub fn SelectOption(is: &'static str, value: ReadSignal) -> impl IntoVie } ``` +> Tip: the single `value` attribute in the component is equivalent to `value=value`. +> This is only the case for _components_: in HTML elements, a single `value` attribute is equivalent to `value=true`. +> This is expected to be made consistent in the next major version of Leptos; see [this issue](https://github.com/leptos-rs/leptos/issues/2196) +> for more details. + +**Controlled vs uncontrolled forms CodeSandbox:** + [Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/5-forms-0-5-rf2t7c?file=%2Fsrc%2Fmain.rs%3A1%2C1) From ba50f6e226d88c68f297d6628770e9783fc33415 Mon Sep 17 00:00:00 2001 From: blorbb <88137137+blorbb@users.noreply.github.com> Date: Sun, 11 Feb 2024 15:57:06 +1100 Subject: [PATCH 2/3] add docs to `with!` macros --- src/reactivity/working_with_signals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reactivity/working_with_signals.md b/src/reactivity/working_with_signals.md index 89556c9..f576086 100644 --- a/src/reactivity/working_with_signals.md +++ b/src/reactivity/working_with_signals.md @@ -91,7 +91,7 @@ Instead, you can use the `with!` macro to get references to all the signals at t let name = move || with!(|first, middle, last| format!("{first} {middle} {last}")); ``` -This expands to the same thing as above. Take a look at the `with!` docs for more info, and the corresponding macros `update!`, `with_value!` and `update_value!`. +This expands to the same thing as above. Take a look at the [`with!`](https://docs.rs/leptos/latest/leptos/macro.with.html) docs for more info, and the corresponding macros [`update!`](https://docs.rs/leptos/latest/leptos/macro.update.html), [`with_value!`](https://docs.rs/leptos/latest/leptos/macro.with_value.html) and [`update_value!`](https://docs.rs/leptos/latest/leptos/macro.update_value.html). ## Making signals depend on each other From 062bc9493e8a2570b3e2690877bf3d72b01dca76 Mon Sep 17 00:00:00 2001 From: blorbb <88137137+blorbb@users.noreply.github.com> Date: Sun, 11 Feb 2024 15:59:18 +1100 Subject: [PATCH 3/3] show full path of `SubmitEvent` --- src/view/05_forms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view/05_forms.md b/src/view/05_forms.md index 578dbf6..740e12e 100644 --- a/src/view/05_forms.md +++ b/src/view/05_forms.md @@ -109,7 +109,7 @@ The view should be pretty self-explanatory by now. Note two things: underlying DOM node. Its value will be set when the element is rendered. ```rust -let on_submit = move |ev: SubmitEvent| { +let on_submit = move |ev: leptos::ev::SubmitEvent| { // stop the page from reloading! ev.prevent_default();