Find a smart way to handle a form.
<form onsubmit=|e| { e.prevent_default(); Msg::Submit(FormData::from(e.target()) },>
<input type="text", value=&self.search, />
<button>{ "Search" }</button>
</form>
Retrieving a FormData object from an HTML form.
If I correctly understand, to handle a form I need a message for each input to update model state and a message for the submit button.
<div>
<input type="text", value=&self.search, oninput=|e| Msg::Update(e.value) />
<button onclick=|_| Msg::Submit>{ "Search" }</button>
</div>
I don鈥檛 know if my proposal is the good way to do that (I discovert FormData while writing this issue) but it seems less painful than added one message per input.
I play with stdweb to implement FormData, and here is a real example:
use stdweb::web::FormData;
use stdweb::web::event::IEvent;
use stdweb::unstable::TryInto;
use yew::{html, Component, ComponentLink, Html, Renderable, ShouldRender};
#[derive(Default)]
pub struct Model {
state: State,
}
#[derive(Debug, Default)]
pub struct State {
terms: String,
strict: bool,
}
impl From<FormData> for State {
fn from(data: FormData) -> Self {
Self {
terms: data.get("terms").into_string().unwrap(),
strict: data.get("strict").as_str() == Some("on"),
}
}
}
impl std::fmt::Display for State {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub enum Msg {
Submit(FormData),
}
impl Component for Model {
type Message = Msg;
type Properties = ();
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
Default::default()
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::Submit(data) => self.state = data.into(),
}
true
}
}
impl Renderable<Model> for Model {
fn view(&self) -> Html<Self> {
html! {
<div>
<form onsubmit=|e| { e.prevent_default(); Msg::Submit(FormData::new(&e.target().unwrap().try_into().unwrap())) },>
<input type="text", name="terms", value=&self.state.terms, />
<input type="checkbox", name="strict", checked=self.state.strict, />
<button>{ "Search" }</button>
</form>
</div>
<div>{ &self.state }</div>
}
}
}
Looks like this has been fixed!
Most helpful comment
I play with stdweb to implement
FormData, and here is a real example: