generated from mitchell/rust_template
Conditional Rendering WORKS!
This commit is contained in:
parent
835271cd22
commit
da84bdbb27
@ -1,6 +1,9 @@
|
|||||||
use super::{BuilderFn, ControlRenderData};
|
use super::{BuilderFn, ControlRenderData, ShowWhenFn};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
|
use leptos::view;
|
||||||
use leptos::RwSignal;
|
use leptos::RwSignal;
|
||||||
|
use leptos::Show;
|
||||||
|
use leptos::Signal;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use web_sys::MouseEvent;
|
use web_sys::MouseEvent;
|
||||||
|
|
||||||
@ -36,9 +39,24 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
data: control.data,
|
data: control.data,
|
||||||
styles: control.styles,
|
styles: control.styles,
|
||||||
};
|
};
|
||||||
|
let show_when = control.show_when;
|
||||||
|
|
||||||
let render_fn = move |fs: &FD::Style, fd: RwSignal<FD>| {
|
let cx = self.cx.clone();
|
||||||
let view = fs.button(render_data, fd);
|
let render_fn = move |fs: Rc<FD::Style>, fd: RwSignal<FD>| {
|
||||||
|
let render_data = Rc::new(render_data);
|
||||||
|
// let cloned_fs = fs.clone();
|
||||||
|
let view = move || fs.clone().button(render_data.clone(), fd);
|
||||||
|
let view = match show_when {
|
||||||
|
Some(when) => {
|
||||||
|
let when = move || when(fd.into(), cx.clone());
|
||||||
|
view! {
|
||||||
|
<Show when=when>
|
||||||
|
{view.clone()}
|
||||||
|
</Show>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => view(),
|
||||||
|
};
|
||||||
(view, None)
|
(view, None)
|
||||||
};
|
};
|
||||||
self.render_fns.push(Box::new(render_fn));
|
self.render_fns.push(Box::new(render_fn));
|
||||||
@ -50,6 +68,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
pub struct ButtonBuilder<FD: FormToolData> {
|
pub struct ButtonBuilder<FD: FormToolData> {
|
||||||
pub(crate) styles: Vec<<FD::Style as FormStyle>::StylingAttributes>,
|
pub(crate) styles: Vec<<FD::Style as FormStyle>::StylingAttributes>,
|
||||||
pub(crate) data: ButtonData<FD>,
|
pub(crate) data: ButtonData<FD>,
|
||||||
|
pub(crate) show_when: Option<Box<dyn ShowWhenFn<FD, FD::Context>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData> ButtonBuilder<FD> {
|
impl<FD: FormToolData> ButtonBuilder<FD> {
|
||||||
@ -57,9 +76,21 @@ impl<FD: FormToolData> ButtonBuilder<FD> {
|
|||||||
ButtonBuilder {
|
ButtonBuilder {
|
||||||
styles: Vec::default(),
|
styles: Vec::default(),
|
||||||
data: ButtonData::default(),
|
data: ButtonData::default(),
|
||||||
|
show_when: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the function to decide when to render the control.
|
||||||
|
///
|
||||||
|
/// Validations for components that are not shown DO NOT run.
|
||||||
|
pub fn show_when(
|
||||||
|
mut self,
|
||||||
|
when: impl Fn(Signal<FD>, Rc<FD::Context>) -> bool + 'static,
|
||||||
|
) -> Self {
|
||||||
|
self.show_when = Some(Box::new(when));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn style(mut self, style: <FD::Style as FormStyle>::StylingAttributes) -> Self {
|
pub fn style(mut self, style: <FD::Style as FormStyle>::StylingAttributes) -> Self {
|
||||||
self.styles.push(style);
|
self.styles.push(style);
|
||||||
self
|
self
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData};
|
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct CheckboxData {
|
pub struct CheckboxData {
|
||||||
@ -13,9 +14,9 @@ impl ControlData for CheckboxData {
|
|||||||
|
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
_validation_state: Signal<Result<(), String>>,
|
_validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.checkbox(control, value_getter, value_setter)
|
fs.checkbox(control, value_getter, value_setter)
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
use super::ValidationCb;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use super::{ControlRenderData, ValidationCb};
|
||||||
use crate::styles::FormStyle;
|
use crate::styles::FormStyle;
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder};
|
use crate::{form::FormToolData, form_builder::FormBuilder};
|
||||||
use leptos::{CollectView, RwSignal};
|
use leptos::{CollectView, RwSignal};
|
||||||
@ -15,17 +17,20 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
self.validations.push(validation);
|
self.validations.push(validation);
|
||||||
}
|
}
|
||||||
|
|
||||||
let render_fn = move |fs: &FD::Style, fd: RwSignal<FD>| {
|
let render_fn = move |fs: Rc<FD::Style>, fd: RwSignal<FD>| {
|
||||||
let (views, validation_cbs): (Vec<_>, Vec<_>) = group_builder
|
let (views, validation_cbs): (Vec<_>, Vec<_>) = group_builder
|
||||||
.render_fns
|
.render_fns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r_fn| r_fn(fs, fd))
|
.map(|r_fn| r_fn(fs.clone(), fd))
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
let view = fs.group(super::ControlRenderData {
|
let render_data = Rc::new(ControlRenderData {
|
||||||
data: views.collect_view(),
|
data: views.collect_view(),
|
||||||
styles: group_builder.styles,
|
styles: group_builder.styles,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let view = fs.group(render_data.clone());
|
||||||
|
|
||||||
let validation_cb = move || {
|
let validation_cb = move || {
|
||||||
let mut success = true;
|
let mut success = true;
|
||||||
for validation in validation_cbs.iter().flatten() {
|
for validation in validation_cbs.iter().flatten() {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlRenderData, VanityControlBuilder, VanityControlData};
|
use super::{BuilderFn, ControlRenderData, VanityControlBuilder, VanityControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::View;
|
use leptos::View;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct HeadingData {
|
pub struct HeadingData {
|
||||||
@ -10,7 +11,7 @@ pub struct HeadingData {
|
|||||||
impl VanityControlData for HeadingData {
|
impl VanityControlData for HeadingData {
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
_value_getter: Option<leptos::prelude::Signal<String>>,
|
_value_getter: Option<leptos::prelude::Signal<String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.heading(control)
|
fs.heading(control)
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct HiddenData {
|
pub struct HiddenData {
|
||||||
@ -12,7 +13,7 @@ pub struct HiddenData {
|
|||||||
impl VanityControlData for HiddenData {
|
impl VanityControlData for HiddenData {
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Option<Signal<String>>,
|
value_getter: Option<Signal<String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.hidden(control, value_getter)
|
fs.hidden(control, value_getter)
|
||||||
|
|||||||
@ -26,8 +26,8 @@ pub trait UnparseFn<CR, FDT>: Fn(FDT) -> CR + 'static {}
|
|||||||
pub trait FieldGetter<FD, FDT>: Fn(FD) -> FDT + 'static {}
|
pub trait FieldGetter<FD, FDT>: Fn(FD) -> FDT + 'static {}
|
||||||
pub trait FieldSetter<FD, FDT>: Fn(&mut FD, FDT) + 'static {}
|
pub trait FieldSetter<FD, FDT>: Fn(&mut FD, FDT) + 'static {}
|
||||||
pub trait ShowWhenFn<FD: 'static, CX>: Fn(Signal<FD>, Rc<CX>) -> bool + 'static {}
|
pub trait ShowWhenFn<FD: 'static, CX>: Fn(Signal<FD>, Rc<CX>) -> bool + 'static {}
|
||||||
pub trait RenderFn<FS, FD>:
|
pub trait RenderFn<FS, FD: 'static>:
|
||||||
FnOnce(&FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
|
FnOnce(Rc<FS>, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ impl<CR, FDT, F> UnparseFn<CR, FDT> for F where F: Fn(FDT) -> CR + 'static {}
|
|||||||
impl<FD, FDT, F> FieldGetter<FD, FDT> for F where F: Fn(FD) -> FDT + 'static {}
|
impl<FD, FDT, F> FieldGetter<FD, FDT> for F where F: Fn(FD) -> FDT + 'static {}
|
||||||
impl<FD, FDT, F> FieldSetter<FD, FDT> for F where F: Fn(&mut FD, FDT) + 'static {}
|
impl<FD, FDT, F> FieldSetter<FD, FDT> for F where F: Fn(&mut FD, FDT) + 'static {}
|
||||||
impl<FD: 'static, CX, F> ShowWhenFn<FD, CX> for F where F: Fn(Signal<FD>, Rc<CX>) -> bool + 'static {}
|
impl<FD: 'static, CX, F> ShowWhenFn<FD, CX> for F where F: Fn(Signal<FD>, Rc<CX>) -> bool + 'static {}
|
||||||
impl<FS, FD, F> RenderFn<FS, FD> for F where
|
impl<FS, FD: 'static, F> RenderFn<FS, FD> for F where
|
||||||
F: FnOnce(&FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
|
F: FnOnce(Rc<FS>, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ pub trait VanityControlData: 'static {
|
|||||||
/// Builds the control, returning the [`View`] that was built.
|
/// Builds the control, returning the [`View`] that was built.
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Option<Signal<String>>,
|
value_getter: Option<Signal<String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
}
|
}
|
||||||
@ -64,9 +64,9 @@ pub trait ControlData: 'static {
|
|||||||
/// Builds the control, returning the [`View`] that was built.
|
/// Builds the control, returning the [`View`] that was built.
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct OutputData;
|
pub struct OutputData;
|
||||||
@ -10,7 +11,7 @@ pub struct OutputData;
|
|||||||
impl VanityControlData for OutputData {
|
impl VanityControlData for OutputData {
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Option<Signal<String>>,
|
value_getter: Option<Signal<String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.output(control, value_getter)
|
fs.output(control, value_getter)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct RadioButtonsData {
|
pub struct RadioButtonsData {
|
||||||
@ -14,9 +15,9 @@ impl ControlData for RadioButtonsData {
|
|||||||
|
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.radio_buttons(control, value_getter, value_setter, validation_state)
|
fs.radio_buttons(control, value_getter, value_setter, validation_state)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct SelectData {
|
pub struct SelectData {
|
||||||
@ -17,9 +18,9 @@ impl ControlData for SelectData {
|
|||||||
|
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.select(control, value_getter, value_setter, validation_state)
|
fs.select(control, value_getter, value_setter, validation_state)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData};
|
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
use std::ops::RangeInclusive;
|
use std::{ops::RangeInclusive, rc::Rc};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct SliderData {
|
pub struct SliderData {
|
||||||
@ -27,9 +27,9 @@ impl ControlData for SliderData {
|
|||||||
|
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.slider(control, value_getter, value_setter, validation_state)
|
fs.slider(control, value_getter, value_setter, validation_state)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlRenderData, VanityControlBuilder, VanityControlData};
|
use super::{BuilderFn, ControlRenderData, VanityControlBuilder, VanityControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{prelude::Signal, View};
|
use leptos::{prelude::Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct SpacerData {
|
pub struct SpacerData {
|
||||||
@ -10,7 +11,7 @@ pub struct SpacerData {
|
|||||||
impl VanityControlData for SpacerData {
|
impl VanityControlData for SpacerData {
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
_value_getter: Option<Signal<String>>,
|
_value_getter: Option<Signal<String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.spacer(control)
|
fs.spacer(control)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
use std::ops::RangeInclusive;
|
use std::{ops::RangeInclusive, rc::Rc};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct StepperData {
|
pub struct StepperData {
|
||||||
@ -17,9 +17,9 @@ impl ControlData for StepperData {
|
|||||||
|
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.stepper(control, value_getter, value_setter, validation_state)
|
fs.stepper(control, value_getter, value_setter, validation_state)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlRenderData, VanityControlBuilder, VanityControlData};
|
use super::{BuilderFn, ControlRenderData, VanityControlBuilder, VanityControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{prelude::Signal, View};
|
use leptos::{prelude::Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct SubmitData {
|
pub struct SubmitData {
|
||||||
@ -10,7 +11,7 @@ pub struct SubmitData {
|
|||||||
impl VanityControlData for SubmitData {
|
impl VanityControlData for SubmitData {
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
_value_getter: Option<Signal<String>>,
|
_value_getter: Option<Signal<String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.submit(control)
|
fs.submit(control)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct TextAreaData {
|
pub struct TextAreaData {
|
||||||
@ -13,9 +14,9 @@ impl ControlData for TextAreaData {
|
|||||||
|
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.text_area(control, value_getter, value_setter, validation_state)
|
fs.text_area(control, value_getter, value_setter, validation_state)
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
use super::{BuilderFn, ControlBuilder, ControlData, ControlRenderData, ValidatedControlData};
|
||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{Signal, View};
|
use leptos::{Signal, View};
|
||||||
@ -28,9 +30,9 @@ impl ControlData for TextInputData {
|
|||||||
|
|
||||||
fn build_control<FS: FormStyle>(
|
fn build_control<FS: FormStyle>(
|
||||||
fs: &FS,
|
fs: &FS,
|
||||||
control: ControlRenderData<FS, Self>,
|
control: Rc<ControlRenderData<FS, Self>>,
|
||||||
value_getter: Signal<Self::ReturnType>,
|
value_getter: Signal<Self::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(Self::ReturnType)>,
|
value_setter: Rc<dyn Fn(Self::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
fs.text_input(control, value_getter, value_setter, validation_state)
|
fs.text_input(control, value_getter, value_setter, validation_state)
|
||||||
|
|||||||
@ -93,19 +93,21 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
} = vanity_control.build();
|
} = vanity_control.build();
|
||||||
|
|
||||||
let cx = self.cx.clone();
|
let cx = self.cx.clone();
|
||||||
let render_fn = move |fs: &FD::Style, fd: RwSignal<FD>| {
|
let render_fn = move |fs: Rc<FD::Style>, fd: RwSignal<FD>| {
|
||||||
|
let render_data = Rc::new(render_data);
|
||||||
let value_getter = getter.map(|getter| (move || getter(fd.get())).into_signal());
|
let value_getter = getter.map(|getter| (move || getter(fd.get())).into_signal());
|
||||||
let view = VanityControlData::build_control(fs, render_data, value_getter);
|
let view =
|
||||||
|
move || VanityControlData::build_control(&*fs, render_data.clone(), value_getter);
|
||||||
let view = match show_when {
|
let view = match show_when {
|
||||||
Some(when) => {
|
Some(when) => {
|
||||||
let when = move || when(fd.into(), cx.clone());
|
let when = move || when(fd.into(), cx.clone());
|
||||||
view! {
|
view! {
|
||||||
<Show when=when>
|
<Show when=when>
|
||||||
{&view}
|
{view.clone()}
|
||||||
</Show>
|
</Show>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => view,
|
None => view(),
|
||||||
};
|
};
|
||||||
(view, None)
|
(view, None)
|
||||||
};
|
};
|
||||||
@ -128,7 +130,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let cx = self.cx.clone();
|
let cx = self.cx.clone();
|
||||||
let render_fn = move |fs: &FD::Style, fd: RwSignal<FD>| {
|
let render_fn = move |fs: Rc<FD::Style>, fd: RwSignal<FD>| {
|
||||||
let (view, cb) = Self::build_control_view(fd, fs, built_control_data, cx);
|
let (view, cb) = Self::build_control_view(fd, fs, built_control_data, cx);
|
||||||
(view, Some(cb))
|
(view, Some(cb))
|
||||||
};
|
};
|
||||||
@ -138,7 +140,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
|
|
||||||
fn build_control_view<C: ControlData, FDT: 'static>(
|
fn build_control_view<C: ControlData, FDT: 'static>(
|
||||||
fd: RwSignal<FD>,
|
fd: RwSignal<FD>,
|
||||||
fs: &FD::Style,
|
fs: Rc<FD::Style>,
|
||||||
control_data: BuiltControlData<FD, C, FDT>,
|
control_data: BuiltControlData<FD, C, FDT>,
|
||||||
cx: Rc<FD::Context>,
|
cx: Rc<FD::Context>,
|
||||||
) -> (View, Box<dyn ValidationCb>) {
|
) -> (View, Box<dyn ValidationCb>) {
|
||||||
@ -152,6 +154,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
show_when,
|
show_when,
|
||||||
} = control_data;
|
} = control_data;
|
||||||
|
|
||||||
|
let render_data = Rc::new(render_data);
|
||||||
let (validation_signal, validation_signal_set) = create_signal(Ok(()));
|
let (validation_signal, validation_signal_set) = create_signal(Ok(()));
|
||||||
let validation_fn_clone = validation_fn.clone();
|
let validation_fn_clone = validation_fn.clone();
|
||||||
let value_getter = move || {
|
let value_getter = move || {
|
||||||
@ -194,23 +197,25 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
fd,
|
fd,
|
||||||
);
|
);
|
||||||
|
|
||||||
let view = C::build_control(
|
let view = move || {
|
||||||
fs,
|
C::build_control(
|
||||||
render_data,
|
&*fs,
|
||||||
value_getter,
|
render_data.clone(),
|
||||||
value_setter,
|
value_getter,
|
||||||
validation_signal.into(),
|
value_setter.clone(),
|
||||||
);
|
validation_signal.into(),
|
||||||
|
)
|
||||||
|
};
|
||||||
let view = match show_when {
|
let view = match show_when {
|
||||||
Some(when) => {
|
Some(when) => {
|
||||||
let when = move || when(fd.into(), cx.clone());
|
let when = move || when(fd.into(), cx.clone());
|
||||||
view! {
|
view! {
|
||||||
<Show when=when>
|
<Show when=when>
|
||||||
{&view}
|
{view.clone()}
|
||||||
</Show>
|
</Show>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => view,
|
None => view(),
|
||||||
};
|
};
|
||||||
(view, validation_cb)
|
(view, validation_cb)
|
||||||
}
|
}
|
||||||
@ -221,7 +226,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
parse_fn: Box<dyn ParseFn<CRT, FDT>>,
|
parse_fn: Box<dyn ParseFn<CRT, FDT>>,
|
||||||
setter: Rc<dyn FieldSetter<FD, FDT>>,
|
setter: Rc<dyn FieldSetter<FD, FDT>>,
|
||||||
fd: RwSignal<FD>,
|
fd: RwSignal<FD>,
|
||||||
) -> Box<dyn Fn(CRT) + 'static> {
|
) -> Rc<dyn Fn(CRT) + 'static> {
|
||||||
let value_setter = move |value| {
|
let value_setter = move |value| {
|
||||||
let parsed = match parse_fn(value) {
|
let parsed = match parse_fn(value) {
|
||||||
Ok(p) => {
|
Ok(p) => {
|
||||||
@ -242,7 +247,7 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
// run validation
|
// run validation
|
||||||
(validation_cb)();
|
(validation_cb)();
|
||||||
};
|
};
|
||||||
Box::new(value_setter)
|
Rc::new(value_setter)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: impl build_formless function that builds the form without adding
|
// TODO: impl build_formless function that builds the form without adding
|
||||||
@ -260,11 +265,12 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
From<FormData>,
|
From<FormData>,
|
||||||
{
|
{
|
||||||
let fd = create_rw_signal(fd);
|
let fd = create_rw_signal(fd);
|
||||||
|
let fs = Rc::new(fs);
|
||||||
|
|
||||||
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
|
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
|
||||||
.render_fns
|
.render_fns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r_fn| r_fn(&fs, fd))
|
.map(|r_fn| r_fn(fs.clone(), fd))
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
let elements = fs.form_frame(ControlRenderData {
|
let elements = fs.form_frame(ControlRenderData {
|
||||||
@ -310,11 +316,12 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
From<FormData>,
|
From<FormData>,
|
||||||
{
|
{
|
||||||
let fd = create_rw_signal(fd);
|
let fd = create_rw_signal(fd);
|
||||||
|
let fs = Rc::new(fs);
|
||||||
|
|
||||||
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
|
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
|
||||||
.render_fns
|
.render_fns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r_fn| r_fn(&fs, fd))
|
.map(|r_fn| r_fn(fs.clone(), fd))
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
let elements = fs.form_frame(ControlRenderData {
|
let elements = fs.form_frame(ControlRenderData {
|
||||||
@ -349,11 +356,12 @@ impl<FD: FormToolData> FormBuilder<FD> {
|
|||||||
|
|
||||||
pub(crate) fn build_plain_form(self, url: String, fd: FD, fs: FD::Style) -> Form<FD> {
|
pub(crate) fn build_plain_form(self, url: String, fd: FD, fs: FD::Style) -> Form<FD> {
|
||||||
let fd = create_rw_signal(fd);
|
let fd = create_rw_signal(fd);
|
||||||
|
let fs = Rc::new(fs);
|
||||||
|
|
||||||
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
|
let (views, validation_cbs): (Vec<_>, Vec<_>) = self
|
||||||
.render_fns
|
.render_fns
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|r_fn| r_fn(&fs, fd))
|
.map(|r_fn| r_fn(fs.clone(), fd))
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
let elements = fs.form_frame(ControlRenderData {
|
let elements = fs.form_frame(ControlRenderData {
|
||||||
|
|||||||
@ -2,7 +2,8 @@ use super::FormStyle;
|
|||||||
use crate::{
|
use crate::{
|
||||||
controls::{
|
controls::{
|
||||||
button::ButtonData, checkbox::CheckboxData, heading::HeadingData, hidden::HiddenData,
|
button::ButtonData, checkbox::CheckboxData, heading::HeadingData, hidden::HiddenData,
|
||||||
output::OutputData, select::SelectData, spacer::SpacerData, submit::SubmitData,
|
output::OutputData, radio_buttons::RadioButtonsData, select::SelectData,
|
||||||
|
slider::SliderData, spacer::SpacerData, stepper::StepperData, submit::SubmitData,
|
||||||
text_area::TextAreaData, text_input::TextInputData, ControlData, ControlRenderData,
|
text_area::TextAreaData, text_input::TextInputData, ControlData, ControlRenderData,
|
||||||
},
|
},
|
||||||
FormToolData,
|
FormToolData,
|
||||||
@ -25,22 +26,22 @@ impl FormStyle for GridFormStyle {
|
|||||||
view! { <div class="form_grid">{form.data}</div> }.into_view()
|
view! { <div class="form_grid">{form.data}</div> }.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View {
|
fn heading(&self, control: Rc<ControlRenderData<Self, HeadingData>>) -> View {
|
||||||
view! { <h2 class="form_heading">{&control.data.title}</h2> }.into_view()
|
view! { <h2 class="form_heading">{&control.data.title}</h2> }.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_input(
|
fn text_input(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, TextInputData>,
|
control: Rc<ControlRenderData<Self, TextInputData>>,
|
||||||
value_getter: Signal<<TextInputData as ControlData>::ReturnType>,
|
value_getter: Signal<<TextInputData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<TextInputData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<TextInputData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
// TODO: extract this to a common thing
|
// TODO: extract this to a common thing
|
||||||
let mut width = 1;
|
let mut width = 1;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +56,8 @@ impl FormStyle for GridFormStyle {
|
|||||||
<input
|
<input
|
||||||
type=control.data.input_type
|
type=control.data.input_type
|
||||||
id=&control.data.name
|
id=&control.data.name
|
||||||
name=control.data.name
|
name=&control.data.name
|
||||||
placeholder=control.data.placeholder
|
placeholder=control.data.placeholder.as_ref()
|
||||||
prop:value=move || value_getter.get()
|
prop:value=move || value_getter.get()
|
||||||
on:focusout=move |ev| {
|
on:focusout=move |ev| {
|
||||||
value_setter(event_target_value(&ev));
|
value_setter(event_target_value(&ev));
|
||||||
@ -72,26 +73,28 @@ impl FormStyle for GridFormStyle {
|
|||||||
|
|
||||||
fn select(
|
fn select(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, SelectData>,
|
control: Rc<ControlRenderData<Self, SelectData>>,
|
||||||
value_getter: Signal<<SelectData as ControlData>::ReturnType>,
|
value_getter: Signal<<SelectData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<SelectData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
let mut width = 1;
|
let mut width = 1;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let options_view = control
|
let options_view = control
|
||||||
.data
|
.data
|
||||||
.options
|
.options
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|(display, value)| {
|
.map(|(display, value)| {
|
||||||
|
let display = display.clone();
|
||||||
|
let value = value.clone();
|
||||||
view! {
|
view! {
|
||||||
<option value=value.clone() selected=move || { value_getter.get() == *value }>
|
<option value=value.clone() selected=move || { value_getter.get() == *value }>
|
||||||
{display.clone()}
|
{display}
|
||||||
</option>
|
</option>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -107,7 +110,7 @@ impl FormStyle for GridFormStyle {
|
|||||||
</div>
|
</div>
|
||||||
<select
|
<select
|
||||||
id=&control.data.name
|
id=&control.data.name
|
||||||
name=control.data.name
|
name=&control.data.name
|
||||||
class="form_input"
|
class="form_input"
|
||||||
on:input=move |ev| {
|
on:input=move |ev| {
|
||||||
value_setter(event_target_value(&ev));
|
value_setter(event_target_value(&ev));
|
||||||
@ -121,15 +124,15 @@ impl FormStyle for GridFormStyle {
|
|||||||
.into_view()
|
.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View {
|
fn submit(&self, control: Rc<ControlRenderData<Self, SubmitData>>) -> View {
|
||||||
view! { <input type="submit" value=control.data.text class="form_submit"/> }.into_view()
|
view! { <input type="submit" value=&control.data.text class="form_submit"/> }.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn text_area(
|
fn text_area(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, TextAreaData>,
|
control: Rc<ControlRenderData<Self, TextAreaData>>,
|
||||||
value_getter: Signal<<TextAreaData as ControlData>::ReturnType>,
|
value_getter: Signal<<TextAreaData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<TextAreaData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<TextAreaData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
view! {
|
view! {
|
||||||
@ -137,8 +140,8 @@ impl FormStyle for GridFormStyle {
|
|||||||
{move || format!("{:?}", validation_state.get())}
|
{move || format!("{:?}", validation_state.get())}
|
||||||
<textarea
|
<textarea
|
||||||
id=&control.data.name
|
id=&control.data.name
|
||||||
name=control.data.name
|
name=&control.data.name
|
||||||
placeholder=control.data.placeholder
|
placeholder=control.data.placeholder.as_ref()
|
||||||
class="form_input"
|
class="form_input"
|
||||||
prop:value=move || value_getter.get()
|
prop:value=move || value_getter.get()
|
||||||
on:change=move |ev| {
|
on:change=move |ev| {
|
||||||
@ -158,29 +161,25 @@ impl FormStyle for GridFormStyle {
|
|||||||
|
|
||||||
fn hidden(
|
fn hidden(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, HiddenData>,
|
control: Rc<ControlRenderData<Self, HiddenData>>,
|
||||||
value_getter: Option<Signal<String>>,
|
value_getter: Option<Signal<String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
let value_getter = move || value_getter.map(|g| g.get());
|
let value_getter = move || value_getter.map(|g| g.get());
|
||||||
view! { <input name=control.data.name prop:value=value_getter style="visibility: hidden"/> }
|
view! { <input name=&control.data.name prop:value=value_getter style="visibility: hidden"/> }
|
||||||
.into_view()
|
.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn radio_buttons(
|
fn radio_buttons(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, crate::controls::radio_buttons::RadioButtonsData>,
|
control: Rc<ControlRenderData<Self, RadioButtonsData>>,
|
||||||
value_getter: Signal<
|
value_getter: Signal<<RadioButtonsData as ControlData>::ReturnType>,
|
||||||
<crate::controls::radio_buttons::RadioButtonsData as ControlData>::ReturnType,
|
value_setter: Rc<dyn Fn(<RadioButtonsData as ControlData>::ReturnType)>,
|
||||||
>,
|
|
||||||
value_setter: Box<
|
|
||||||
dyn Fn(<crate::controls::radio_buttons::RadioButtonsData as ControlData>::ReturnType),
|
|
||||||
>,
|
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
let mut width = 1;
|
let mut width = 1;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +187,7 @@ impl FormStyle for GridFormStyle {
|
|||||||
let buttons_view = control
|
let buttons_view = control
|
||||||
.data
|
.data
|
||||||
.options
|
.options
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|o| {
|
.map(|o| {
|
||||||
let value_setter = value_setter.clone();
|
let value_setter = value_setter.clone();
|
||||||
let o_clone1 = o.clone();
|
let o_clone1 = o.clone();
|
||||||
@ -209,7 +208,7 @@ impl FormStyle for GridFormStyle {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<label for=&o>{&o}</label>
|
<label for=o>{o}</label>
|
||||||
<br/>
|
<br/>
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -236,14 +235,14 @@ impl FormStyle for GridFormStyle {
|
|||||||
|
|
||||||
fn checkbox(
|
fn checkbox(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, CheckboxData>,
|
control: Rc<ControlRenderData<Self, CheckboxData>>,
|
||||||
value_getter: Signal<<CheckboxData as ControlData>::ReturnType>,
|
value_getter: Signal<<CheckboxData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<CheckboxData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<CheckboxData as ControlData>::ReturnType)>,
|
||||||
) -> View {
|
) -> View {
|
||||||
let mut width = 1;
|
let mut width = 1;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +263,7 @@ impl FormStyle for GridFormStyle {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<span>{control.data.label}</span>
|
<span>{control.data.label.as_ref()}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -273,17 +272,15 @@ impl FormStyle for GridFormStyle {
|
|||||||
|
|
||||||
fn stepper(
|
fn stepper(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, crate::controls::stepper::StepperData>,
|
control: Rc<ControlRenderData<Self, StepperData>>,
|
||||||
value_getter: Signal<<crate::controls::stepper::StepperData as ControlData>::ReturnType>,
|
value_getter: Signal<<StepperData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<
|
value_setter: Rc<dyn Fn(<StepperData as ControlData>::ReturnType)>,
|
||||||
dyn Fn(<crate::controls::stepper::StepperData as ControlData>::ReturnType),
|
|
||||||
>,
|
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
let mut width = 1;
|
let mut width = 1;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +311,7 @@ impl FormStyle for GridFormStyle {
|
|||||||
|
|
||||||
fn output(
|
fn output(
|
||||||
&self,
|
&self,
|
||||||
_control: ControlRenderData<Self, OutputData>,
|
_control: Rc<ControlRenderData<Self, OutputData>>,
|
||||||
value_getter: Option<Signal<String>>,
|
value_getter: Option<Signal<String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
view! { <div>{move || value_getter.map(|g| g.get())}</div> }.into_view()
|
view! { <div>{move || value_getter.map(|g| g.get())}</div> }.into_view()
|
||||||
@ -322,15 +319,15 @@ impl FormStyle for GridFormStyle {
|
|||||||
|
|
||||||
fn slider(
|
fn slider(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, crate::controls::slider::SliderData>,
|
control: Rc<ControlRenderData<Self, SliderData>>,
|
||||||
value_getter: Signal<<crate::controls::slider::SliderData as ControlData>::ReturnType>,
|
value_getter: Signal<<SliderData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<crate::controls::slider::SliderData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<SliderData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View {
|
) -> View {
|
||||||
let mut width = 1;
|
let mut width = 1;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,13 +362,13 @@ impl FormStyle for GridFormStyle {
|
|||||||
|
|
||||||
fn button<FD: FormToolData>(
|
fn button<FD: FormToolData>(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, ButtonData<FD>>,
|
control: Rc<ControlRenderData<Self, ButtonData<FD>>>,
|
||||||
data_signal: RwSignal<FD>,
|
data_signal: RwSignal<FD>,
|
||||||
) -> View {
|
) -> View {
|
||||||
let mut width = 1;
|
let mut width = 1;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,37 +386,37 @@ impl FormStyle for GridFormStyle {
|
|||||||
on:click=on_click
|
on:click=on_click
|
||||||
style:grid-column=format!("span {}", width)
|
style:grid-column=format!("span {}", width)
|
||||||
>
|
>
|
||||||
{control.data.text}
|
{&control.data.text}
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
.into_view()
|
.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn group(&self, group: ControlRenderData<Self, View>) -> View {
|
fn group(&self, group: Rc<ControlRenderData<Self, View>>) -> View {
|
||||||
let mut width = 12;
|
let mut width = 12;
|
||||||
for style in group.styles {
|
for style in group.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class="form_group form_grid" style:grid-column=format!("span {}", width)>
|
<div class="form_group form_grid" style:grid-column=format!("span {}", width)>
|
||||||
{group.data}
|
{&group.data}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
.into_view()
|
.into_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spacer(&self, control: ControlRenderData<Self, SpacerData>) -> View {
|
fn spacer(&self, control: Rc<ControlRenderData<Self, SpacerData>>) -> View {
|
||||||
let mut width = 12;
|
let mut width = 12;
|
||||||
for style in control.styles {
|
for style in control.styles.iter() {
|
||||||
match style {
|
match style {
|
||||||
GridFormStylingAttributes::Width(w) => width = w,
|
GridFormStylingAttributes::Width(w) => width = *w,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view! { <div style:grid-column=format!("span {}", width) style:height=control.data.height></div> }
|
view! { <div style:grid-column=format!("span {}", width) style:height=control.data.height.as_ref()></div> }
|
||||||
.into_view()
|
.into_view()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
mod grid_form;
|
mod grid_form;
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
controls::{
|
controls::{
|
||||||
button::ButtonData, checkbox::CheckboxData, heading::HeadingData, hidden::HiddenData,
|
button::ButtonData, checkbox::CheckboxData, heading::HeadingData, hidden::HiddenData,
|
||||||
@ -24,72 +26,72 @@ pub trait FormStyle: 'static {
|
|||||||
/// Do NOT wrap it in an actual `form` element; any
|
/// Do NOT wrap it in an actual `form` element; any
|
||||||
/// wrapping should be done with `div` or similar elements.
|
/// wrapping should be done with `div` or similar elements.
|
||||||
fn form_frame(&self, form: ControlRenderData<Self, View>) -> View;
|
fn form_frame(&self, form: ControlRenderData<Self, View>) -> View;
|
||||||
fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View;
|
fn heading(&self, control: Rc<ControlRenderData<Self, HeadingData>>) -> View;
|
||||||
fn hidden(
|
fn hidden(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, HiddenData>,
|
control: Rc<ControlRenderData<Self, HiddenData>>,
|
||||||
value_getter: Option<Signal<String>>,
|
value_getter: Option<Signal<String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn text_input(
|
fn text_input(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, TextInputData>,
|
control: Rc<ControlRenderData<Self, TextInputData>>,
|
||||||
value_getter: Signal<<TextInputData as ControlData>::ReturnType>,
|
value_getter: Signal<<TextInputData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<TextInputData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<TextInputData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn text_area(
|
fn text_area(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, TextAreaData>,
|
control: Rc<ControlRenderData<Self, TextAreaData>>,
|
||||||
value_getter: Signal<<TextAreaData as ControlData>::ReturnType>,
|
value_getter: Signal<<TextAreaData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<TextAreaData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<TextAreaData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn radio_buttons(
|
fn radio_buttons(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, RadioButtonsData>,
|
control: Rc<ControlRenderData<Self, RadioButtonsData>>,
|
||||||
value_getter: Signal<<RadioButtonsData as ControlData>::ReturnType>,
|
value_getter: Signal<<RadioButtonsData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<RadioButtonsData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<RadioButtonsData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn select(
|
fn select(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, SelectData>,
|
control: Rc<ControlRenderData<Self, SelectData>>,
|
||||||
value_getter: Signal<<SelectData as ControlData>::ReturnType>,
|
value_getter: Signal<<SelectData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<SelectData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn button<FD: FormToolData>(
|
fn button<FD: FormToolData>(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, ButtonData<FD>>,
|
control: Rc<ControlRenderData<Self, ButtonData<FD>>>,
|
||||||
data_signal: RwSignal<FD>,
|
data_signal: RwSignal<FD>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn checkbox(
|
fn checkbox(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, CheckboxData>,
|
control: Rc<ControlRenderData<Self, CheckboxData>>,
|
||||||
value_getter: Signal<<CheckboxData as ControlData>::ReturnType>,
|
value_getter: Signal<<CheckboxData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<CheckboxData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<CheckboxData as ControlData>::ReturnType)>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn stepper(
|
fn stepper(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, StepperData>,
|
control: Rc<ControlRenderData<Self, StepperData>>,
|
||||||
value_getter: Signal<<StepperData as ControlData>::ReturnType>,
|
value_getter: Signal<<StepperData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<StepperData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<StepperData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn output(
|
fn output(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, OutputData>,
|
control: Rc<ControlRenderData<Self, OutputData>>,
|
||||||
value_getter: Option<Signal<String>>,
|
value_getter: Option<Signal<String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn slider(
|
fn slider(
|
||||||
&self,
|
&self,
|
||||||
control: ControlRenderData<Self, SliderData>,
|
control: Rc<ControlRenderData<Self, SliderData>>,
|
||||||
value_getter: Signal<<SliderData as ControlData>::ReturnType>,
|
value_getter: Signal<<SliderData as ControlData>::ReturnType>,
|
||||||
value_setter: Box<dyn Fn(<SliderData as ControlData>::ReturnType)>,
|
value_setter: Rc<dyn Fn(<SliderData as ControlData>::ReturnType)>,
|
||||||
validation_state: Signal<Result<(), String>>,
|
validation_state: Signal<Result<(), String>>,
|
||||||
) -> View;
|
) -> View;
|
||||||
fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View;
|
fn submit(&self, control: Rc<ControlRenderData<Self, SubmitData>>) -> View;
|
||||||
fn custom_component(&self, view: View) -> View;
|
fn custom_component(&self, view: View) -> View;
|
||||||
fn group(&self, group: ControlRenderData<Self, View>) -> View;
|
fn group(&self, group: Rc<ControlRenderData<Self, View>>) -> View;
|
||||||
fn spacer(&self, control: ControlRenderData<Self, SpacerData>) -> View;
|
fn spacer(&self, control: Rc<ControlRenderData<Self, SpacerData>>) -> View;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user