remove fd and fs from builder

This commit is contained in:
Mitchell Marino 2024-06-12 16:02:43 -05:00
parent a39f2ce664
commit 115ff1abde
5 changed files with 31 additions and 35 deletions

View File

@ -4,11 +4,19 @@ use leptos::RwSignal;
use std::rc::Rc; use std::rc::Rc;
use web_sys::MouseEvent; use web_sys::MouseEvent;
#[derive(Default, Clone)] #[derive(Clone)]
pub struct ButtonData<FD: FormToolData> { pub struct ButtonData<FD: FormToolData> {
pub(crate) text: String, pub(crate) text: String,
pub(crate) action: Option<Rc<dyn Fn(MouseEvent, &mut FD)>>, pub(crate) action: Option<Rc<dyn Fn(MouseEvent, &mut FD)>>,
} }
impl<FD: FormToolData> Default for ButtonData<FD> {
fn default() -> Self {
ButtonData {
text: String::default(),
action: None,
}
}
}
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub fn button( pub fn button(

View File

@ -4,9 +4,8 @@ use leptos::{CollectView, RwSignal};
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub fn group(mut self, builder: impl Fn(FormBuilder<FD, FS>) -> FormBuilder<FD, FS>) -> Self { pub fn group(mut self, builder: impl Fn(FormBuilder<FD, FS>) -> FormBuilder<FD, FS>) -> Self {
let mut group_builder = FormBuilder::new_group(self.fd, self.fs); let mut group_builder = FormBuilder::new();
group_builder = builder(group_builder); group_builder = builder(group_builder);
self.fs = group_builder.fs; // take the style back
for validation in group_builder.validations { for validation in group_builder.validations {
self.validations.push(validation); self.validations.push(validation);

View File

@ -78,7 +78,7 @@ impl<FD: FormToolData> IntoView for Form<FD> {
/// ///
/// This trait defines a function that can be used to build all the data needed /// This trait defines a function that can be used to build all the data needed
/// to physically lay out a form, and how that data should be parsed and validated. /// to physically lay out a form, and how that data should be parsed and validated.
pub trait FormToolData: Default + Clone + 'static { pub trait FormToolData: Clone + 'static {
type Style: FormStyle; type Style: FormStyle;
/// Defines how the form should be layed out and how the data should be parsed and validated. /// Defines how the form should be layed out and how the data should be parsed and validated.
@ -97,9 +97,9 @@ pub trait FormToolData: Default + Clone + 'static {
/// component. Call [`get_action_form`]\() to get the /// component. Call [`get_action_form`]\() to get the
/// [`ActionForm`](leptos_router::ActionForm) version. /// [`ActionForm`](leptos_router::ActionForm) version.
fn get_form(self, action: impl ToString, style: Self::Style) -> Form<Self> { fn get_form(self, action: impl ToString, style: Self::Style) -> Form<Self> {
let builder = FormBuilder::new(self, style); let builder = FormBuilder::new();
let builder = Self::build_form(builder); let builder = Self::build_form(builder);
builder.build_plain_form(action.to_string()) builder.build_plain_form(action.to_string(), self, style)
} }
/// Constructs a [`Form`] for this [`FormToolData`] type. /// Constructs a [`Form`] for this [`FormToolData`] type.
@ -118,9 +118,9 @@ pub trait FormToolData: Default + Clone + 'static {
<<ServFn::Client as Client<ServFn::Error>>::Request as ClientReq<ServFn::Error>>::FormData: <<ServFn::Client as Client<ServFn::Error>>::Request as ClientReq<ServFn::Error>>::FormData:
From<FormData>, From<FormData>,
{ {
let builder = FormBuilder::new(self, style); let builder = FormBuilder::new();
let builder = Self::build_form(builder); let builder = Self::build_form(builder);
builder.build_action_form(action) builder.build_action_form(action, self, style)
} }
/// Gets a [`Validator`] for this [`ToolFormData`]. /// Gets a [`Validator`] for this [`ToolFormData`].
@ -132,7 +132,7 @@ pub trait FormToolData: Default + Clone + 'static {
/// However, the code to render the views are not configured out, it /// However, the code to render the views are not configured out, it
/// simply doesn't run, so the view needs to compile even on the server. /// simply doesn't run, so the view needs to compile even on the server.
fn get_validator() -> FormValidator<Self> { fn get_validator() -> FormValidator<Self> {
let builder = FormBuilder::new(Self::default(), Self::Style::default()); let builder = FormBuilder::new();
let builder = Self::build_form(builder); let builder = Self::build_form(builder);
builder.validator() builder.validator()
} }

View File

@ -20,10 +20,6 @@ use web_sys::{FormData, SubmitEvent};
/// ///
/// This builder allows you to specify what components should make up the form. /// This builder allows you to specify what components should make up the form.
pub struct FormBuilder<FD: FormToolData, FS: FormStyle> { pub struct FormBuilder<FD: FormToolData, FS: FormStyle> {
/// The [`ToolFormData`] signal.
pub(crate) fd: RwSignal<FD>,
/// The [`FormStyle`].
pub(crate) fs: FS,
/// The list of [`ValidationFn`]s. /// The list of [`ValidationFn`]s.
pub(crate) validations: Vec<Rc<dyn ValidationFn<FD>>>, pub(crate) validations: Vec<Rc<dyn ValidationFn<FD>>>,
/// The list of functions that will render the form. /// The list of functions that will render the form.
@ -34,21 +30,8 @@ pub struct FormBuilder<FD: FormToolData, FS: FormStyle> {
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
/// Creates a new [`FormBuilder`] /// Creates a new [`FormBuilder`]
pub(crate) fn new(starting_data: FD, form_style: FS) -> FormBuilder<FD, FS> { pub(crate) fn new() -> FormBuilder<FD, FS> {
let fd = create_rw_signal(starting_data);
FormBuilder { FormBuilder {
fd,
fs: form_style,
validations: Vec::new(),
render_fns: Vec::new(),
styles: Vec::new(),
}
}
pub(crate) fn new_group(fd: RwSignal<FD>, fs: FS) -> FormBuilder<FD, FS> {
FormBuilder {
fd,
fs,
validations: Vec::new(), validations: Vec::new(),
render_fns: Vec::new(), render_fns: Vec::new(),
styles: Vec::new(), styles: Vec::new(),
@ -232,19 +215,23 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
pub(crate) fn build_action_form<ServFn>( pub(crate) fn build_action_form<ServFn>(
self, self,
action: Action<ServFn, Result<ServFn::Output, ServerFnError<ServFn::Error>>>, action: Action<ServFn, Result<ServFn::Output, ServerFnError<ServFn::Error>>>,
fd: FD,
fs: FS,
) -> Form<FD> ) -> Form<FD>
where where
ServFn: DeserializeOwned + ServerFn<InputEncoding = PostUrl> + 'static, ServFn: DeserializeOwned + ServerFn<InputEncoding = PostUrl> + 'static,
<<ServFn::Client as Client<ServFn::Error>>::Request as ClientReq<ServFn::Error>>::FormData: <<ServFn::Client as Client<ServFn::Error>>::Request as ClientReq<ServFn::Error>>::FormData:
From<FormData>, From<FormData>,
{ {
let fd = create_rw_signal(fd);
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(&self.fs, self.fd)) .map(|r_fn| r_fn(&fs, fd))
.unzip(); .unzip();
let elements = self.fs.form_frame(views.into_view(), self.styles); let elements = fs.form_frame(views.into_view(), self.styles);
let on_submit = move |ev: SubmitEvent| { let on_submit = move |ev: SubmitEvent| {
let mut failed = false; let mut failed = false;
@ -265,20 +252,22 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
}; };
Form { Form {
fd: self.fd, fd,
validations: self.validations, validations: self.validations,
view, view,
} }
} }
pub(crate) fn build_plain_form(self, url: String) -> Form<FD> { pub(crate) fn build_plain_form(self, url: String, fd: FD, fs: FS) -> Form<FD> {
let fd = create_rw_signal(fd);
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(&self.fs, self.fd)) .map(|r_fn| r_fn(&fs, fd))
.unzip(); .unzip();
let elements = self.fs.form_frame(views.into_view(), self.styles); let elements = fs.form_frame(views.into_view(), self.styles);
let on_submit = move |ev: SubmitEvent| { let on_submit = move |ev: SubmitEvent| {
let mut failed = false; let mut failed = false;
@ -299,7 +288,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
}; };
Form { Form {
fd: self.fd, fd,
validations: self.validations, validations: self.validations,
view, view,
} }

View File

@ -13,7 +13,7 @@ use leptos::{RwSignal, Signal, View};
pub use grid_form::{GridFormStyle, GridFormStylingAttributes}; pub use grid_form::{GridFormStyle, GridFormStylingAttributes};
pub trait FormStyle: Default + 'static { pub trait FormStyle: 'static {
type StylingAttributes; type StylingAttributes;
/// Render any containing components for the form. /// Render any containing components for the form.