Form Style Mutable #20

Closed
opened 2024-06-07 18:40:11 +00:00 by mitchell · 1 comment
Owner

It could be a good idea to pass in a mutable reference to the form style to all the component render methods of the FormStyle. This would allow the rendering of one component to impact the rendering of a different component, or it could add some persitant mutable state.

It could be a good idea to pass in a mutable reference to the form style to all the component render methods of the FormStyle. This would allow the rendering of one component to impact the rendering of a different component, or it could add some persitant mutable state.
Author
Owner

I dont think this is a good idea. Leptos might re-render things which may update the style in a weird way. This seems like a bad idea.
However, I did implement this going off of commit 360ef63b58.

Here is the diff

diff --git a/src/controls/button.rs b/src/controls/button.rs
index 1b72b24..69f4562 100644
--- a/src/controls/button.rs
+++ b/src/controls/button.rs
@@ -15,7 +15,7 @@ pub struct ButtonData<FD: FormToolData> {
 
 impl<FD: FormToolData> VanityControlData for ButtonData<FD> {
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         _value_getter: Option<Signal<String>>,
     ) -> View {
diff --git a/src/controls/checkbox.rs b/src/controls/checkbox.rs
index 67bd179..03f76f4 100644
--- a/src/controls/checkbox.rs
+++ b/src/controls/checkbox.rs
@@ -13,7 +13,7 @@ impl ControlData for CheckboxData {
     type ReturnType = bool;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/group.rs b/src/controls/group.rs
index 1832f41..ccdcf7d 100644
--- a/src/controls/group.rs
+++ b/src/controls/group.rs
@@ -12,11 +12,11 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
             self.validations.push(validation);
         }
 
-        let render_fn = move |fs: &FS, fd: RwSignal<FD>| {
+        let render_fn = move |fs: &mut FS, fd: RwSignal<FD>| {
             let (views, validation_cbs): (Vec<_>, Vec<_>) = group_builder
                 .render_fns
                 .into_iter()
-                .map(|r_fn| r_fn(&fs, fd))
+                .map(|r_fn| r_fn(fs, fd))
                 .unzip();
 
             let view = fs.group(views.collect_view(), group_builder.styles);
diff --git a/src/controls/heading.rs b/src/controls/heading.rs
index c9d05a9..72b040b 100644
--- a/src/controls/heading.rs
+++ b/src/controls/heading.rs
@@ -9,7 +9,7 @@ pub struct HeadingData {
 
 impl VanityControlData for HeadingData {
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         _value_getter: Option<leptos::prelude::Signal<String>>,
     ) -> View {
diff --git a/src/controls/hidden.rs b/src/controls/hidden.rs
index 88bcafc..d5f7f77 100644
--- a/src/controls/hidden.rs
+++ b/src/controls/hidden.rs
@@ -10,7 +10,7 @@ impl ControlData for HiddenData {
     type ReturnType = String;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         _value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/mod.rs b/src/controls/mod.rs
index cacf492..d331160 100644
--- a/src/controls/mod.rs
+++ b/src/controls/mod.rs
@@ -23,7 +23,7 @@ pub trait UnparseFn<CR, FDT>: Fn(FDT) -> CR + 'static {}
 pub trait FieldGetter<FD, FDT>: Fn(FD) -> FDT + 'static {}
 pub trait FieldSetter<FD, FDT>: Fn(&mut FD, FDT) + 'static {}
 pub trait RenderFn<FS, FD>:
-    FnOnce(&FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
+    FnOnce(&mut FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
 {
 }
 
@@ -35,7 +35,7 @@ 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> FieldSetter<FD, FDT> for F where F: Fn(&mut FD, FDT) + 'static {}
 impl<FS, FD, F> RenderFn<FS, FD> for F where
-    F: FnOnce(&FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
+    F: FnOnce(&mut FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static
 {
 }
 
@@ -43,7 +43,7 @@ impl<FS, FD, F> RenderFn<FS, FD> for F where
 pub trait VanityControlData: 'static {
     /// Builds the control, returning the [`View`] that was built.
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Option<Signal<String>>,
     ) -> View;
@@ -56,7 +56,7 @@ pub trait ControlData: 'static {
 
     /// Builds the control, returning the [`View`] that was built.
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/output.rs b/src/controls/output.rs
index d13500c..4a67410 100644
--- a/src/controls/output.rs
+++ b/src/controls/output.rs
@@ -8,7 +8,7 @@ pub struct OutputData;
 
 impl VanityControlData for OutputData {
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Option<Signal<String>>,
     ) -> View {
diff --git a/src/controls/radio_buttons.rs b/src/controls/radio_buttons.rs
index 6fa8961..8f68fd5 100644
--- a/src/controls/radio_buttons.rs
+++ b/src/controls/radio_buttons.rs
@@ -14,7 +14,7 @@ impl ControlData for RadioButtonsData {
     type ReturnType = String;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/select.rs b/src/controls/select.rs
index 8d06488..cd16628 100644
--- a/src/controls/select.rs
+++ b/src/controls/select.rs
@@ -16,7 +16,7 @@ impl ControlData for SelectData {
     type ReturnType = String;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/slider.rs b/src/controls/slider.rs
index 3cd5b5b..d9991eb 100644
--- a/src/controls/slider.rs
+++ b/src/controls/slider.rs
@@ -28,7 +28,7 @@ impl ControlData for SliderData {
     type ReturnType = i32;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/stepper.rs b/src/controls/stepper.rs
index f874d6f..4633f94 100644
--- a/src/controls/stepper.rs
+++ b/src/controls/stepper.rs
@@ -18,7 +18,7 @@ impl ControlData for StepperData {
     type ReturnType = String;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/submit.rs b/src/controls/submit.rs
index 35ee7bc..244dfe5 100644
--- a/src/controls/submit.rs
+++ b/src/controls/submit.rs
@@ -10,7 +10,7 @@ pub struct SubmitData {
 
 impl VanityControlData for SubmitData {
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         _value_getter: Option<leptos::prelude::Signal<String>>,
     ) -> View {
diff --git a/src/controls/text_area.rs b/src/controls/text_area.rs
index ea1214f..de08662 100644
--- a/src/controls/text_area.rs
+++ b/src/controls/text_area.rs
@@ -12,7 +12,7 @@ impl ControlData for TextAreaData {
     type ReturnType = String;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/controls/text_input.rs b/src/controls/text_input.rs
index dd62869..8e1ff8b 100644
--- a/src/controls/text_input.rs
+++ b/src/controls/text_input.rs
@@ -28,7 +28,7 @@ impl ControlData for TextInputData {
     type ReturnType = String;
 
     fn build_control<FS: FormStyle>(
-        fs: &FS,
+        fs: &mut FS,
         control: ControlRenderData<FS, Self>,
         value_getter: Signal<Self::ReturnType>,
         value_setter: Box<dyn Fn(Self::ReturnType)>,
diff --git a/src/form_builder.rs b/src/form_builder.rs
index 10b952c..746aec1 100644
--- a/src/form_builder.rs
+++ b/src/form_builder.rs
@@ -90,7 +90,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
             getter,
         } = vanity_control.build();
 
-        let render_fn = move |fs: &FS, fd: RwSignal<FD>| {
+        let render_fn = move |fs: &mut FS, fd: RwSignal<FD>| {
             let value_getter = getter.map(|getter| (move || getter(fd.get())).into_signal());
             let view = VanityControlData::build_control(fs, render_data, value_getter);
             (view, None)
@@ -120,7 +120,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
             self.validations.push(validation_fn.clone());
         }
 
-        let render_fn = move |fs: &FS, fd: RwSignal<FD>| {
+        let render_fn = move |fs: &mut FS, fd: RwSignal<FD>| {
             let (view, cb) = Self::build_control_view(
                 fd,
                 fs,
@@ -139,7 +139,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
 
     fn build_control_view<C: ControlData, FDT: 'static>(
         fd: RwSignal<FD>,
-        fs: &FS,
+        fs: &mut FS,
         getter: Rc<dyn FieldGetter<FD, FDT>>,
         setter: Rc<dyn FieldSetter<FD, FDT>>,
         unparse_fn: Box<dyn UnparseFn<<C as ControlData>::ReturnType, FDT>>,
@@ -230,7 +230,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
     }
 
     pub(crate) fn build_action_form<ServFn>(
-        self,
+        mut self,
         action: Action<ServFn, Result<ServFn::Output, ServerFnError<ServFn::Error>>>,
     ) -> Form<FD>
     where
@@ -241,7 +241,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
         let (views, validation_cbs): (Vec<_>, Vec<_>) = self
             .render_fns
             .into_iter()
-            .map(|r_fn| r_fn(&self.fs, self.fd))
+            .map(|r_fn| r_fn(&mut self.fs, self.fd))
             .unzip();
 
         let elements = self.fs.form_frame(views.into_view(), self.styles);
@@ -271,11 +271,11 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> {
         }
     }
 
-    pub(crate) fn build_plain_form(self, url: String) -> Form<FD> {
+    pub(crate) fn build_plain_form(mut self, url: String) -> Form<FD> {
         let (views, validation_cbs): (Vec<_>, Vec<_>) = self
             .render_fns
             .into_iter()
-            .map(|r_fn| r_fn(&self.fs, self.fd))
+            .map(|r_fn| r_fn(&mut self.fs, self.fd))
             .unzip();
 
         let elements = self.fs.form_frame(views.into_view(), self.styles);
diff --git a/src/styles/grid_form.rs b/src/styles/grid_form.rs
index 3cefd8c..a16f679 100644
--- a/src/styles/grid_form.rs
+++ b/src/styles/grid_form.rs
@@ -13,21 +13,23 @@ pub enum GridFormStylingAttributes {
 }
 
 #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
-pub struct GridFormStyle;
+pub struct GridFormStyle {
+    count: u32,
+}
 
 impl FormStyle for GridFormStyle {
     type StylingAttributes = GridFormStylingAttributes;
 
-    fn form_frame(&self, children: View, _styles: Vec<Self::StylingAttributes>) -> View {
+    fn form_frame(&mut self, children: View, _styles: Vec<Self::StylingAttributes>) -> View {
         view! { <div class="form_grid">{children}</div> }.into_view()
     }
 
-    fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View {
+    fn heading(&mut self, control: ControlRenderData<Self, HeadingData>) -> View {
         view! { <h2 class="form_heading">{&control.data.title}</h2> }.into_view()
     }
 
     fn text_input(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, TextInputData>,
         value_getter: Signal<<TextInputData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<TextInputData as ControlData>::ReturnType)>,
@@ -40,12 +42,13 @@ impl FormStyle for GridFormStyle {
                 GridFormStylingAttributes::Width(w) => width = w,
             }
         }
+        self.count += 1;
 
-        view! {
+        let inner = view! {
             <div style:grid-column=format!("span {}", width)>
                 <div>
                     <label for=&control.data.name class="form_label">
-                        {control.data.label.as_ref()}
+                        {control.data.label.as_ref().map(|l| format!("{} - {}", l, self.count))}
                     </label>
                     <span class="form_error">{move || validation_state.get().err()}</span>
                 </div>
@@ -64,11 +67,18 @@ impl FormStyle for GridFormStyle {
                 />
             </div>
         }
+        .into_view();
+
+        view! {
+            <Show when=move || value_getter.get() != "22">
+                {inner.clone()}
+            </Show>
+        }
         .into_view()
     }
 
     fn select(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, SelectData>,
         value_getter: Signal<<SelectData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
@@ -111,7 +121,7 @@ impl FormStyle for GridFormStyle {
         .into_view()
     }
 
-    fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View {
+    fn submit(&mut self, control: ControlRenderData<Self, SubmitData>) -> View {
         view! {
             <input type="submit" value=control.data.text class="form_submit"/>
         }
@@ -119,7 +129,7 @@ impl FormStyle for GridFormStyle {
     }
 
     fn text_area(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, TextAreaData>,
         value_getter: Signal<<TextAreaData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<TextAreaData as ControlData>::ReturnType)>,
@@ -144,12 +154,12 @@ impl FormStyle for GridFormStyle {
         .into_view()
     }
 
-    fn custom_component(&self, view: View) -> View {
+    fn custom_component(&mut self, view: View) -> View {
         view
     }
 
     fn hidden(
-        &self,
+        &mut self,
         _control: ControlRenderData<Self, HiddenData>,
         value_getter: Signal<String>,
     ) -> View {
@@ -157,7 +167,7 @@ impl FormStyle for GridFormStyle {
     }
 
     fn radio_buttons(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, crate::controls::radio_buttons::RadioButtonsData>,
         value_getter: Signal<
             <crate::controls::radio_buttons::RadioButtonsData as ControlData>::ReturnType,
@@ -224,7 +234,7 @@ impl FormStyle for GridFormStyle {
     }
 
     fn checkbox(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, CheckboxData>,
         value_getter: Signal<<CheckboxData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<CheckboxData as ControlData>::ReturnType)>,
@@ -261,7 +271,7 @@ impl FormStyle for GridFormStyle {
     }
 
     fn stepper(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, crate::controls::stepper::StepperData>,
         value_getter: Signal<<crate::controls::stepper::StepperData as ControlData>::ReturnType>,
         value_setter: Box<
@@ -302,7 +312,7 @@ impl FormStyle for GridFormStyle {
     }
 
     fn output(
-        &self,
+        &mut self,
         _control: ControlRenderData<Self, OutputData>,
         value_getter: Option<Signal<String>>,
     ) -> View {
@@ -310,7 +320,7 @@ impl FormStyle for GridFormStyle {
     }
 
     fn slider(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, crate::controls::slider::SliderData>,
         value_getter: Signal<<crate::controls::slider::SliderData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<crate::controls::slider::SliderData as ControlData>::ReturnType)>,
@@ -380,7 +390,7 @@ impl FormStyle for GridFormStyle {
     }
 
     // TODO: change this and form frame to use ControlRenderData
-    fn group(&self, inner: View, styles: Vec<Self::StylingAttributes>) -> View {
+    fn group(&mut self, inner: View, styles: Vec<Self::StylingAttributes>) -> View {
         let mut width = 12;
         for style in styles {
             match style {
diff --git a/src/styles/mod.rs b/src/styles/mod.rs
index 25896f1..fffe2e3 100644
--- a/src/styles/mod.rs
+++ b/src/styles/mod.rs
@@ -22,36 +22,36 @@ pub trait FormStyle: Default + 'static {
     ///
     /// Do NOT wrap it in an actual `form` element; any
     /// wrapping should be done with `div` or similar elements.
-    fn form_frame(&self, children: View, style: Vec<Self::StylingAttributes>) -> View;
-    fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View;
+    fn form_frame(&mut self, children: View, style: Vec<Self::StylingAttributes>) -> View;
+    fn heading(&mut self, control: ControlRenderData<Self, HeadingData>) -> View;
     fn hidden(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, HiddenData>,
         value_getter: Signal<String>,
     ) -> View;
     fn text_input(
-        &self,
+        &mut 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;
     fn text_area(
-        &self,
+        &mut 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;
     fn radio_buttons(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, RadioButtonsData>,
         value_getter: Signal<<RadioButtonsData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<RadioButtonsData as ControlData>::ReturnType)>,
         validation_state: Signal<Result<(), String>>,
     ) -> View;
     fn select(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, SelectData>,
         value_getter: Signal<<SelectData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>,
@@ -59,32 +59,32 @@ pub trait FormStyle: Default + 'static {
     ) -> View;
     fn button<FD: FormToolData>(&self, control: ControlRenderData<Self, ButtonData<FD>>) -> View;
     fn checkbox(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, CheckboxData>,
         value_getter: Signal<<CheckboxData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<CheckboxData as ControlData>::ReturnType)>,
     ) -> View;
     fn stepper(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, StepperData>,
         value_getter: Signal<<StepperData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<StepperData as ControlData>::ReturnType)>,
         validation_state: Signal<Result<(), String>>,
     ) -> View;
     fn output(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, OutputData>,
         value_getter: Option<Signal<String>>,
     ) -> View;
     fn slider(
-        &self,
+        &mut self,
         control: ControlRenderData<Self, SliderData>,
         value_getter: Signal<<SliderData as ControlData>::ReturnType>,
         value_setter: Box<dyn Fn(<SliderData as ControlData>::ReturnType)>,
         validation_state: Signal<Result<(), String>>,
     ) -> View;
-    fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View;
+    fn submit(&mut self, control: ControlRenderData<Self, SubmitData>) -> View;
     // TODO: test custom component
-    fn custom_component(&self, view: View) -> View;
-    fn group(&self, inner: View, style: Vec<Self::StylingAttributes>) -> View;
+    fn custom_component(&mut self, view: View) -> View;
+    fn group(&mut self, inner: View, style: Vec<Self::StylingAttributes>) -> View;
 }
I dont think this is a good idea. Leptos might re-render things which may update the style in a weird way. This seems like a bad idea. However, I did implement this going off of commit [`360ef63b58`](https://git.marinodev.com/MarinoDev/leptos_form_tool/commit/360ef63b5883764004d665383f9ab657f1492cc8). Here is the diff ``` diff --git a/src/controls/button.rs b/src/controls/button.rs index 1b72b24..69f4562 100644 --- a/src/controls/button.rs +++ b/src/controls/button.rs @@ -15,7 +15,7 @@ pub struct ButtonData<FD: FormToolData> { impl<FD: FormToolData> VanityControlData for ButtonData<FD> { fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, _value_getter: Option<Signal<String>>, ) -> View { diff --git a/src/controls/checkbox.rs b/src/controls/checkbox.rs index 67bd179..03f76f4 100644 --- a/src/controls/checkbox.rs +++ b/src/controls/checkbox.rs @@ -13,7 +13,7 @@ impl ControlData for CheckboxData { type ReturnType = bool; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/group.rs b/src/controls/group.rs index 1832f41..ccdcf7d 100644 --- a/src/controls/group.rs +++ b/src/controls/group.rs @@ -12,11 +12,11 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { self.validations.push(validation); } - let render_fn = move |fs: &FS, fd: RwSignal<FD>| { + let render_fn = move |fs: &mut FS, fd: RwSignal<FD>| { let (views, validation_cbs): (Vec<_>, Vec<_>) = group_builder .render_fns .into_iter() - .map(|r_fn| r_fn(&fs, fd)) + .map(|r_fn| r_fn(fs, fd)) .unzip(); let view = fs.group(views.collect_view(), group_builder.styles); diff --git a/src/controls/heading.rs b/src/controls/heading.rs index c9d05a9..72b040b 100644 --- a/src/controls/heading.rs +++ b/src/controls/heading.rs @@ -9,7 +9,7 @@ pub struct HeadingData { impl VanityControlData for HeadingData { fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, _value_getter: Option<leptos::prelude::Signal<String>>, ) -> View { diff --git a/src/controls/hidden.rs b/src/controls/hidden.rs index 88bcafc..d5f7f77 100644 --- a/src/controls/hidden.rs +++ b/src/controls/hidden.rs @@ -10,7 +10,7 @@ impl ControlData for HiddenData { type ReturnType = String; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, _value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/mod.rs b/src/controls/mod.rs index cacf492..d331160 100644 --- a/src/controls/mod.rs +++ b/src/controls/mod.rs @@ -23,7 +23,7 @@ pub trait UnparseFn<CR, FDT>: Fn(FDT) -> CR + 'static {} pub trait FieldGetter<FD, FDT>: Fn(FD) -> FDT + 'static {} pub trait FieldSetter<FD, FDT>: Fn(&mut FD, FDT) + 'static {} pub trait RenderFn<FS, FD>: - FnOnce(&FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static + FnOnce(&mut FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static { } @@ -35,7 +35,7 @@ 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> FieldSetter<FD, FDT> for F where F: Fn(&mut FD, FDT) + 'static {} impl<FS, FD, F> RenderFn<FS, FD> for F where - F: FnOnce(&FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static + F: FnOnce(&mut FS, RwSignal<FD>) -> (View, Option<Box<dyn ValidationCb>>) + 'static { } @@ -43,7 +43,7 @@ impl<FS, FD, F> RenderFn<FS, FD> for F where pub trait VanityControlData: 'static { /// Builds the control, returning the [`View`] that was built. fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Option<Signal<String>>, ) -> View; @@ -56,7 +56,7 @@ pub trait ControlData: 'static { /// Builds the control, returning the [`View`] that was built. fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/output.rs b/src/controls/output.rs index d13500c..4a67410 100644 --- a/src/controls/output.rs +++ b/src/controls/output.rs @@ -8,7 +8,7 @@ pub struct OutputData; impl VanityControlData for OutputData { fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Option<Signal<String>>, ) -> View { diff --git a/src/controls/radio_buttons.rs b/src/controls/radio_buttons.rs index 6fa8961..8f68fd5 100644 --- a/src/controls/radio_buttons.rs +++ b/src/controls/radio_buttons.rs @@ -14,7 +14,7 @@ impl ControlData for RadioButtonsData { type ReturnType = String; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/select.rs b/src/controls/select.rs index 8d06488..cd16628 100644 --- a/src/controls/select.rs +++ b/src/controls/select.rs @@ -16,7 +16,7 @@ impl ControlData for SelectData { type ReturnType = String; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/slider.rs b/src/controls/slider.rs index 3cd5b5b..d9991eb 100644 --- a/src/controls/slider.rs +++ b/src/controls/slider.rs @@ -28,7 +28,7 @@ impl ControlData for SliderData { type ReturnType = i32; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/stepper.rs b/src/controls/stepper.rs index f874d6f..4633f94 100644 --- a/src/controls/stepper.rs +++ b/src/controls/stepper.rs @@ -18,7 +18,7 @@ impl ControlData for StepperData { type ReturnType = String; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/submit.rs b/src/controls/submit.rs index 35ee7bc..244dfe5 100644 --- a/src/controls/submit.rs +++ b/src/controls/submit.rs @@ -10,7 +10,7 @@ pub struct SubmitData { impl VanityControlData for SubmitData { fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, _value_getter: Option<leptos::prelude::Signal<String>>, ) -> View { diff --git a/src/controls/text_area.rs b/src/controls/text_area.rs index ea1214f..de08662 100644 --- a/src/controls/text_area.rs +++ b/src/controls/text_area.rs @@ -12,7 +12,7 @@ impl ControlData for TextAreaData { type ReturnType = String; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/controls/text_input.rs b/src/controls/text_input.rs index dd62869..8e1ff8b 100644 --- a/src/controls/text_input.rs +++ b/src/controls/text_input.rs @@ -28,7 +28,7 @@ impl ControlData for TextInputData { type ReturnType = String; fn build_control<FS: FormStyle>( - fs: &FS, + fs: &mut FS, control: ControlRenderData<FS, Self>, value_getter: Signal<Self::ReturnType>, value_setter: Box<dyn Fn(Self::ReturnType)>, diff --git a/src/form_builder.rs b/src/form_builder.rs index 10b952c..746aec1 100644 --- a/src/form_builder.rs +++ b/src/form_builder.rs @@ -90,7 +90,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { getter, } = vanity_control.build(); - let render_fn = move |fs: &FS, fd: RwSignal<FD>| { + let render_fn = move |fs: &mut FS, fd: RwSignal<FD>| { let value_getter = getter.map(|getter| (move || getter(fd.get())).into_signal()); let view = VanityControlData::build_control(fs, render_data, value_getter); (view, None) @@ -120,7 +120,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { self.validations.push(validation_fn.clone()); } - let render_fn = move |fs: &FS, fd: RwSignal<FD>| { + let render_fn = move |fs: &mut FS, fd: RwSignal<FD>| { let (view, cb) = Self::build_control_view( fd, fs, @@ -139,7 +139,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { fn build_control_view<C: ControlData, FDT: 'static>( fd: RwSignal<FD>, - fs: &FS, + fs: &mut FS, getter: Rc<dyn FieldGetter<FD, FDT>>, setter: Rc<dyn FieldSetter<FD, FDT>>, unparse_fn: Box<dyn UnparseFn<<C as ControlData>::ReturnType, FDT>>, @@ -230,7 +230,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { } pub(crate) fn build_action_form<ServFn>( - self, + mut self, action: Action<ServFn, Result<ServFn::Output, ServerFnError<ServFn::Error>>>, ) -> Form<FD> where @@ -241,7 +241,7 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { let (views, validation_cbs): (Vec<_>, Vec<_>) = self .render_fns .into_iter() - .map(|r_fn| r_fn(&self.fs, self.fd)) + .map(|r_fn| r_fn(&mut self.fs, self.fd)) .unzip(); let elements = self.fs.form_frame(views.into_view(), self.styles); @@ -271,11 +271,11 @@ impl<FD: FormToolData, FS: FormStyle> FormBuilder<FD, FS> { } } - pub(crate) fn build_plain_form(self, url: String) -> Form<FD> { + pub(crate) fn build_plain_form(mut self, url: String) -> Form<FD> { let (views, validation_cbs): (Vec<_>, Vec<_>) = self .render_fns .into_iter() - .map(|r_fn| r_fn(&self.fs, self.fd)) + .map(|r_fn| r_fn(&mut self.fs, self.fd)) .unzip(); let elements = self.fs.form_frame(views.into_view(), self.styles); diff --git a/src/styles/grid_form.rs b/src/styles/grid_form.rs index 3cefd8c..a16f679 100644 --- a/src/styles/grid_form.rs +++ b/src/styles/grid_form.rs @@ -13,21 +13,23 @@ pub enum GridFormStylingAttributes { } #[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct GridFormStyle; +pub struct GridFormStyle { + count: u32, +} impl FormStyle for GridFormStyle { type StylingAttributes = GridFormStylingAttributes; - fn form_frame(&self, children: View, _styles: Vec<Self::StylingAttributes>) -> View { + fn form_frame(&mut self, children: View, _styles: Vec<Self::StylingAttributes>) -> View { view! { <div class="form_grid">{children}</div> }.into_view() } - fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View { + fn heading(&mut self, control: ControlRenderData<Self, HeadingData>) -> View { view! { <h2 class="form_heading">{&control.data.title}</h2> }.into_view() } fn text_input( - &self, + &mut self, control: ControlRenderData<Self, TextInputData>, value_getter: Signal<<TextInputData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<TextInputData as ControlData>::ReturnType)>, @@ -40,12 +42,13 @@ impl FormStyle for GridFormStyle { GridFormStylingAttributes::Width(w) => width = w, } } + self.count += 1; - view! { + let inner = view! { <div style:grid-column=format!("span {}", width)> <div> <label for=&control.data.name class="form_label"> - {control.data.label.as_ref()} + {control.data.label.as_ref().map(|l| format!("{} - {}", l, self.count))} </label> <span class="form_error">{move || validation_state.get().err()}</span> </div> @@ -64,11 +67,18 @@ impl FormStyle for GridFormStyle { /> </div> } + .into_view(); + + view! { + <Show when=move || value_getter.get() != "22"> + {inner.clone()} + </Show> + } .into_view() } fn select( - &self, + &mut self, control: ControlRenderData<Self, SelectData>, value_getter: Signal<<SelectData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>, @@ -111,7 +121,7 @@ impl FormStyle for GridFormStyle { .into_view() } - fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View { + fn submit(&mut self, control: ControlRenderData<Self, SubmitData>) -> View { view! { <input type="submit" value=control.data.text class="form_submit"/> } @@ -119,7 +129,7 @@ impl FormStyle for GridFormStyle { } fn text_area( - &self, + &mut self, control: ControlRenderData<Self, TextAreaData>, value_getter: Signal<<TextAreaData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<TextAreaData as ControlData>::ReturnType)>, @@ -144,12 +154,12 @@ impl FormStyle for GridFormStyle { .into_view() } - fn custom_component(&self, view: View) -> View { + fn custom_component(&mut self, view: View) -> View { view } fn hidden( - &self, + &mut self, _control: ControlRenderData<Self, HiddenData>, value_getter: Signal<String>, ) -> View { @@ -157,7 +167,7 @@ impl FormStyle for GridFormStyle { } fn radio_buttons( - &self, + &mut self, control: ControlRenderData<Self, crate::controls::radio_buttons::RadioButtonsData>, value_getter: Signal< <crate::controls::radio_buttons::RadioButtonsData as ControlData>::ReturnType, @@ -224,7 +234,7 @@ impl FormStyle for GridFormStyle { } fn checkbox( - &self, + &mut self, control: ControlRenderData<Self, CheckboxData>, value_getter: Signal<<CheckboxData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<CheckboxData as ControlData>::ReturnType)>, @@ -261,7 +271,7 @@ impl FormStyle for GridFormStyle { } fn stepper( - &self, + &mut self, control: ControlRenderData<Self, crate::controls::stepper::StepperData>, value_getter: Signal<<crate::controls::stepper::StepperData as ControlData>::ReturnType>, value_setter: Box< @@ -302,7 +312,7 @@ impl FormStyle for GridFormStyle { } fn output( - &self, + &mut self, _control: ControlRenderData<Self, OutputData>, value_getter: Option<Signal<String>>, ) -> View { @@ -310,7 +320,7 @@ impl FormStyle for GridFormStyle { } fn slider( - &self, + &mut self, control: ControlRenderData<Self, crate::controls::slider::SliderData>, value_getter: Signal<<crate::controls::slider::SliderData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<crate::controls::slider::SliderData as ControlData>::ReturnType)>, @@ -380,7 +390,7 @@ impl FormStyle for GridFormStyle { } // TODO: change this and form frame to use ControlRenderData - fn group(&self, inner: View, styles: Vec<Self::StylingAttributes>) -> View { + fn group(&mut self, inner: View, styles: Vec<Self::StylingAttributes>) -> View { let mut width = 12; for style in styles { match style { diff --git a/src/styles/mod.rs b/src/styles/mod.rs index 25896f1..fffe2e3 100644 --- a/src/styles/mod.rs +++ b/src/styles/mod.rs @@ -22,36 +22,36 @@ pub trait FormStyle: Default + 'static { /// /// Do NOT wrap it in an actual `form` element; any /// wrapping should be done with `div` or similar elements. - fn form_frame(&self, children: View, style: Vec<Self::StylingAttributes>) -> View; - fn heading(&self, control: ControlRenderData<Self, HeadingData>) -> View; + fn form_frame(&mut self, children: View, style: Vec<Self::StylingAttributes>) -> View; + fn heading(&mut self, control: ControlRenderData<Self, HeadingData>) -> View; fn hidden( - &self, + &mut self, control: ControlRenderData<Self, HiddenData>, value_getter: Signal<String>, ) -> View; fn text_input( - &self, + &mut 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; fn text_area( - &self, + &mut 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; fn radio_buttons( - &self, + &mut self, control: ControlRenderData<Self, RadioButtonsData>, value_getter: Signal<<RadioButtonsData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<RadioButtonsData as ControlData>::ReturnType)>, validation_state: Signal<Result<(), String>>, ) -> View; fn select( - &self, + &mut self, control: ControlRenderData<Self, SelectData>, value_getter: Signal<<SelectData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<SelectData as ControlData>::ReturnType)>, @@ -59,32 +59,32 @@ pub trait FormStyle: Default + 'static { ) -> View; fn button<FD: FormToolData>(&self, control: ControlRenderData<Self, ButtonData<FD>>) -> View; fn checkbox( - &self, + &mut self, control: ControlRenderData<Self, CheckboxData>, value_getter: Signal<<CheckboxData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<CheckboxData as ControlData>::ReturnType)>, ) -> View; fn stepper( - &self, + &mut self, control: ControlRenderData<Self, StepperData>, value_getter: Signal<<StepperData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<StepperData as ControlData>::ReturnType)>, validation_state: Signal<Result<(), String>>, ) -> View; fn output( - &self, + &mut self, control: ControlRenderData<Self, OutputData>, value_getter: Option<Signal<String>>, ) -> View; fn slider( - &self, + &mut self, control: ControlRenderData<Self, SliderData>, value_getter: Signal<<SliderData as ControlData>::ReturnType>, value_setter: Box<dyn Fn(<SliderData as ControlData>::ReturnType)>, validation_state: Signal<Result<(), String>>, ) -> View; - fn submit(&self, control: ControlRenderData<Self, SubmitData>) -> View; + fn submit(&mut self, control: ControlRenderData<Self, SubmitData>) -> View; // TODO: test custom component - fn custom_component(&self, view: View) -> View; - fn group(&self, inner: View, style: Vec<Self::StylingAttributes>) -> View; + fn custom_component(&mut self, view: View) -> View; + fn group(&mut self, inner: View, style: Vec<Self::StylingAttributes>) -> View; } ```
This repo is archived. You cannot comment on issues.
No Milestone
No project
No Assignees
1 Participants
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: MarinoDev/leptos_form_tool#20
No description provided.