generated from mitchell/rust_template
add context
This commit is contained in:
parent
bd73591b9f
commit
4c6b6fa920
@ -20,7 +20,7 @@ impl<FD: FormToolData> Default for ButtonData<FD> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn button(
|
pub fn button(
|
||||||
mut self,
|
mut self,
|
||||||
builder: impl Fn(ButtonBuilder<FD, FS>) -> ButtonBuilder<FD, FS>,
|
builder: impl Fn(ButtonBuilder<FD, FS>) -> ButtonBuilder<FD, FS>,
|
||||||
|
|||||||
@ -23,7 +23,7 @@ impl ControlData for CheckboxData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn checkbox<FDT: Clone + PartialEq + 'static>(
|
pub fn checkbox<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use super::{ControlBuilder, ControlData};
|
use super::{ControlBuilder, ControlData};
|
||||||
use crate::{styles::FormStyle, FormBuilder, FormToolData};
|
use crate::{styles::FormStyle, FormBuilder, FormToolData};
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn custom<CC: ControlData, FDT: Clone + PartialEq + 'static>(
|
pub fn custom<CC: ControlData, FDT: Clone + PartialEq + 'static>(
|
||||||
mut self,
|
mut self,
|
||||||
control_data: CC,
|
control_data: CC,
|
||||||
|
|||||||
@ -2,11 +2,17 @@ use super::ValidationCb;
|
|||||||
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
use crate::{form::FormToolData, form_builder::FormBuilder, styles::FormStyle};
|
||||||
use leptos::{CollectView, RwSignal};
|
use leptos::{CollectView, RwSignal};
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn group(mut self, builder: impl Fn(FormBuilder<FD, FS>) -> FormBuilder<FD, FS>) -> Self {
|
pub fn group(
|
||||||
let mut group_builder = FormBuilder::new();
|
mut self,
|
||||||
|
builder: impl Fn(FormBuilder<FD, FS, CX>) -> FormBuilder<FD, FS, CX>,
|
||||||
|
) -> Self {
|
||||||
|
let mut group_builder = FormBuilder::new(self.cx);
|
||||||
group_builder = builder(group_builder);
|
group_builder = builder(group_builder);
|
||||||
|
|
||||||
|
// Take context back
|
||||||
|
self.cx = group_builder.cx;
|
||||||
|
|
||||||
for validation in group_builder.validations {
|
for validation in group_builder.validations {
|
||||||
self.validations.push(validation);
|
self.validations.push(validation);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ impl VanityControlData for HeadingData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn heading(
|
pub fn heading(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -20,7 +20,7 @@ impl ControlData for HiddenData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn hidden<FDT: Clone + PartialEq + 'static>(
|
pub fn hidden<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -17,7 +17,7 @@ impl VanityControlData for OutputData {
|
|||||||
}
|
}
|
||||||
impl GetterVanityControlData for OutputData {}
|
impl GetterVanityControlData for OutputData {}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn output(
|
pub fn output(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -25,7 +25,7 @@ impl ControlData for RadioButtonsData {
|
|||||||
}
|
}
|
||||||
impl ValidatedControlData for RadioButtonsData {}
|
impl ValidatedControlData for RadioButtonsData {}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn radio_buttons<FDT: Clone + PartialEq + 'static>(
|
pub fn radio_buttons<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -27,7 +27,7 @@ impl ControlData for SelectData {
|
|||||||
}
|
}
|
||||||
impl ValidatedControlData for SelectData {}
|
impl ValidatedControlData for SelectData {}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn select<FDT: Clone + PartialEq + 'static>(
|
pub fn select<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -38,7 +38,7 @@ impl ControlData for SliderData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn slider<FDT: Clone + PartialEq + 'static>(
|
pub fn slider<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -18,7 +18,7 @@ impl VanityControlData for SpacerData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn spacer(
|
pub fn spacer(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -29,7 +29,7 @@ impl ControlData for StepperData {
|
|||||||
}
|
}
|
||||||
impl ValidatedControlData for StepperData {}
|
impl ValidatedControlData for StepperData {}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn stepper<FDT: Clone + PartialEq + 'static>(
|
pub fn stepper<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -18,7 +18,7 @@ impl VanityControlData for SubmitData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn submit(
|
pub fn submit(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -23,7 +23,7 @@ impl ControlData for TextAreaData {
|
|||||||
}
|
}
|
||||||
impl ValidatedControlData for TextAreaData {}
|
impl ValidatedControlData for TextAreaData {}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn text_area<FDT: Clone + PartialEq + 'static>(
|
pub fn text_area<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
@ -39,7 +39,7 @@ impl ControlData for TextInputData {
|
|||||||
}
|
}
|
||||||
impl ValidatedControlData for TextInputData {}
|
impl ValidatedControlData for TextInputData {}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
pub fn text_input<FDT: Clone + PartialEq + 'static>(
|
pub fn text_input<FDT: Clone + PartialEq + 'static>(
|
||||||
self,
|
self,
|
||||||
builder: impl Fn(
|
builder: impl Fn(
|
||||||
|
|||||||
36
src/form.rs
36
src/form.rs
@ -40,15 +40,16 @@ pub struct Form<FD: FormToolData> {
|
|||||||
|
|
||||||
impl<FD: FormToolData> Form<FD> {
|
impl<FD: FormToolData> Form<FD> {
|
||||||
/// Gets the [`Validator`] for this form.
|
/// Gets the [`Validator`] for this form.
|
||||||
pub fn validator(self) -> FormValidator<FD> {
|
pub fn validator(&self) -> FormValidator<FD> {
|
||||||
FormValidator {
|
FormValidator {
|
||||||
validations: self.validations,
|
validations: self.validations.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validates the [`ToolFormData`], returning the result
|
/// Validates the [`ToolFormData`], returning the result
|
||||||
pub fn validate(&self) -> Result<(), String> {
|
pub fn validate(&self) -> Result<(), String> {
|
||||||
self.fd.get_untracked().validate()
|
let validator = self.validator();
|
||||||
|
validator.validate(&self.fd.get_untracked())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the view associated with this [`Form`].
|
/// Gets the view associated with this [`Form`].
|
||||||
@ -80,6 +81,7 @@ impl<FD: FormToolData> IntoView for Form<FD> {
|
|||||||
/// 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: Clone + 'static {
|
pub trait FormToolData: Clone + 'static {
|
||||||
type Style: FormStyle;
|
type Style: FormStyle;
|
||||||
|
type Context: 'static;
|
||||||
|
|
||||||
/// 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.
|
||||||
///
|
///
|
||||||
@ -88,7 +90,9 @@ pub trait FormToolData: Clone + 'static {
|
|||||||
/// Uses the given form builder to specify what fields should be present
|
/// Uses the given form builder to specify what fields should be present
|
||||||
/// in the form, what properties those fields should have, and how that
|
/// in the form, what properties those fields should have, and how that
|
||||||
/// data should be parsed and checked.
|
/// data should be parsed and checked.
|
||||||
fn build_form(fb: FormBuilder<Self, Self::Style>) -> FormBuilder<Self, Self::Style>;
|
fn build_form(
|
||||||
|
fb: FormBuilder<Self, Self::Style, Self::Context>,
|
||||||
|
) -> FormBuilder<Self, Self::Style, Self::Context>;
|
||||||
|
|
||||||
/// Constructs a [`Form`] for this [`FormToolData`] type.
|
/// Constructs a [`Form`] for this [`FormToolData`] type.
|
||||||
///
|
///
|
||||||
@ -96,8 +100,13 @@ pub trait FormToolData: Clone + 'static {
|
|||||||
/// [`Form`](leptos_router::Form)
|
/// [`Form`](leptos_router::Form)
|
||||||
/// 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(
|
||||||
let builder = FormBuilder::new();
|
self,
|
||||||
|
action: impl ToString,
|
||||||
|
style: Self::Style,
|
||||||
|
context: Self::Context,
|
||||||
|
) -> Form<Self> {
|
||||||
|
let builder = FormBuilder::new(context);
|
||||||
let builder = Self::build_form(builder);
|
let builder = Self::build_form(builder);
|
||||||
builder.build_plain_form(action.to_string(), self, style)
|
builder.build_plain_form(action.to_string(), self, style)
|
||||||
}
|
}
|
||||||
@ -112,13 +121,14 @@ pub trait FormToolData: Clone + 'static {
|
|||||||
self,
|
self,
|
||||||
action: Action<ServFn, Result<ServFn::Output, ServerFnError<ServFn::Error>>>,
|
action: Action<ServFn, Result<ServFn::Output, ServerFnError<ServFn::Error>>>,
|
||||||
style: Self::Style,
|
style: Self::Style,
|
||||||
|
context: Self::Context,
|
||||||
) -> Form<Self>
|
) -> Form<Self>
|
||||||
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 builder = FormBuilder::new();
|
let builder = FormBuilder::new(context);
|
||||||
let builder = Self::build_form(builder);
|
let builder = Self::build_form(builder);
|
||||||
builder.build_action_form(action, self, style)
|
builder.build_action_form(action, self, style)
|
||||||
}
|
}
|
||||||
@ -131,18 +141,18 @@ pub trait FormToolData: 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(context: Self::Context) -> FormValidator<Self> {
|
||||||
let builder = FormBuilder::new();
|
let builder = FormBuilder::new(context);
|
||||||
let builder = Self::build_form(builder);
|
let builder = Self::build_form(builder);
|
||||||
builder.validator()
|
builder.validator()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validates this [`FormToolData`] struct.
|
/// Validates this [`FormToolData`] struct.
|
||||||
///
|
///
|
||||||
/// This is shorthand for creating a validator with [`get_validator`]\()
|
/// This is shorthand for creating a validator with [`get_validator`]
|
||||||
/// and then calling `validator.validate(&self)`.
|
/// and then calling `validator.validate(&self, context)`.
|
||||||
fn validate(&self) -> Result<(), String> {
|
fn validate(&self, context: Self::Context) -> Result<(), String> {
|
||||||
let validator = Self::get_validator();
|
let validator = Self::get_validator(context);
|
||||||
validator.validate(self)
|
validator.validate(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,13 @@ use web_sys::{FormData, SubmitEvent};
|
|||||||
/// A builder for laying out forms.
|
/// A builder for laying out forms.
|
||||||
///
|
///
|
||||||
/// 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> {
|
///
|
||||||
|
/// ### Type Parameters
|
||||||
|
/// - `FD`: FormToolData - Your form data
|
||||||
|
/// - `FS`: FormStyle - The form style you are using
|
||||||
|
/// - `CX`: Context - A user defined context that you are rendering the form in
|
||||||
|
pub struct FormBuilder<FD: FormToolData, FS: FormStyle, CX: 'static> {
|
||||||
|
pub(crate) cx: CX,
|
||||||
/// 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.
|
||||||
@ -28,10 +34,11 @@ pub struct FormBuilder<FD: FormToolData, FS: FormStyle> {
|
|||||||
pub(crate) styles: Vec<FS::StylingAttributes>,
|
pub(crate) styles: Vec<FS::StylingAttributes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
|
impl<FD: FormToolData, FS: FormStyle, CX: 'static> FormBuilder<FD, FS, CX> {
|
||||||
/// Creates a new [`FormBuilder`]
|
/// Creates a new [`FormBuilder`]
|
||||||
pub(crate) fn new() -> FormBuilder<FD, FS> {
|
pub(crate) fn new(cx: CX) -> Self {
|
||||||
FormBuilder {
|
FormBuilder {
|
||||||
|
cx,
|
||||||
validations: Vec::new(),
|
validations: Vec::new(),
|
||||||
render_fns: Vec::new(),
|
render_fns: Vec::new(),
|
||||||
styles: Vec::new(),
|
styles: Vec::new(),
|
||||||
|
|||||||
Reference in New Issue
Block a user