-
-
Notifications
You must be signed in to change notification settings - Fork 759
<intput> with f64 values and interactive editing #1956
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I think I understand using european vs. us number formatting. I need to use the browser locale setting, or something similar to this code:
https://stackoverflow.com/questions/13412204/localization-of-input-type-number I'll update the question to make it shorter now. |
The way I typically do this is using a String for the input value, and then a derived signal parsing the value into f64. let value = RwSignal::new(String::new());
let num: Signal<Option<f64>> = Signal::derive(move || value.with(|value| value.parse().ok())); |
Nevermind, I also just came across this issue! In my case I'm going to use uncontrolled inputs to let my browser control the value. let num = RwSignal::new(0.0);
view! {
<input type="number" value=num on:input=move |ev| {
let input: web_sys::HtmlInputElement = event_target(&ev);
let value = input.value_as_number();
if !value.is_nan() {
num.set(value);
}
} />
} Note: I don't use |
I do not think this is a bug in Leptos. Specifically, when you use If I just open up the example and pull the input into the console, Using an uncontrolled input (so, not using |
@tqwewe thanks for pointing out how to modify the input value directly!
@gbj thanks for clearifications. i will decouple the f64 value from the prop:value and use a string instead! i do this now:
thanks so much! |
This is the code I think i'll use: Internally it uses a String so I can even have incomplete values like: "1,". When compared to using a float as internal value I had this problem: Say you were editing 1,2 into 1,3 and you would remove the 3 at the end, it would auto-correct into 1 instead of 1, so one would always have to enter ,3 instead of just 3. Hard to explain. But for whoever cares, this is the code I think works nice: // parses 1.100.100,23 to 1100100.23
fn parse_de_string_into_f64(input: String) -> Result<f64, String> {
let f = input.replace(".", "").replace(",", ".").parse::<f64>();
match f {
Ok(v) => {
Ok(v)
},
Err(e) => {
Err(format!("{}", e))
}
}
}
// formats 23222221231.7666 to 23.222.221.231,7666
// formats 23222221231 to 23.222.221.231
// formats 2, to 2
fn format_f64_into_de_string(number: f64) -> String {
let mut num_str = format!("{:.}", number);
let mut integer="";
let mut decimal="";
if num_str.find('.').is_none() {
num_str.push_str(".");
(integer, _) = num_str.split_at(num_str.find('.').unwrap());
} else {
(integer, decimal) = num_str.split_at(num_str.find('.').unwrap());
}
let integer_str = integer.chars().rev().enumerate().map(|(i, c)| {
let z: &str = if i!= 0 &&i % 3==0 && i!=integer.len() {"."} else {""};
format!("{}{}", z, c.to_string())}).collect::<String>();
let v = integer_str.chars().rev().collect::<String>();
format!("{}{}", v, decimal.replace(".", ","))
}
pub fn Input4() -> impl IntoView {
let input_string = create_rw_signal(String::new());
let output_float = RwSignal::new(Option::<f64>::None);
let infoX = create_rw_signal("".to_string());
view! {
<h2>input4</h2>
<p>With focus events: Using the same f64 type internally and as signal externally</p>
<input data-testid="Input4" type="text"
on:focusin=move |ev| {
let z = input_string.get().replace(".", "");
input_string.set(format!("{}", z));
}
on:focusout=move |ev| {
let zz = parse_de_string_into_f64(input_string.get());
match zz {
Ok(v) => {
let s = format_f64_into_de_string(v);
infoX.set("".to_string());
input_string.set(s);
},
Err(e) => {
infoX.set("Can't update input_string because float is invalid".to_string());
info!("{}: zz not parsable", e)
}
}
}
on:input=move |ev| {
let input: String = event_target_value(&ev);
input_string.set(input);
}
prop:value = move || {
let zz = parse_de_string_into_f64(input_string.get());
match zz {
Ok(v) => {
infoX.set("".to_string());
output_float.set(Some(v));
},
Err(e) => {
infoX.set("Can't update output_float from prop:value because float is invalid".to_string());
output_float.set(None);
}
}
input_string.get()
}
/>
<p>
input_string: { move || input_string.get()}
</p>
<p>
output_float: { move || {let o = output_float.get(); if o.is_some() {format!("{}", o.unwrap())} else {"None".to_string()} }}
</p>
<p>
"Status: " { move || infoX.get() }
</p>
<button on:click=move |_| {
input_string.set("1,23".to_string());
}
>Reset</button>
}
} |
Describe the bug
Big picture:
Not sure this is a bug or me using the signals/input typs wrong.
question
Example Input() uses only a f64 and updates itself on changes. This breaks editing, as going from "1.2" (with backspace) rewrites the number to "1" instead of "1.".
Question: Is using signals in a loop a bad thing?
the code
The text was updated successfully, but these errors were encountered: