yew icon indicating copy to clipboard operation
yew copied to clipboard

Select element last element cant be set programatically

Open voidpumpkin opened this issue 3 years ago • 5 comments

Problem

use yew::prelude::*;

#[function_component]
fn App() -> Html {
    let selection_handle = use_state(|| 2_usize);

    html! {
        <div>
            <select >
                <option value=1 selected={*selection_handle == 1}>{ "Option 1" }</option>
                <option value=2 selected={*selection_handle == 2}>{ "Option 2" }</option>
                <option value=3 selected={*selection_handle == 3}>{ "Option 3" }</option>
                <option value=4 selected={*selection_handle == 4}>{ "Option 4" }</option>
            </select>

            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(1))} }>{"Set to 1"}</button>
            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(2))} }>{"Set to 2"}</button>
            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(3))} }>{"Set to 3"}</button>
            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(4))} }>{"Set to 4"}</button>
        </div>
    }
}

fn main() {
    yew::start_app::<App>();
}

click "Set to 4" observe how select shows "Option 1" not 4

Environment:

  • Yew version: [0.19, master]

Questionnaire

  • [ ] I'm interested in fixing this myself but don't know where to start
  • [ ] I would like to fix and I have a solution
  • [ x] I don't have time to fix this right now, but maybe later

voidpumpkin avatar Mar 19 '22 13:03 voidpumpkin

On MDN it says selected is only used for first load.

Its possible we need to introduce custom yew attribute for select so we could pass value I believe react solved this exactly that way, with introduction of value and defaultValue on select tag

voidpumpkin avatar Mar 19 '22 13:03 voidpumpkin

Related? #1322

WorldSEnder avatar Mar 19 '22 13:03 WorldSEnder

Related? #1322

i dont think so

voidpumpkin avatar Mar 19 '22 13:03 voidpumpkin

For now this bug can be worked around:

use web_sys::HtmlSelectElement;
use yew::prelude::*;

#[function_component]
fn App() -> Html {
    let selection_handle = use_state(|| 2_usize);

    let select_node_ref = use_node_ref();

    {
        let select_node_ref = select_node_ref.clone();
        use_effect_with_deps(
            move |selection| {
                if let Some(element) = select_node_ref.cast::<HtmlSelectElement>() {
                    element.set_value(&(selection.to_string()));
                }
                || {}
            },
            *selection_handle,
        )
    };

    html! {
        <div>
            <select ref={select_node_ref}>
                <option value=1>{ "Option 1" }</option>
                <option value=2>{ "Option 2" }</option>
                <option value=3>{ "Option 3" }</option>
                <option value=4>{ "Option 4" }</option>
            </select>

            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(1))} }>{"Set to 1"}</button>
            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(2))} }>{"Set to 2"}</button>
            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(3))} }>{"Set to 3"}</button>
            <button onclick={ {let selection_handle = selection_handle.clone();  Callback::from(move |_| selection_handle.set(4))} }>{"Set to 4"}</button>
        </div>
    }
}

fn main() {
    yew::start_app::<App>();
}

voidpumpkin avatar Mar 19 '22 13:03 voidpumpkin

Related? #1322

i dont whink so

Going by your fix of calling set_value, I'd say it is related

ranile avatar Mar 19 '22 13:03 ranile