generated from mitchell/rust_template
156 lines
4.6 KiB
Rust
156 lines
4.6 KiB
Rust
use super::FormStyle;
|
|
use crate::controls::{
|
|
heading::HeadingData, select::SelectData, submit::SubmitData, text_area::TextAreaData,
|
|
text_input::TextInputData, ControlData, ControlRenderData,
|
|
};
|
|
use leptos::*;
|
|
use leptos_router::Form;
|
|
|
|
pub enum GridFormStylingAttributes {
|
|
Width(u32),
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
|
pub struct GridFormStyle;
|
|
|
|
impl FormStyle for GridFormStyle {
|
|
type StylingAttributes = GridFormStylingAttributes;
|
|
|
|
// TODO: something about an on-submit thing
|
|
fn form_frame(&self, children: View) -> View {
|
|
view! {
|
|
<Form action="" class="form_grid">
|
|
{children}
|
|
</Form>
|
|
}
|
|
.into_view()
|
|
}
|
|
|
|
fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View {
|
|
view! {
|
|
<h2 class="form_heading">
|
|
{&control.data.title}
|
|
</h2>
|
|
}
|
|
.into_view()
|
|
}
|
|
|
|
fn text_input(
|
|
&self,
|
|
control: ControlRenderData<Self, TextInputData>,
|
|
value_getter: Signal<<TextInputData as ControlData>::ReturnType>,
|
|
value_setter: Box<dyn Fn(<TextInputData as ControlData>::ReturnType)>,
|
|
validation_state: Signal<Result<(), String>>,
|
|
) -> View {
|
|
view! {
|
|
<div>
|
|
<div>
|
|
<label for={&control.data.name} class="form_label">
|
|
{control.data.label.as_ref()}
|
|
</label>
|
|
<span class="form_error">
|
|
{move || format!("{}", validation_state.get().err().unwrap_or_default())}
|
|
</span>
|
|
</div>
|
|
<input
|
|
// TODO:
|
|
type=control.data.input_type
|
|
id=&control.data.name
|
|
name=control.data.name
|
|
placeholder=control.data.placeholder
|
|
prop:value=move || value_getter.get()
|
|
on:change=move |ev| {
|
|
value_setter(event_target_value(&ev));
|
|
}
|
|
class="form_input"
|
|
class=("form_input_invalid", move || validation_state.get().is_err())
|
|
/>
|
|
</div>
|
|
}
|
|
.into_view()
|
|
}
|
|
|
|
fn select(
|
|
&self,
|
|
control: ControlRenderData<Self, SelectData>,
|
|
value_getter: Signal<<SelectData as ControlData>::ReturnType>,
|
|
value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
|
|
validation_state: Signal<Result<(), String>>,
|
|
) -> View {
|
|
let options_view = control
|
|
.data
|
|
.options
|
|
.into_iter()
|
|
.map(|value| {
|
|
// let value = value;
|
|
let cloned_value = value.clone();
|
|
view! {
|
|
<option
|
|
value={value}
|
|
selected=move || value_getter.get() == *cloned_value
|
|
>
|
|
*value
|
|
</option>
|
|
}
|
|
})
|
|
.collect_view();
|
|
|
|
view! {
|
|
<div>
|
|
{move || format!("{:?}", validation_state.get())}
|
|
<select
|
|
id=&control.data.name
|
|
name=control.data.name
|
|
class="form_input"
|
|
on:change=move |ev| {
|
|
value_setter(event_target_value(&ev));
|
|
}
|
|
>
|
|
{options_view}
|
|
</select>
|
|
</div>
|
|
}
|
|
.into_view()
|
|
}
|
|
|
|
fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View {
|
|
view! {
|
|
<input
|
|
type="submit"
|
|
value=control.data.text
|
|
class="w-full form_submit"
|
|
/>
|
|
}
|
|
.into_view()
|
|
}
|
|
|
|
fn text_area(
|
|
&self,
|
|
control: ControlRenderData<Self, TextAreaData>,
|
|
value_getter: Signal<<TextAreaData as ControlData>::ReturnType>,
|
|
value_setter: Box<dyn Fn(<TextAreaData as ControlData>::ReturnType)>,
|
|
validation_state: Signal<Result<(), String>>,
|
|
) -> View {
|
|
view! {
|
|
<div>
|
|
{move || format!("{:?}", validation_state.get())}
|
|
<textarea
|
|
id=&control.data.name
|
|
name=control.data.name
|
|
placeholder=control.data.placeholder
|
|
class="form_input"
|
|
prop:value=move || value_getter.get()
|
|
on:change=move |ev| {
|
|
value_setter(event_target_value(&ev));
|
|
}
|
|
/>
|
|
</div>
|
|
}
|
|
.into_view()
|
|
}
|
|
|
|
fn custom_component(&self, view: View) -> View {
|
|
view
|
|
}
|
|
}
|