differ rendering

This commit is contained in:
Mitchell Marino 2024-06-05 11:46:48 -05:00
parent f19d53830c
commit 3621e5fb7b

View File

@ -87,8 +87,10 @@ struct FullFormBuilder<FD: FormToolData, FS: FormStyle> {
fd: RwSignal<FD>, fd: RwSignal<FD>,
fs: FS, fs: FS,
validations: Vec<Rc<dyn ValidationFn<FD>>>, validations: Vec<Rc<dyn ValidationFn<FD>>>,
validation_cbs: Vec<Box<dyn ValidationCb>>, render_fns:
views: Vec<View>, Vec<Box<dyn FnOnce(&FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static>>,
// validation_cbs: Vec<Box<dyn ValidationCb>>,
// views: Vec<View>,
} }
/// The internal type for building forms /// The internal type for building forms
@ -126,8 +128,9 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
fd, fd,
fs: form_style, fs: form_style,
validations: Vec::new(), validations: Vec::new(),
validation_cbs: Vec::new(), render_fns: Vec::new(),
views: Vec::new(), // validation_cbs: Vec::new(),
// views: Vec::new(),
}), }),
} }
} }
@ -168,8 +171,12 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
}; };
let render_data = vanity_control.build(); let render_data = vanity_control.build();
let view = VanityControlData::build_control(&builder.fs, render_data); let render_fn = move |fs: &FS, _| {
builder.views.push(view); let view = VanityControlData::build_control(fs, render_data);
(view, None)
};
builder.render_fns.push(Box::new(render_fn));
} }
fn add_control<C: ControlData, FDT: Clone + PartialEq + 'static>( fn add_control<C: ControlData, FDT: Clone + PartialEq + 'static>(
@ -203,31 +210,36 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
builder.validations.push(validation_fn.clone()); builder.validations.push(validation_fn.clone());
} }
let (validation_cb, view) = Self::build_control_view( let render_fn = move |fs: &FS, fd: RwSignal<FD>| {
builder, let (view, cb) = Self::build_control_view(
getter, fd,
setter, fs,
unparse_fn, getter,
parse_fn, setter,
validation_fn, unparse_fn,
render_data, parse_fn,
); validation_fn,
render_data,
);
(view, Some(cb))
};
builder.views.push(view); // builder.views.push(view);
builder.validation_cbs.push(validation_cb); // builder.validation_cbs.push(validation_cb);
builder.render_fns.push(Box::new(render_fn));
} }
fn build_control_view<C: ControlData, FDT: Clone + PartialEq + 'static>( fn build_control_view<C: ControlData, FDT: Clone + PartialEq + 'static>(
builder: &FullFormBuilder<FD, FS>, fd: RwSignal<FD>,
fs: &FS,
getter: Rc<dyn FieldGetter<FD, FDT>>, getter: Rc<dyn FieldGetter<FD, FDT>>,
setter: Rc<dyn FieldSetter<FD, FDT>>, setter: Rc<dyn FieldSetter<FD, FDT>>,
unparse_fn: Box<dyn UnparseFn<<C as ControlData>::ReturnType, FDT>>, unparse_fn: Box<dyn UnparseFn<<C as ControlData>::ReturnType, FDT>>,
parse_fn: Box<dyn ParseFn<<C as ControlData>::ReturnType, FDT>>, parse_fn: Box<dyn ParseFn<<C as ControlData>::ReturnType, FDT>>,
validation_fn: Option<Rc<dyn ValidationFn<FD>>>, validation_fn: Option<Rc<dyn ValidationFn<FD>>>,
render_data: crate::controls::ControlRenderData<FS, C>, render_data: crate::controls::ControlRenderData<FS, C>,
) -> (Box<dyn ValidationCb>, View) { ) -> (View, Box<dyn ValidationCb>) {
let (validation_signal, validation_signal_set) = create_signal(Ok(())); let (validation_signal, validation_signal_set) = create_signal(Ok(()));
let fd = builder.fd;
let value_getter = move || { let value_getter = move || {
let getter = getter.clone(); let getter = getter.clone();
// memoize so that updating one field doesn't cause a re-render for all fields // memoize so that updating one field doesn't cause a re-render for all fields
@ -275,13 +287,13 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
let value_setter = Box::new(value_setter); let value_setter = Box::new(value_setter);
let view = C::build_control( let view = C::build_control(
&builder.fs, fs,
render_data, render_data,
value_getter, value_getter,
value_setter, value_setter,
validation_signal.into(), validation_signal.into(),
); );
(validation_cb, view) (view, validation_cb)
} }
fn build_action_form<ServFn>( fn build_action_form<ServFn>(
@ -298,12 +310,17 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
FormBuilderInner::ValidationBuilder { validations: _ } => return None, FormBuilderInner::ValidationBuilder { validations: _ } => return None,
}; };
let elements = builder.fs.form_frame(builder.views.into_view()); let (views, validation_cbs): (Vec<_>, Vec<_>) = builder
.render_fns
.into_iter()
.map(|r_fn| r_fn(&builder.fs, builder.fd))
.unzip();
let elements = builder.fs.form_frame(views.into_view());
let validation_cbs = builder.validation_cbs;
let on_submit = move |ev: SubmitEvent| { let on_submit = move |ev: SubmitEvent| {
let mut failed = false; let mut failed = false;
for validation in validation_cbs.iter() { for validation in validation_cbs.iter().flatten() {
if !validation() { if !validation() {
failed = true; failed = true;
} }
@ -332,12 +349,17 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
FormBuilderInner::ValidationBuilder { validations: _ } => return None, FormBuilderInner::ValidationBuilder { validations: _ } => return None,
}; };
let elements = builder.fs.form_frame(builder.views.into_view()); let (views, validation_cbs): (Vec<_>, Vec<_>) = builder
.render_fns
.into_iter()
.map(|r_fn| r_fn(&builder.fs, builder.fd))
.unzip();
let elements = builder.fs.form_frame(views.into_view());
let validation_cbs = builder.validation_cbs;
let on_submit = move |ev: SubmitEvent| { let on_submit = move |ev: SubmitEvent| {
let mut failed = false; let mut failed = false;
for validation in validation_cbs.iter() { for validation in validation_cbs.iter().flatten() {
if !validation() { if !validation() {
failed = true; failed = true;
} }