DioxusLabs / dioxus

Fullstack app framework for web, desktop, mobile, and more.
https://dioxuslabs.com
Apache License 2.0
20.08k stars 768 forks source link

Select not updating on load with `selected` changing #2637

Closed kalebvonburris closed 1 month ago

kalebvonburris commented 1 month ago

Problem

When loading data into an application, you set what <option> a <select> is using with the selected=true flag. In Dioxus, doing this results in the selected <option> always displaying the first value available regardless of the selected value.

Steps To Reproduce

Steps to reproduce the behavior:

Expected behavior

Screenshots

Environment:

Questionnaire

ealmloff commented 1 month ago

I cannot reproduce the issue with this setup:

#![allow(non_snake_case)]
use dioxus::prelude::*;

fn main() {
    launch(|| {
        let mut value = use_signal(|| "volvo".to_string());
        rsx! {
            select {
                id: "cars",
                oninput: move |evt| {
                    value.set(evt.value());
                },
                option {
                    value: "volvo",
                    selected: &*value.read() == "volvo",
                    "Volvo"
                }
                option {
                    value: "saab",
                    selected: &*value.read() == "saab",
                    "Saab"
                }
                option {
                    value: "opel",
                    selected: &*value.read() == "opel",
                    "Opel"
                }
                option {
                    value: "audi",
                    selected: &*value.read() == "audi",
                    "Audi"
                }
            }
            "{value}"
        }
    });
}
[dependencies]
dioxus = { version = "0.5.1", features = ["web"] }

A similar setup with numbers for values also works:

#![allow(non_snake_case)]
use dioxus::prelude::*;

fn main() {
    launch(|| {
        let mut value = use_signal(|| 0);
        rsx! {
            select {
                id: "cars",
                oninput: move |evt| {
                    value.set(evt.value().parse::<usize>().unwrap());
                },
                option {
                    value: 0,
                    selected: value() == 0,
                    "Volvo"
                }
                option {
                    value: 1,
                    selected: value() == 1,
                    "Saab"
                }
                option {
                    value: 2,
                    selected: value() == 2,
                    "Opel"
                }
                option {
                    value: 3,
                    selected: value() == 3,
                    "Audi"
                }
            }
            "{value}"
        }
    });
}
kalebvonburris commented 1 month ago

Try setting the initial value to something that isn't the first option.

ealmloff commented 1 month ago

This also works with the initial value set to the second option:

#![allow(non_snake_case)]
use dioxus::prelude::*;

fn main() {
    launch(|| {
        let mut value = use_signal(|| 1);

        rsx! {
            select {
                id: "cars",
                oninput: move |evt| {
                    value.set(evt.value().parse::<usize>().unwrap());
                },
                option {
                    value: 0,
                    selected: value() == 0,
                    "Volvo"
                }
                option {
                    value: 1,
                    selected: value() == 1,
                    "Saab"
                }
                option {
                    value: 2,
                    selected: value() == 2,
                    "Opel"
                }
                option {
                    value: 3,
                    selected: value() == 3,
                    "Audi"
                }
            }
            "{value}"
        }
    });
}