From 5d23a7e35a3d97347bd3ed9fe1f31a0586cbb5de Mon Sep 17 00:00:00 2001 From: blorbb <88137137+blorbb@users.noreply.github.com> Date: Tue, 13 Feb 2024 12:25:58 +1100 Subject: [PATCH] Collection of minor changes (#63) * various fixes to forms page * add docs to `with!` macros * show full path of `SubmitEvent` --- src/reactivity/working_with_signals.md | 2 +- src/view/05_forms.md | 102 ++++++++++++++----------- 2 files changed, 57 insertions(+), 47 deletions(-) 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 diff --git a/src/view/05_forms.md b/src/view/05_forms.md index 11a0ca6..740e12e 100644 --- a/src/view/05_forms.md +++ b/src/view/05_forms.md @@ -75,50 +75,18 @@ 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(); -`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. - -```rust -let on_submit = move |ev: SubmitEvent| { - // stop the page from reloading! - ev.prevent_default(); - - // here, we'll extract the value from the input - 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 - // this means we can call`HtmlInputElement::value()` - // to get the current value of the input - .value(); - set_name(value); -}; -``` - -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. - -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! { - + // on_submit defined below 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(); + set_name(value); +}; +``` + +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 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. + +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)